1.CPSW驱动及设备的初始化;
(1)首先驱动注册,会自动进入cpsw_probe执行;
1 static struct platform_driver cpsw_driver = { 2 .driver = { 3 .name = "cpsw", 4 .owner = THIS_MODULE, 5 .pm = &cpsw_pm_ops, 6 }, 7 .probe = cpsw_probe, 8 .remove = __devexit_p(cpsw_remove), 9 };
进入CPSW后,主要干活是:
- 创建 cpsw_priv *priv,入参pedv->dev.platform_data的参数,都赋值到priv里,后续主要使用的结构;
- 创建netdev结构,这个是网卡的默认数据结构,和上层协议栈通讯,注意注册都是用的name,后续作为匹配的,name应该来自入参;
- 初始化priv_sl2(网卡2),调用cpsw_init_slave_emac()函数,大部分是直接使用网卡1的priv数据直接复制过去;
- cpsw_netdev_ops内open,xmit等函数赋值到netdev的ndev->netdev_ops,协议栈使用会最终调用这些函数;
数据结构关系:
platform_device *pdev : .dev , 指向创建 netdev *ndev, 在netdev结构体后面定义一个 cpsw_priv *priv,
.dev.platform_data , 改名重定义指向到data ,
data: DMA DMA中断 ----> cpsw_priv *priv, 这个结构也是后面主要用的;
reg 寄存器信息
ALE 模块
MAC 配置
clk 时钟
1 static int __devinit cpsw_probe(struct platform_device *pdev) 2 { 3 struct cpsw_platform_data *data = pdev->dev.platform_data; 4 struct net_device *ndev; 5 struct cpsw_priv *priv; 6 struct cpdma_params dma_params; 7 struct cpsw_ale_params ale_params; 8 void __iomem *regs; 15 .............. 16 ndev = alloc_etherdev(sizeof(struct cpsw_priv)); 17 if (!ndev) { 18 pr_err("cpsw: error allocating net_device\n"); 19 return -ENOMEM; 20 } 21 22 platform_set_drvdata(pdev, ndev); 23 priv = netdev_priv(ndev); 24 spin_lock_init(&priv->lock); 25 priv->data = *data; 26 priv->pdev = pdev; 27 priv->ndev = ndev; 28 priv->dev = &ndev->dev; 29 priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG); 30 priv->rx_packet_max = max(rx_packet_max, 128); 31 priv->cpts = devm_kzalloc(&pdev->dev, sizeof(struct cpts), GFP_KERNEL); 32 33 if (is_valid_ether_addr(data->mac_addr)) { 34 memcpy(priv->mac_addr, data->mac_addr, ETH_ALEN); 35 printk(KERN_INFO"Detected MACID=%x:%x:%x:%x:%x:%x\n", 36 priv->mac_addr[0], priv->mac_addr[1], 37 priv->mac_addr[2], priv->mac_addr[3], 38 priv->mac_addr[4], priv->mac_addr[5]); 39 } else { 40 random_ether_addr(priv->mac_addr); 41 printk(KERN_INFO"Random MACID=%x:%x:%x:%x:%x:%x\n", 42 priv->mac_addr[0], priv->mac_addr[1], 43 priv->mac_addr[2], priv->mac_addr[3], 44 priv->mac_addr[4], priv->mac_addr[5]); 45 } 46 47 memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN); 48 49 priv->slaves = kzalloc(sizeof(struct cpsw_slave) * data->slaves, 50 GFP_KERNEL); 51 if (!priv->slaves) { 52 dev_err(priv->dev, "failed to allocate slave ports\n"); 53 ret = -EBUSY; 54 goto clean_ndev_ret; 55 } 56 for (i = 0; i < data->slaves; i++) 57 priv->slaves[i].slave_num = i; 58 59 priv->slaves[0].ndev = ndev; 60 priv->emac_port = 0; 61 62 pm_runtime_enable(&pdev->dev); 63 pm_runtime_get_sync(&pdev->dev); 64 priv->clk = clk_get(&pdev->dev, "fck"); 65 if (IS_ERR(priv->clk)) { 66 dev_err(&pdev->dev, "fck is not found\n"); 67 ret = -ENODEV; 68 goto clean_slave_ret; 69 } 70 71 priv->coal_intvl = 0; 72 priv->bus_freq_mhz = clk_get_rate(priv->clk) / 1000000; 73 74 priv->cpsw_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 75 if (!priv->cpsw_res) { 76 dev_err(priv->dev, "error getting i/o resource\n"); 77 ret = -ENOENT; 78 goto clean_clk_ret; 79 } 80 81 if (!request_mem_region(priv->cpsw_res->start, 82 resource_size(priv->cpsw_res), ndev->name)) { 83 dev_err(priv->dev, "failed request i/o region\n"); 84 ret = -ENXIO; 85 goto clean_clk_ret; 86 } 87 88 regs = ioremap(priv->cpsw_res->start, resource_size(priv->cpsw_res)); 89 if (!regs) { 90 dev_err(priv->dev, "unable to map i/o region\n"); 91 goto clean_cpsw_iores_ret; 92 } 93 priv->regs = regs; 94 priv->host_port = data->host_port_num; 95 priv->host_port_regs = regs + data->host_port_reg_ofs; 96 priv->hw_stats = regs + data->hw_stats_reg_ofs; 97 priv->cpts->reg = regs + data->cpts_reg_ofs; 98 99 priv->cpsw_ss_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 100 if (!priv->cpsw_ss_res) { 101 dev_err(priv->dev, "error getting i/o resource\n"); 102 ret = -ENOENT; 103 goto clean_clk_ret; 104 } 105 106 if (!request_mem_region(priv->cpsw_ss_res->start, 107 resource_size(priv->cpsw_ss_res), ndev->name)) { 108 dev_err(priv->dev, "failed request i/o region\n"); 109 ret = -ENXIO; 110 goto clean_clk_ret; 111 } 112 113 regs = ioremap(priv->cpsw_ss_res->start, 114 resource_size(priv->cpsw_ss_res)); 115 if (!regs) { 116 dev_err(priv->dev, "unable to map i/o region\n"); 117 goto clean_cpsw_ss_iores_ret; 118 } 119 priv->wr_regs = regs; 120 121 for_each_slave(priv, cpsw_slave_init, priv); 122 123 omap_ctrl_writel(CPSW_TIMER_MASK, CPSW_TIMER_CAP_REG); 124 125 dmtimer_rx = omap_dm_timer_request_specific(CPSW_RX_TIMER_REQ); 126 if (!dmtimer_rx) { 127 dev_err(priv->dev, "Error getting Rx Timer resource\n"); 128 ret = -ENODEV; 129 goto clean_iomap_ret; 130 } 131 dmtimer_tx = omap_dm_timer_request_specific(CPSW_TX_TIMER_REQ); 132 if (!dmtimer_tx) { 133 dev_err(priv->dev, "Error getting Tx Timer resource\n"); 134 ret = -ENODEV; 135 goto clean_timer_rx_ret; 136 } 137 138 memset(&dma_params, 0, sizeof(dma_params)); 139 dma_params.dev = &pdev->dev; 140 dma_params.dmaregs = (void __iomem *)(((u32)priv->regs) + 141 data->cpdma_reg_ofs); 142 dma_params.rxthresh = (void __iomem *)(((u32)priv->regs) + 143 data->cpdma_reg_ofs + CPDMA_RXTHRESH); 144 dma_params.rxfree = (void __iomem *)(((u32)priv->regs) + 145 data->cpdma_reg_ofs + CPDMA_RXFREE); 146 147 if (data->version == CPSW_VERSION_2) { 148 dma_params.txhdp = (void __iomem *)(((u32)priv->regs) + 149 data->cpdma_reg_ofs + CPDMA_TXHDP_VER2); 150 dma_params.rxhdp = (void __iomem *)(((u32)priv->regs) + 151 data->cpdma_reg_ofs + CPDMA_RXHDP_VER2); 152 dma_params.txcp = (void __iomem *)(((u32)priv->regs) + 153 data->cpdma_reg_ofs + CPDMA_TXCP_VER2); 154 dma_params.rxcp = (void __iomem *)(((u32)priv->regs) + 155 data->cpdma_reg_ofs + CPDMA_RXCP_VER2); 156 } else { 157 dma_params.txhdp = (void __iomem *)(((u32)priv->regs) + 158 data->cpdma_reg_ofs + CPDMA_TXHDP_VER1); 159 dma_params.rxhdp = (void __iomem *)(((u32)priv->regs) + 160 data->cpdma_reg_ofs + CPDMA_RXHDP_VER1); 161 dma_params.txcp = (void __iomem *)(((u32)priv->regs) + 162 data->cpdma_reg_ofs + CPDMA_TXCP_VER1); 163 dma_params.rxcp = (void __iomem *)(((u32)priv->regs) + 164 data->cpdma_reg_ofs + CPDMA_RXCP_VER1); 165 } 166 167 dma_params.num_chan = data->channels; 168 dma_params.has_soft_reset = true; 169 dma_params.min_packet_size = CPSW_MIN_PACKET_SIZE; 170 dma_params.desc_mem_size = data->bd_ram_size; 171 dma_params.desc_align = 16; 172 dma_params.has_ext_regs = true; 173 dma_params.desc_mem_phys = data->no_bd_ram ? 0 : 174 (u32 __force)priv->cpsw_res->start + data->bd_ram_ofs; 175 dma_params.desc_hw_addr = data->hw_ram_addr ? 176 data->hw_ram_addr : dma_params.desc_mem_phys ; 177 178 priv->dma = cpdma_ctlr_create(&dma_params); 179 if (!priv->dma) { 180 dev_err(priv->dev, "error initializing dma\n"); 181 ret = -ENOMEM; 182 goto clean_timer_ret; 183 } 184 185 priv->txch = cpdma_chan_create(priv->dma, tx_chan_num(0), 186 cpsw_tx_handler); 187 priv->rxch = cpdma_chan_create(priv->dma, rx_chan_num(0), 188 cpsw_rx_handler); 189 190 if (WARN_ON(!priv->txch || !priv->rxch)) { 191 dev_err(priv->dev, "error initializing dma channels\n"); 192 ret = -ENOMEM; 193 goto clean_dma_ret; 194 } 195 196 memset(&ale_params, 0, sizeof(ale_params)); 197 ale_params.dev = &ndev->dev; 198 ale_params.ale_regs = (void *)((u32)priv->regs) + 199 ((u32)data->ale_reg_ofs); 200 ale_params.ale_ageout = ale_ageout; 201 ale_params.ale_entries = data->ale_entries; 202 ale_params.ale_ports = data->slaves; 203 204 priv->ale = cpsw_ale_create(&ale_params); 205 if (!priv->ale) { 206 dev_err(priv->dev, "error initializing ale engine\n"); 207 ret = -ENODEV; 208 goto clean_dma_ret; 209 } 210 211 while ((i = platform_get_irq(pdev, k)) >= 0) { 212 if (request_irq(i, cpsw_interrupt, IRQF_DISABLED, 213 dev_name(&pdev->dev), priv)) { 214 dev_err(priv->dev, "error attaching irq\n"); 215 goto clean_ale_ret; 216 } 217 priv->irqs_table[k] = i; 218 priv->num_irqs = ++k; 219 } 220 221 #ifdef VLAN_SUPPORT 222 ndev->features |= NETIF_F_HW_VLAN_FILTER; 223 #endif 224 225 ndev->flags |= IFF_ALLMULTI; /* see cpsw_ndo_change_rx_flags() */ 226 227 ndev->netdev_ops = &cpsw_netdev_ops; 228 SET_ETHTOOL_OPS(ndev, &cpsw_ethtool_ops); 229 netif_napi_add(ndev, &priv->napi, cpsw_poll, CPSW_POLL_WEIGHT); 230 231 /* register the network device */ 232 SET_NETDEV_DEV(ndev, &pdev->dev); 233 ret = register_netdev(ndev); 234 if (ret) { 235 dev_err(priv->dev, "error registering net device\n"); 236 ret = -ENODEV; 237 goto clean_irq_ret; 238 } 239 240 msg(notice, probe, "initialized device (regs %x, irq %d)\n", 241 priv->cpsw_res->start, ndev->irq); 242 243 ret = cpsw_init_slave_emac(pdev, priv); 244 if (ret) { 245 dev_err(priv->dev, "error probe slave 2 emac interface\n"); 246 goto clean_irq_ret; 247 } 248 249 return 0; 250 ................280 }