📄 pci.c
字号:
if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {// u32 reghi, reglo; agnx_set_bssid(priv, conf->bssid); memcpy(priv->bssid, conf->bssid, ETH_ALEN); hash_write(priv, conf->bssid, BSSID_STAID); sta_init(priv, BSSID_STAID); /* FIXME needed? */ sta_power_init(priv, BSSID_STAID); agnx_write32(ctl, AGNX_BM_MTSM, 0xff & ~0x1); } if (conf->ssid_len != priv->ssid_len || memcmp(conf->ssid, priv->ssid, conf->ssid_len)) { agnx_set_ssid(priv, conf->ssid, conf->ssid_len); priv->ssid_len = conf->ssid_len; memcpy(priv->ssid, conf->ssid, conf->ssid_len); } spin_unlock(&priv->lock); return 0;} /* agnx_config_interface */static void agnx_configure_filter(struct ieee80211_hw *dev, unsigned int changed_flags, unsigned int *total_flags, int mc_count, struct dev_mc_list *mclist){ unsigned int new_flags = 0; *total_flags = new_flags; /* TODO */}static int agnx_add_interface(struct ieee80211_hw *dev, struct ieee80211_if_init_conf *conf){ struct agnx_priv *priv = dev->priv; AGNX_TRACE; spin_lock(&priv->lock); /* FIXME */ if (priv->mode != NL80211_IFTYPE_MONITOR) return -EOPNOTSUPP; switch (conf->type) { case NL80211_IFTYPE_STATION: priv->mode = conf->type; break; default: return -EOPNOTSUPP; } spin_unlock(&priv->lock); return 0;}static void agnx_remove_interface(struct ieee80211_hw *dev, struct ieee80211_if_init_conf *conf){ struct agnx_priv *priv = dev->priv; AGNX_TRACE; /* TODO */ priv->mode = NL80211_IFTYPE_MONITOR;}static int agnx_get_stats(struct ieee80211_hw *dev, struct ieee80211_low_level_stats *stats){ struct agnx_priv *priv = dev->priv; AGNX_TRACE; spin_lock(&priv->lock); /* TODO !! */ memcpy(stats, &priv->stats, sizeof(*stats)); spin_unlock(&priv->lock); return 0;}static u64 agnx_get_tsft(struct ieee80211_hw *dev){ void __iomem *ctl = ((struct agnx_priv *)dev->priv)->ctl; u32 tsftl; u64 tsft; AGNX_TRACE; /* FIXME */ tsftl = ioread32(ctl + AGNX_TXM_TIMESTAMPLO); tsft = ioread32(ctl + AGNX_TXM_TIMESTAMPHI); tsft <<= 32; tsft |= tsftl; return tsft;}static int agnx_get_tx_stats(struct ieee80211_hw *dev, struct ieee80211_tx_queue_stats *stats){ struct agnx_priv *priv = dev->priv; AGNX_TRACE; /* FIXME now we just using txd queue, but should using txm queue too */ stats[0].len = (priv->txd.idx - priv->txd.idx_sent) / 2; stats[0].limit = priv->txd.size - 2; stats[0].count = priv->txd.idx / 2; return 0;}static struct ieee80211_ops agnx_ops = { .tx = agnx_tx, .start = agnx_start, .stop = agnx_stop, .add_interface = agnx_add_interface, .remove_interface = agnx_remove_interface, .config = agnx_config, .config_interface = agnx_config_interface, .configure_filter = agnx_configure_filter, .get_stats = agnx_get_stats, .get_tx_stats = agnx_get_tx_stats, .get_tsf = agnx_get_tsft};static void __devexit agnx_pci_remove(struct pci_dev *pdev){ struct ieee80211_hw *dev = pci_get_drvdata(pdev); struct agnx_priv *priv = dev->priv; AGNX_TRACE; if (!dev) return; if (priv->mac80211_registered) { ieee80211_unregister_hw(dev); priv->mac80211_registered = 0; } pci_iounmap(pdev, priv->ctl); pci_iounmap(pdev, priv->data); pci_release_regions(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); ieee80211_free_hw(dev);}static int __devinit agnx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id){ struct ieee80211_hw *dev; struct agnx_priv *priv; u32 mem_addr0, mem_len0; u32 mem_addr1, mem_len1; int err; DECLARE_MAC_BUF(mac); err = pci_enable_device(pdev); if (err) { printk(KERN_ERR PFX "Can't enable new PCI device\n"); return err; } pci_set_master(pdev); /* get pci resource */ mem_addr0 = pci_resource_start(pdev, 0); mem_len0 = pci_resource_len(pdev, 0); mem_addr1 = pci_resource_start(pdev, 1); mem_len1 = pci_resource_len(pdev, 1); printk(KERN_DEBUG PFX "Memaddr0 is %x, length is %x\n", mem_addr0, mem_len0); printk(KERN_DEBUG PFX "Memaddr1 is %x, length is %x\n", mem_addr1, mem_len1); err = pci_request_regions(pdev, "agnx-pci"); if (err) { printk(KERN_ERR PFX "Can't obtain PCI resource\n"); return err; } if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { printk(KERN_ERR PFX "No suitable DMA available\n"); goto err_free_reg; } printk(KERN_DEBUG PFX "pdev->irq is %d\n", pdev->irq); dev = ieee80211_alloc_hw(sizeof(struct agnx_priv), &agnx_ops); if (!dev) { printk(KERN_ERR PFX "ieee80211 alloc failed\n"); err = -ENOMEM; goto err_free_reg; } /* init priv */ priv = dev->priv; memset(priv, 0, sizeof(*priv)); priv->mode = NL80211_IFTYPE_MONITOR; priv->pdev = pdev; priv->hw = dev; spin_lock_init(&priv->lock); priv->init_status = AGNX_UNINIT; /* Map mem #1 and #2 */ priv->ctl = pci_iomap(pdev, 0, mem_len0); printk(KERN_DEBUG PFX"MEM1 mapped address is 0x%p\n", priv->ctl); if (!priv->ctl) { printk(KERN_ERR PFX "Can't map device memory\n"); goto err_free_dev; } priv->data = pci_iomap(pdev, 1, mem_len1); printk(KERN_DEBUG PFX "MEM2 mapped address is 0x%p\n", priv->data); if (!priv->data) { printk(KERN_ERR PFX "Can't map device memory\n"); goto err_iounmap2; } pci_read_config_byte(pdev, PCI_REVISION_ID, &priv->revid); priv->band = agnx_band_2GHz; SET_IEEE80211_DEV(dev, &pdev->dev); pci_set_drvdata(pdev, dev); dev->extra_tx_headroom = sizeof(struct agnx_hdr); /* FIXME It only include FCS in promious mode but not manage mode */ /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS; */ dev->channel_change_time = 5000; dev->max_signal = 100; dev->queues = 1; agnx_get_mac_address(priv); SET_IEEE80211_PERM_ADDR(dev, priv->mac_addr); priv->channel = 1; dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &agnx_band_2GHz; err = ieee80211_register_hw(dev); if (err) { printk(KERN_ERR PFX "Can't register hardware\n"); goto err_iounmap; } agnx_hw_reset(priv); printk(PFX "%s: hwaddr %s, Rev 0x%02x\n", wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), priv->revid); priv->mac80211_registered = 1; return 0; err_iounmap: pci_iounmap(pdev, priv->data); err_iounmap2: pci_iounmap(pdev, priv->ctl); err_free_dev: pci_set_drvdata(pdev, NULL); ieee80211_free_hw(dev); err_free_reg: pci_release_regions(pdev); pci_disable_device(pdev); return err;} /* agnx_pci_probe*/#ifdef CONFIG_PMstatic int agnx_pci_suspend(struct pci_dev *pdev, pm_message_t state){ struct ieee80211_hw *dev = pci_get_drvdata(pdev); AGNX_TRACE; ieee80211_stop_queues(dev); agnx_stop(dev); pci_save_state(pdev); pci_set_power_state(pdev, pci_choose_state(pdev, state)); return 0;}static int agnx_pci_resume(struct pci_dev *pdev){ struct ieee80211_hw *dev = pci_get_drvdata(pdev); AGNX_TRACE; pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); agnx_start(dev); ieee80211_wake_queues(dev); return 0;}#else #define agnx_pci_suspend NULL#define agnx_pci_resume NULL#endif /* CONFIG_PM */static struct pci_driver agnx_pci_driver = { .name = "agnx-pci", .id_table = agnx_pci_id_tbl, .probe = agnx_pci_probe, .remove = __devexit_p(agnx_pci_remove), .suspend = agnx_pci_suspend, .resume = agnx_pci_resume,};static int __init agnx_pci_init(void){ AGNX_TRACE; return pci_register_driver(&agnx_pci_driver);}static void __exit agnx_pci_exit(void){ AGNX_TRACE; pci_unregister_driver(&agnx_pci_driver);}module_init(agnx_pci_init);module_exit(agnx_pci_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -