AR9344芯片中5G网卡是通过AHB总线连接在SOC中的.还有一个2.4G的无线网卡是挂在PCI总线上的
在ath9k驱动insmod时首先调用的是ath9k_init(void);代码如下:
-
static int __init ath9k_init(void)
-
{
-
int error;
-
-
error = ath_ahb_init(); //这是是初始化AHB总线上的网卡设备的
-
if (error < 0) {
-
error = -ENODEV;
-
goto err_out;
-
}
-
-
error = ath_pci_init(); //初始化PCI总线的网卡设备
-
if (error < 0) {
-
pr_err("No PCI devices found, driver not installed\n");
-
error = -ENODEV;
-
goto err_ahb_exit;
-
}
-
-
return 0;
-
-
err_ahb_exit:
-
ath_ahb_exit();
-
err_out:
-
return error;
-
}
-
module_init(ath9k_init);
通过上面的代码我们知道insmod ath9k驱动时会分别初始化AHB和PCI总线的网卡设备.
我们再看看AHB初始化时会做什么操作:
-
int ath_ahb_init(void)
-
{
-
return platform_driver_register(&ath_ahb_driver);
-
}
其实就是通过函数platform_driver_register注册ahb驱动.
再看看ath_ahb_driver:
-
static struct platform_driver ath_ahb_driver = {
-
.probe = ath_ahb_probe,
-
.remove = ath_ahb_remove,
-
.driver = {
-
.name = "ath9k",
-
},
-
.id_table = ath9k_platform_id_table,
-
};
我们主要关注ath_ahb_probe函数, 在注册完成后会系统会自动调用它.
ath_ahb_remove函数会在unregister时候调用.
-
static int ath_ahb_probe(struct platform_device *pdev)
-
{
-
void __iomem *mem;
-
struct ath_softc *sc; //atheros用于硬件和mac层交互的中间载体.后面我们会单独分析改结构
-
struct ieee80211_hw *hw; //mac80211层中代表硬件的信息和状态.后面会分析.
-
struct resource *res;
-
const struct platform_device_id *id = platform_get_device_id(pdev);
-
int irq;
-
int ret = 0;
-
struct ath_hw *ah;
-
char hw_name[64];
-
-
if (!dev_get_platdata(&pdev->dev)) {
-
dev_err(&pdev->dev, "no platform data specified\n");
-
return -EINVAL;
-
}
-
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
if (res == NULL) {
-
dev_err(&pdev->dev, "no memory resource found\n");
-
return -ENXIO;
-
}
-
-
mem = devm_ioremap_nocache(&pdev->dev, res->start, resource_size(res));
-
if (mem == NULL) {
-
dev_err(&pdev->dev, "ioremap failed\n");
-
return -ENOMEM;
-
}
-
-
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);//获取设备irq线
-
if (res == NULL) {
-
dev_err(&pdev->dev, "no IRQ resource found\n");
-
return -ENXIO;
-
}
-
-
irq = res->start;
-
-
ath9k_fill_chanctx_ops();
-
hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);//分配mac层硬件相关信息和状态结构体
-
if (hw == NULL) {
-
dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
-
return -ENOMEM;
-
}
-
-
SET_IEEE80211_DEV(hw, &pdev->dev);
-
platform_set_drvdata(pdev, hw);
-
-
sc = hw->priv;
-
sc->hw = hw;
-
sc->dev = &pdev->dev;
-
sc->mem = mem;
-
sc->irq = irq;
-
-
ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);//注册中断号
-
if (ret) {
-
dev_err(&pdev->dev, "request_irq failed\n");
-
goto err_free_hw;
-
}
-
-
ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops);
-
if (ret) {
-
dev_err(&pdev->dev, "failed to initialize device\n");
-
goto err_irq;
-
}
-
-
ah = sc->sc_ah;
-
ath9k_hw_name(ah, hw_name, sizeof(hw_name));
-
printk("carson[%s:%d], irq=%d\n", __func__, __LINE__, irq);
-
wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
-
hw_name, (unsigned long)mem, irq);
-
-
return 0;
-
-
err_irq:
-
free_irq(irq, sc);
-
err_free_hw:
-
ieee80211_free_hw(hw);
-
return ret;
-
}
上面即是AHB驱动注册是的相关操作包括: 请求设备的IO内存,irq号等.分配ieee80211_hw结构.
我们先看看相关的结构体分别代码什么意思,再来分析上面的代码.
阅读(2595) | 评论(0) | 转发(0) |