linux/drivers/net/wireless/p54/p54pci.c History
<<
>>
Prefs
   1
   2/*
   3 * Linux device driver for PCI based Prism54
   4 *
   5 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
   6 * Copyright (c) 2008, Christian Lamparter <chunkeey@web.de>
   7 *
   8 * Based on the islsm (softmac prism54) driver, which is:
   9 * Copyright 2004-2006 Jean-Baptiste Note <jean-baptiste.note@m4x.org>, et al.
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as
  13 * published by the Free Software Foundation.
  14 */
  15
  16#include <linux/init.h>
  17#include <linux/pci.h>
  18#include <linux/slab.h>
  19#include <linux/firmware.h>
  20#include <linux/etherdevice.h>
  21#include <linux/delay.h>
  22#include <linux/completion.h>
  23#include <net/mac80211.h>
  24
  25#include "p54.h"
  26#include "lmac.h"
  27#include "p54pci.h"
  28
  29MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
  30MODULE_DESCRIPTION("Prism54 PCI wireless driver");
  31MODULE_LICENSE("GPL");
  32MODULE_ALIAS("prism54pci");
  33MODULE_FIRMWARE("isl3886pci");
  34
  35static DEFINE_PCI_DEVICE_TABLE(p54p_table) = {
  36        /* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
  37        { PCI_DEVICE(0x1260, 0x3890) },
  38        /* 3COM 3CRWE154G72 Wireless LAN adapter */
  39        { PCI_DEVICE(0x10b7, 0x6001) },
  40        /* Intersil PRISM Indigo Wireless LAN adapter */
  41        { PCI_DEVICE(0x1260, 0x3877) },
  42        /* Intersil PRISM Javelin/Xbow Wireless LAN adapter */
  43        { PCI_DEVICE(0x1260, 0x3886) },
  44        { },
  45};
  46
  47MODULE_DEVICE_TABLE(pci, p54p_table);
  48
  49static int p54p_upload_firmware(struct ieee80211_hw *dev)
  50{
  51        struct p54p_priv *priv = dev->priv;
  52        __le32 reg;
  53        int err;
  54        __le32 *data;
  55        u32 remains, left, device_addr;
  56
  57        P54P_WRITE(int_enable, cpu_to_le32(0));
  58        P54P_READ(int_enable);
  59        udelay(10);
  60
  61        reg = P54P_READ(ctrl_stat);
  62        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
  63        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
  64        P54P_WRITE(ctrl_stat, reg);
  65        P54P_READ(ctrl_stat);
  66        udelay(10);
  67
  68        reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
  69        P54P_WRITE(ctrl_stat, reg);
  70        wmb();
  71        udelay(10);
  72
  73        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
  74        P54P_WRITE(ctrl_stat, reg);
  75        wmb();
  76
  77        /* wait for the firmware to reset properly */
  78        mdelay(10);
  79
  80        err = p54_parse_firmware(dev, priv->firmware);
  81        if (err)
  82                return err;
  83
  84        if (priv->common.fw_interface != FW_LM86) {
  85                dev_err(&priv->pdev->dev, "wrong firmware, "
  86                        "please get a LM86(PCI) firmware a try again.\n");
  87                return -EINVAL;
  88        }
  89
  90        data = (__le32 *) priv->firmware->data;
  91        remains = priv->firmware->size;
  92        device_addr = ISL38XX_DEV_FIRMWARE_ADDR;
  93        while (remains) {
  94                u32 i = 0;
  95                left = min((u32)0x1000, remains);
  96                P54P_WRITE(direct_mem_base, cpu_to_le32(device_addr));
  97                P54P_READ(int_enable);
  98
  99                device_addr += 0x1000;
 100                while (i < left) {
 101                        P54P_WRITE(direct_mem_win[i], *data++);
 102                        i += sizeof(u32);
 103                }
 104
 105                remains -= left;
 106                P54P_READ(int_enable);
 107        }
 108
 109        reg = P54P_READ(ctrl_stat);
 110        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
 111        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
 112        reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
 113        P54P_WRITE(ctrl_stat, reg);
 114        P54P_READ(ctrl_stat);
 115        udelay(10);
 116
 117        reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
 118        P54P_WRITE(ctrl_stat, reg);
 119        wmb();
 120        udelay(10);
 121
 122        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
 123        P54P_WRITE(ctrl_stat, reg);
 124        wmb();
 125        udelay(10);
 126
 127        /* wait for the firmware to boot properly */
 128        mdelay(100);
 129
 130        return 0;
 131}
 132
 133static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
 134        int ring_index, struct p54p_desc *ring, u32 ring_limit,
 135        struct sk_buff **rx_buf)
 136{
 137        struct p54p_priv *priv = dev->priv;
 138        struct p54p_ring_control *ring_control = priv->ring_control;
 139        u32 limit, idx, i;
 140
 141        idx = le32_to_cpu(ring_control->host_idx[ring_index]);
 142        limit = idx;
 143        limit -= le32_to_cpu(ring_control->device_idx[ring_index]);
 144        limit = ring_limit - limit;
 145
 146        i = idx % ring_limit;
 147        while (limit-- > 1) {
 148                struct p54p_desc *desc = &ring[i];
 149
 150                if (!desc->host_addr) {
 151                        struct sk_buff *skb;
 152                        dma_addr_t mapping;
 153                        skb = dev_alloc_skb(priv->common.rx_mtu + 32);
 154                        if (!skb)
 155                                break;
 156
 157                        mapping = pci_map_single(priv->pdev,
 158                                                 skb_tail_pointer(skb),
 159                                                 priv->common.rx_mtu + 32,
 160                                                 PCI_DMA_FROMDEVICE);
 161
 162                        if (pci_dma_mapping_error(priv->pdev, mapping)) {
 163                                dev_kfree_skb_any(skb);
 164                                dev_err(&priv->pdev->dev,
 165                                        "RX DMA Mapping error\n");
 166                                break;
 167                        }
 168
 169                        desc->host_addr = cpu_to_le32(mapping);
 170                        desc->device_addr = 0;  // FIXME: necessary?
 171                        desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
 172                        desc->flags = 0;
 173                        rx_buf[i] = skb;
 174                }
 175
 176                i++;
 177                idx++;
 178                i %= ring_limit;
 179        }
 180
 181        wmb();
 182        ring_control->host_idx[ring_index] = cpu_to_le32(idx);
 183}
 184
 185static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
 186        int ring_index, struct p54p_desc *ring, u32 ring_limit,
 187        struct sk_buff **rx_buf)
 188{
 189        struct p54p_priv *priv = dev->priv;
 190        struct p54p_ring_control *ring_control = priv->ring_control;
 191        struct p54p_desc *desc;
 192        u32 idx, i;
 193
 194        i = (*index) % ring_limit;
 195        (*index) = idx = le32_to_cpu(ring_control->device_idx[ring_index]);
 196        idx %= ring_limit;
 197        while (i != idx) {
 198                u16 len;
 199                struct sk_buff *skb;
 200                desc = &ring[i];
 201                len = le16_to_cpu(desc->len);
 202                skb = rx_buf[i];
 203
 204                if (!skb) {
 205                        i++;
 206                        i %= ring_limit;
 207                        continue;
 208                }
 209
 210                if (unlikely(len > priv->common.rx_mtu)) {
 211                        if (net_ratelimit())
 212                                dev_err(&priv->pdev->dev, "rx'd frame size "
 213                                        "exceeds length threshold.\n");
 214
 215                        len = priv->common.rx_mtu;
 216                }
 217                skb_put(skb, len);
 218
 219                if (p54_rx(dev, skb)) {
 220                        pci_unmap_single(priv->pdev,
 221                                         le32_to_cpu(desc->host_addr),
 222                                         priv->common.rx_mtu + 32,
 223                                         PCI_DMA_FROMDEVICE);
 224                        rx_buf[i] = NULL;
 225                        desc->host_addr = 0;
 226                } else {
 227                        skb_trim(skb, 0);
 228                        desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
 229                }
 230
 231                i++;
 232                i %= ring_limit;
 233        }
 234
 235        p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf);
 236}
 237
 238static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
 239        int ring_index, struct p54p_desc *ring, u32 ring_limit,
 240        struct sk_buff **tx_buf)
 241{
 242        struct p54p_priv *priv = dev->priv;
 243        struct p54p_ring_control *ring_control = priv->ring_control;
 244        struct p54p_desc *desc;
 245        struct sk_buff *skb;
 246        u32 idx, i;
 247
 248        i = (*index) % ring_limit;
 249        (*index) = idx = le32_to_cpu(ring_control->device_idx[ring_index]);
 250        idx %= ring_limit;
 251
 252        while (i != idx) {
 253                desc = &ring[i];
 254
 255                skb = tx_buf[i];
 256                tx_buf[i] = NULL;
 257
 258                pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
 259                                 le16_to_cpu(desc->len), PCI_DMA_TODEVICE);
 260
 261                desc->host_addr = 0;
 262                desc->device_addr = 0;
 263                desc->len = 0;
 264                desc->flags = 0;
 265
 266                if (skb && FREE_AFTER_TX(skb))
 267                        p54_free_skb(dev, skb);
 268
 269                i++;
 270                i %= ring_limit;
 271        }
 272}
 273
 274static void p54p_tasklet(unsigned long dev_id)
 275{
 276        struct ieee80211_hw *dev = (struct ieee80211_hw *)dev_id;
 277        struct p54p_priv *priv = dev->priv;
 278        struct p54p_ring_control *ring_control = priv->ring_control;
 279
 280        p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt,
 281                           ARRAY_SIZE(ring_control->tx_mgmt),
 282                           priv->tx_buf_mgmt);
 283
 284        p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data,
 285                           ARRAY_SIZE(ring_control->tx_data),
 286                           priv->tx_buf_data);
 287
 288        p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt,
 289                ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt);
 290
 291        p54p_check_rx_ring(dev, &priv->rx_idx_data, 0, ring_control->rx_data,
 292                ARRAY_SIZE(ring_control->rx_data), priv->rx_buf_data);
 293
 294        wmb();
 295        P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
 296}
 297
 298static irqreturn_t p54p_interrupt(int irq, void *dev_id)
 299{
 300        struct ieee80211_hw *dev = dev_id;
 301        struct p54p_priv *priv = dev->priv;
 302        __le32 reg;
 303
 304        reg = P54P_READ(int_ident);
 305        if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) {
 306                goto out;
 307        }
 308        P54P_WRITE(int_ack, reg);
 309
 310        reg &= P54P_READ(int_enable);
 311
 312        if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE))
 313                tasklet_schedule(&priv->tasklet);
 314        else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
 315                complete(&priv->boot_comp);
 316
 317out:
 318        return reg ? IRQ_HANDLED : IRQ_NONE;
 319}
 320
 321static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 322{
 323        unsigned long flags;
 324        struct p54p_priv *priv = dev->priv;
 325        struct p54p_ring_control *ring_control = priv->ring_control;
 326        struct p54p_desc *desc;
 327        dma_addr_t mapping;
 328        u32 device_idx, idx, i;
 329
 330        spin_lock_irqsave(&priv->lock, flags);
 331        device_idx = le32_to_cpu(ring_control->device_idx[1]);
 332        idx = le32_to_cpu(ring_control->host_idx[1]);
 333        i = idx % ARRAY_SIZE(ring_control->tx_data);
 334
 335        mapping = pci_map_single(priv->pdev, skb->data, skb->len,
 336                                 PCI_DMA_TODEVICE);
 337        if (pci_dma_mapping_error(priv->pdev, mapping)) {
 338                spin_unlock_irqrestore(&priv->lock, flags);
 339                p54_free_skb(dev, skb);
 340                dev_err(&priv->pdev->dev, "TX DMA mapping error\n");
 341                return ;
 342        }
 343        priv->tx_buf_data[i] = skb;
 344
 345        desc = &ring_control->tx_data[i];
 346        desc->host_addr = cpu_to_le32(mapping);
 347        desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
 348        desc->len = cpu_to_le16(skb->len);
 349        desc->flags = 0;
 350
 351        wmb();
 352        ring_control->host_idx[1] = cpu_to_le32(idx + 1);
 353        spin_unlock_irqrestore(&priv->lock, flags);
 354
 355        P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
 356        P54P_READ(dev_int);
 357}
 358
 359static void p54p_stop(struct ieee80211_hw *dev)
 360{
 361        struct p54p_priv *priv = dev->priv;
 362        struct p54p_ring_control *ring_control = priv->ring_control;
 363        unsigned int i;
 364        struct p54p_desc *desc;
 365
 366        P54P_WRITE(int_enable, cpu_to_le32(0));
 367        P54P_READ(int_enable);
 368        udelay(10);
 369
 370        free_irq(priv->pdev->irq, dev);
 371
 372        tasklet_kill(&priv->tasklet);
 373
 374        P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
 375
 376        for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) {
 377                desc = &ring_control->rx_data[i];
 378                if (desc->host_addr)
 379                        pci_unmap_single(priv->pdev,
 380                                         le32_to_cpu(desc->host_addr),
 381                                         priv->common.rx_mtu + 32,
 382                                         PCI_DMA_FROMDEVICE);
 383                kfree_skb(priv->rx_buf_data[i]);
 384                priv->rx_buf_data[i] = NULL;
 385        }
 386
 387        for (i = 0; i < ARRAY_SIZE(priv->rx_buf_mgmt); i++) {
 388                desc = &ring_control->rx_mgmt[i];
 389                if (desc->host_addr)
 390                        pci_unmap_single(priv->pdev,
 391                                         le32_to_cpu(desc->host_addr),
 392                                         priv->common.rx_mtu + 32,
 393                                         PCI_DMA_FROMDEVICE);
 394                kfree_skb(priv->rx_buf_mgmt[i]);
 395                priv->rx_buf_mgmt[i] = NULL;
 396        }
 397
 398        for (i = 0; i < ARRAY_SIZE(priv->tx_buf_data); i++) {
 399                desc = &ring_control->tx_data[i];
 400                if (desc->host_addr)
 401                        pci_unmap_single(priv->pdev,
 402                                         le32_to_cpu(desc->host_addr),
 403                                         le16_to_cpu(desc->len),
 404                                         PCI_DMA_TODEVICE);
 405
 406                p54_free_skb(dev, priv->tx_buf_data[i]);
 407                priv->tx_buf_data[i] = NULL;
 408        }
 409
 410        for (i = 0; i < ARRAY_SIZE(priv->tx_buf_mgmt); i++) {
 411                desc = &ring_control->tx_mgmt[i];
 412                if (desc->host_addr)
 413                        pci_unmap_single(priv->pdev,
 414                                         le32_to_cpu(desc->host_addr),
 415                                         le16_to_cpu(desc->len),
 416                                         PCI_DMA_TODEVICE);
 417
 418                p54_free_skb(dev, priv->tx_buf_mgmt[i]);
 419                priv->tx_buf_mgmt[i] = NULL;
 420        }
 421
 422        memset(ring_control, 0, sizeof(*ring_control));
 423}
 424
 425static int p54p_open(struct ieee80211_hw *dev)
 426{
 427        struct p54p_priv *priv = dev->priv;
 428        int err;
 429
 430        init_completion(&priv->boot_comp);
 431        err = request_irq(priv->pdev->irq, p54p_interrupt,
 432                          IRQF_SHARED, "p54pci", dev);
 433        if (err) {
 434                dev_err(&priv->pdev->dev, "failed to register IRQ handler\n");
 435                return err;
 436        }
 437
 438        memset(priv->ring_control, 0, sizeof(*priv->ring_control));
 439        err = p54p_upload_firmware(dev);
 440        if (err) {
 441                free_irq(priv->pdev->irq, dev);
 442                return err;
 443        }
 444        priv->rx_idx_data = priv->tx_idx_data = 0;
 445        priv->rx_idx_mgmt = priv->tx_idx_mgmt = 0;
 446
 447        p54p_refill_rx_ring(dev, 0, priv->ring_control->rx_data,
 448                ARRAY_SIZE(priv->ring_control->rx_data), priv->rx_buf_data);
 449
 450        p54p_refill_rx_ring(dev, 2, priv->ring_control->rx_mgmt,
 451                ARRAY_SIZE(priv->ring_control->rx_mgmt), priv->rx_buf_mgmt);
 452
 453        P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma));
 454        P54P_READ(ring_control_base);
 455        wmb();
 456        udelay(10);
 457
 458        P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_INIT));
 459        P54P_READ(int_enable);
 460        wmb();
 461        udelay(10);
 462
 463        P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
 464        P54P_READ(dev_int);
 465
 466        if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) {
 467                printk(KERN_ERR "%s: Cannot boot firmware!\n",
 468                       wiphy_name(dev->wiphy));
 469                p54p_stop(dev);
 470                return -ETIMEDOUT;
 471        }
 472
 473        P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_UPDATE));
 474        P54P_READ(int_enable);
 475        wmb();
 476        udelay(10);
 477
 478        P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
 479        P54P_READ(dev_int);
 480        wmb();
 481        udelay(10);
 482
 483        return 0;
 484}
 485
 486static int __devinit p54p_probe(struct pci_dev *pdev,
 487                                const struct pci_device_id *id)
 488{
 489        struct p54p_priv *priv;
 490        struct ieee80211_hw *dev;
 491        unsigned long mem_addr, mem_len;
 492        int err;
 493
 494        err = pci_enable_device(pdev);
 495        if (err) {
 496                dev_err(&pdev->dev, "Cannot enable new PCI device\n");
 497                return err;
 498        }
 499
 500        mem_addr = pci_resource_start(pdev, 0);
 501        mem_len = pci_resource_len(pdev, 0);
 502        if (mem_len < sizeof(struct p54p_csr)) {
 503                dev_err(&pdev->dev, "Too short PCI resources\n");
 504                goto err_disable_dev;
 505        }
 506
 507        err = pci_request_regions(pdev, "p54pci");
 508        if (err) {
 509                dev_err(&pdev->dev, "Cannot obtain PCI resources\n");
 510                goto err_disable_dev;
 511        }
 512
 513        if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
 514            pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
 515                dev_err(&pdev->dev, "No suitable DMA available\n");
 516                goto err_free_reg;
 517        }
 518
 519        pci_set_master(pdev);
 520        pci_try_set_mwi(pdev);
 521
 522        pci_write_config_byte(pdev, 0x40, 0);
 523        pci_write_config_byte(pdev, 0x41, 0);
 524
 525        dev = p54_init_common(sizeof(*priv));
 526        if (!dev) {
 527                dev_err(&pdev->dev, "ieee80211 alloc failed\n");
 528                err = -ENOMEM;
 529                goto err_free_reg;
 530        }
 531
 532        priv = dev->priv;
 533        priv->pdev = pdev;
 534
 535        SET_IEEE80211_DEV(dev, &pdev->dev);
 536        pci_set_drvdata(pdev, dev);
 537
 538        priv->map = ioremap(mem_addr, mem_len);
 539        if (!priv->map) {
 540                dev_err(&pdev->dev, "Cannot map device memory\n");
 541                err = -ENOMEM;
 542                goto err_free_dev;
 543        }
 544
 545        priv->ring_control = pci_alloc_consistent(pdev, sizeof(*priv->ring_control),
 546                                                  &priv->ring_control_dma);
 547        if (!priv->ring_control) {
 548                dev_err(&pdev->dev, "Cannot allocate rings\n");
 549                err = -ENOMEM;
 550                goto err_iounmap;
 551        }
 552        priv->common.open = p54p_open;
 553        priv->common.stop = p54p_stop;
 554        priv->common.tx = p54p_tx;
 555
 556        spin_lock_init(&priv->lock);
 557        tasklet_init(&priv->tasklet, p54p_tasklet, (unsigned long)dev);
 558
 559        err = request_firmware(&priv->firmware, "isl3886pci",
 560                               &priv->pdev->dev);
 561        if (err) {
 562                dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n");
 563                err = request_firmware(&priv->firmware, "isl3886",
 564                                       &priv->pdev->dev);
 565                if (err)
 566                        goto err_free_common;
 567        }
 568
 569        err = p54p_open(dev);
 570        if (err)
 571                goto err_free_common;
 572        err = p54_read_eeprom(dev);
 573        p54p_stop(dev);
 574        if (err)
 575                goto err_free_common;
 576
 577        err = p54_register_common(dev, &pdev->dev);
 578        if (err)
 579                goto err_free_common;
 580
 581        return 0;
 582
 583 err_free_common:
 584        release_firmware(priv->firmware);
 585        pci_free_consistent(pdev, sizeof(*priv->ring_control),
 586                            priv->ring_control, priv->ring_control_dma);
 587
 588 err_iounmap:
 589        iounmap(priv->map);
 590
 591 err_free_dev:
 592        pci_set_drvdata(pdev, NULL);
 593        p54_free_common(dev);
 594
 595 err_free_reg:
 596        pci_release_regions(pdev);
 597 err_disable_dev:
 598        pci_disable_device(pdev);
 599        return err;
 600}
 601
 602static void __devexit p54p_remove(struct pci_dev *pdev)
 603{
 604        struct ieee80211_hw *dev = pci_get_drvdata(pdev);
 605        struct p54p_priv *priv;
 606
 607        if (!dev)
 608                return;
 609
 610        p54_unregister_common(dev);
 611        priv = dev->priv;
 612        release_firmware(priv->firmware);
 613        pci_free_consistent(pdev, sizeof(*priv->ring_control),
 614                            priv->ring_control, priv->ring_control_dma);
 615        iounmap(priv->map);
 616        pci_release_regions(pdev);
 617        pci_disable_device(pdev);
 618        p54_free_common(dev);
 619}
 620
 621#ifdef CONFIG_PM
 622static int p54p_suspend(struct pci_dev *pdev, pm_message_t state)
 623{
 624        struct ieee80211_hw *dev = pci_get_drvdata(pdev);
 625        struct p54p_priv *priv = dev->priv;
 626
 627        if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) {
 628                ieee80211_stop_queues(dev);
 629                p54p_stop(dev);
 630        }
 631
 632        pci_save_state(pdev);
 633        pci_set_power_state(pdev, pci_choose_state(pdev, state));
 634        return 0;
 635}
 636
 637static int p54p_resume(struct pci_dev *pdev)
 638{
 639        struct ieee80211_hw *dev = pci_get_drvdata(pdev);
 640        struct p54p_priv *priv = dev->priv;
 641
 642        pci_set_power_state(pdev, PCI_D0);
 643        pci_restore_state(pdev);
 644
 645        if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) {
 646                p54p_open(dev);
 647                ieee80211_wake_queues(dev);
 648        }
 649
 650        return 0;
 651}
 652#endif /* CONFIG_PM */
 653
 654static struct pci_driver p54p_driver = {
 655        .name           = "p54pci",
 656        .id_table       = p54p_table,
 657        .probe          = p54p_probe,
 658        .remove         = __devexit_p(p54p_remove),
 659#ifdef CONFIG_PM
 660        .suspend        = p54p_suspend,
 661        .resume         = p54p_resume,
 662#endif /* CONFIG_PM */
 663};
 664
 665static int __init p54p_init(void)
 666{
 667        return pci_register_driver(&p54p_driver);
 668}
 669
 670static void __exit p54p_exit(void)
 671{
 672        pci_unregister_driver(&p54p_driver);
 673}
 674
 675module_init(p54p_init);
 676module_exit(p54p_exit);
 677
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.