[Linux]移植驱动(一)配置环境&移植DM9000
[Linux]移植驱动(一)配置环境&移植DM9000
个人博客 https://aeneag.xyz/
艾恩凝
2021/7/12
introduction
前段时间进行写的驱动是在内核2.6版本上的,现在移植到新内核中去,万事开头难
开发板:JZ2440
操作系统:Ubuntu16.04
编译环境:arm-linux-gcc 4.3.2
内核:Linux 3.4.2
参考资料:韦东山 Linux 开发视频,网络
配置环境
问题描述:新内核之前移植过,编译环境,根文件系统理解还没上一层楼,花了一上午到下午快两点才彻底搞完,问题引出,首先挂载网络根文件系统挂载不上,尝试重新编译内核,又引出其他问题,之前内核编译的已经遗忘,重新清理了之前内核编译,忽略了清理之后需要重新配置,最开始出现的问题,怀疑根文件系统构建的有问题,一想之前可以用,没问题 ,只能把根文件系统烧到板子上才能挂载成功,后来才明白,新内核没有dm9000网卡驱动,需要配置,修改后,重新编译,板子上运行后,竟然乱码,就开始到处检查错误,找错误,清理编译,最后怀疑改的驱动有问题,改回之前的,清理之后重新编译,不乱码,就是没法挂载,改回去之后,又乱码,也不知道最后怎么怀疑改的有问题,重新修改了dm9000驱动,终于成功了,来来回回折腾到了两点
折腾的结局就是越来越熟
问题解决:
移植DM9000到内核3.4.2
之前有一篇移植这个的文章,之前的代码适配了内核2.6的版本,在这个基础上适配3.4.2版本
1--- dm9dev9000c_old.c 2021-07-12 16:37:33.638299772 +0800
2+++ dm9dev9000c.c 2021-07-12 15:18:47.258451326 +0800
3@@ -2,8 +2,10 @@
4 /*
5 * @author aen
6 * @date 2021/7/4
7+ * @modify support kernel 3.4.2 2021/7/12
8 */
9
10+
11 /*
12
13 dm9ks.c: Version 2.08 2007/02/12
14@@ -96,12 +98,13 @@
15 #include <asm/hardware.h>
16 #include <asm/irq.h>
17 #endif
18-
19+ #include <linux/interrupt.h>
20
21 #include <asm/delay.h>
22 #include <asm/irq.h>
23 #include <asm/io.h>
24- #include <asm/arch-s3c2410/regs-mem.h>
25+ #include "dm9000.h"
26+ //#include <asm/arch-s3c2410/regs-mem.h>
27
28 /* Board/System/Debug information/definition ---------------- */
29
30@@ -325,10 +328,10 @@
31 static int dmfe_set_settings(struct net_device *, struct ethtool_cmd *);
32 static u32 dmfe_get_link(struct net_device *);
33 static int dmfe_nway_reset(struct net_device *);
34- static uint32_t dmfe_get_rx_csum(struct net_device *);
35- static uint32_t dmfe_get_tx_csum(struct net_device *);
36- static int dmfe_set_rx_csum(struct net_device *, uint32_t );
37- static int dmfe_set_tx_csum(struct net_device *, uint32_t );
38+ //static uint32_t dmfe_get_rx_csum(struct net_device *);
39+ //static uint32_t dmfe_get_tx_csum(struct net_device *);
40+ //static int dmfe_set_rx_csum(struct net_device *, uint32_t );
41+ //static int dmfe_set_tx_csum(struct net_device *, uint32_t );
42
43 #ifdef DM8606
44 #include "dm8606.h"
45@@ -359,7 +362,7 @@
46 if(!dev)
47 return ERR_PTR(-ENOMEM);
48
49- SET_MODULE_OWNER(dev);
50+ //SET_MODULE_OWNER(dev);
51 err = dmfe_probe1(dev);
52 if (err)
53 goto out;
54@@ -379,7 +382,23 @@
55 #endif
56 return ERR_PTR(err);
57 }
58-
59+ static const struct net_device_ops dm9000C_netdev_ops = {
60+ .ndo_open = dmfe_open,
61+ .ndo_stop = dmfe_stop,
62+ .ndo_start_xmit = dmfe_start_xmit,
63+ .ndo_tx_timeout = dmfe_timeout,
64+ .ndo_set_rx_mode = dm9000_hash_table,
65+ .ndo_do_ioctl = dmfe_do_ioctl,
66+ .ndo_change_mtu = eth_change_mtu,
67+ .ndo_get_stats = dmfe_get_stats,
68+ // .ndo_set_features = dm9000_set_features,
69+ .ndo_validate_addr = eth_validate_addr,
70+ .ndo_set_mac_address = eth_mac_addr,
71+#ifdef CONFIG_NET_POLL_CONTROLLER
72+ .ndo_poll_controller = dm9000_poll_controller,
73+#endif
74+ };
75+
76 int __init dmfe_probe1(struct net_device *dev)
77 {
78 struct board_info *db; /* Point a board information structure */
79@@ -408,10 +427,11 @@
80
81 printk(KERN_ERR"<DM9KS> I/O: %x, VID: %x \n",iobase, id_val);
82 dm9000_found = TRUE;
83-
84+
85+ db = netdev_priv(dev);
86 /* Allocated board information structure */
87- memset(dev->priv, 0, sizeof(struct board_info));
88- db = (board_info_t *)dev->priv;
89+ memset(db, 0, sizeof(struct board_info));
90+
91 dmfe_dev = dev;
92 db->io_addr = iobase;
93 db->io_data = iobase + 4;
94@@ -420,17 +440,20 @@
95 chip_info = ior(db,0x43);
96 //if((db->chip_revision!=0x1A) || ((chip_info&(1<<5))!=0) || ((chip_info&(1<<2))!=1)) return -ENODEV;
97
98- /* driver system function */
99+ /* driver system function */
100+ dev->netdev_ops = &dm9000C_netdev_ops;
101+
102+
103 dev->base_addr = iobase;
104 dev->irq = irq;
105- dev->open = &dmfe_open;
106- dev->hard_start_xmit = &dmfe_start_xmit;
107+ //dev->open = &dmfe_open;
108+ //dev->hard_start_xmit = &dmfe_start_xmit;
109 dev->watchdog_timeo = 5*HZ;
110- dev->tx_timeout = dmfe_timeout;
111- dev->stop = &dmfe_stop;
112- dev->get_stats = &dmfe_get_stats;
113- dev->set_multicast_list = &dm9000_hash_table;
114- dev->do_ioctl = &dmfe_do_ioctl;
115+ //dev->tx_timeout = dmfe_timeout;
116+ //dev->stop = &dmfe_stop;
117+ //dev->get_stats = &dmfe_get_stats;
118+ //dev->set_multicast_list = &dm9000_hash_table;
119+ //dev->do_ioctl = &dmfe_do_ioctl;
120 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,28)
121 dev->ethtool_ops = &dmfe_ethtool_ops;
122 #endif
123@@ -480,7 +503,7 @@
124 */
125 static int dmfe_open(struct net_device *dev)
126 {
127- board_info_t *db = (board_info_t *)dev->priv;
128+ board_info_t *db = netdev_priv(dev);
129 u8 reg_nsr;
130 int i;
131 DMFE_DBUG(0, "dmfe_open", 0);
132@@ -663,7 +686,7 @@
133 */
134 static void dmfe_init_dm9000(struct net_device *dev)
135 {
136- board_info_t *db = (board_info_t *)dev->priv;
137+ board_info_t *db = netdev_priv(dev);
138 DMFE_DBUG(0, "dmfe_init_dm9000()", 0);
139
140 spin_lock_init(&db->lock);
141@@ -746,7 +769,7 @@
142 */
143 static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev)
144 {
145- board_info_t *db = (board_info_t *)dev->priv;
146+ board_info_t *db = netdev_priv(dev);
147 char * data_ptr;
148 int i, tmplen;
149 u16 MDWAH, MDWAL;
150@@ -857,7 +880,7 @@
151 */
152 static int dmfe_stop(struct net_device *dev)
153 {
154- board_info_t *db = (board_info_t *)dev->priv;
155+ board_info_t *db = netdev_priv(dev);
156 DMFE_DBUG(0, "dmfe_stop", 0);
157
158 /* deleted timer */
159@@ -890,7 +913,7 @@
160 static void dmfe_tx_done(unsigned long unused)
161 {
162 struct net_device *dev = dmfe_dev;
163- board_info_t *db = (board_info_t *)dev->priv;
164+ board_info_t *db = netdev_priv(dev);
165 int nsr;
166
167 DMFE_DBUG(0, "dmfe_tx_done()", 0);
168@@ -939,7 +962,7 @@
169 DMFE_DBUG(0, "dmfe_interrupt()", 0);
170
171 /* A real interrupt coming */
172- db = (board_info_t *)dev->priv;
173+ db = netdev_priv(dev);
174 spin_lock(&db->lock);
175
176 /* Save previous register address */
177@@ -1006,7 +1029,7 @@
178 */
179 static struct net_device_stats * dmfe_get_stats(struct net_device *dev)
180 {
181- board_info_t *db = (board_info_t *)dev->priv;
182+ board_info_t *db =netdev_priv(dev);
183 DMFE_DBUG(0, "dmfe_get_stats", 0);
184 return &db->stats;
185 }
186@@ -1041,7 +1064,7 @@
187 */
188 static int dmfe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
189 {
190- board_info_t *db = (board_info_t *)dev->priv;
191+ board_info_t *db = netdev_priv(dev);
192 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) /* for kernel 2.6.7 */
193 struct mii_ioctl_data *data=(struct mii_ioctl_data *)&ifr->ifr_data;
194 #endif
195@@ -1070,7 +1093,7 @@
196 /* Our watchdog timed out. Called by the networking layer */
197 static void dmfe_timeout(struct net_device *dev)
198 {
199- board_info_t *db = (board_info_t *)dev->priv;
200+ board_info_t *db = netdev_priv(dev);
201 int i;
202
203 DMFE_DBUG(0, "dmfe_TX_timeout()", 0);
204@@ -1106,7 +1129,7 @@
205
206 static void dmfe_reset(struct net_device * dev)
207 {
208- board_info_t *db = (board_info_t *)dev->priv;
209+ board_info_t *db = netdev_priv(dev);
210 u8 reg_save;
211 int i;
212 /* Save previous register address */
213@@ -1140,7 +1163,7 @@
214 static void dmfe_timer(unsigned long data)
215 {
216 struct net_device * dev = (struct net_device *)data;
217- board_info_t *db = (board_info_t *)dev->priv;
218+ board_info_t *db = netdev_priv(dev);
219 DMFE_DBUG(0, "dmfe_timer()", 0);
220
221 if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
222@@ -1161,7 +1184,7 @@
223 */
224 static void dmfe_packet_receive(struct net_device *dev)
225 {
226- board_info_t *db = (board_info_t *)dev->priv;
227+ board_info_t *db = netdev_priv(dev);
228 struct sk_buff *skb;
229 u8 rxbyte;
230 u16 i, GoodPacket, tmplen = 0, MDRAH, MDRAL;
231@@ -1377,9 +1400,10 @@
232 /*
233 Set DM9000/DM9010 multicast address
234 */
235+ #if 0
236 static void dm9000_hash_table(struct net_device *dev)
237 {
238- board_info_t *db = (board_info_t *)dev->priv;
239+ board_info_t *db = netdev_priv(dev);
240 struct dev_mc_list *mcptr = dev->mc_list;
241 int mc_cnt = dev->mc_count;
242 u32 hash_val;
243@@ -1429,12 +1453,71 @@
244 iow(db, oft++, (hash_table[i] >> 8) & 0xff);
245 }
246 }
247+ #else
248
249 /*
250+ * Set DM9000 multicast address
251+ */
252+ static void
253+ dm9000_hash_table_unlocked(struct net_device *dev)
254+ {
255+ board_info_t *db = netdev_priv(dev);
256+ struct netdev_hw_addr *ha;
257+ int i, oft;
258+ u32 hash_val;
259+ u16 hash_table[4];
260+ u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN;
261+
262+ //dm9000_dbg(db, 1, "entering %s\n", __func__);
263+
264+ for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
265+ iow(db, oft, dev->dev_addr[i]);
266+
267+ /* Clear Hash Table */
268+ for (i = 0; i < 4; i++)
269+ hash_table[i] = 0x0;
270+
271+ /* broadcast address */
272+ hash_table[3] = 0x8000;
273+
274+ if (dev->flags & IFF_PROMISC)
275+ rcr |= RCR_PRMSC;
276+
277+ if (dev->flags & IFF_ALLMULTI)
278+ rcr |= RCR_ALL;
279+
280+ /* the multicast address in Hash Table : 64 bits */
281+ netdev_for_each_mc_addr(ha, dev) {
282+ hash_val = ether_crc_le(6, ha->addr) & 0x3f;
283+ hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
284+ }
285+
286+ /* Write the hash table to MAC MD table */
287+ for (i = 0, oft = DM9000_MAR; i < 4; i++) {
288+ iow(db, oft++, hash_table[i]);
289+ iow(db, oft++, hash_table[i] >> 8);
290+ }
291+
292+ iow(db, DM9000_RCR, rcr);
293+ }
294+ static void
295+ dm9000_hash_table(struct net_device *dev)
296+ {
297+ board_info_t *db = netdev_priv(dev);
298+ unsigned long flags;
299+
300+ spin_lock_irqsave(&db->lock, flags);
301+ dm9000_hash_table_unlocked(dev);
302+ spin_unlock_irqrestore(&db->lock, flags);
303+ }
304+
305+ #endif
306+ /*
307 Calculate the CRC valude of the Rx packet
308 flag = 1 : return the reverse CRC (for the received packet CRC)
309 0 : return the normal CRC (for Hash Table index)
310 */
311+ #if 0
312 static unsigned long cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
313 {
314 u32 crc = ether_crc_le(Len, Data);
315@@ -1444,16 +1527,16 @@
316
317 return crc;
318 }
319-
320+ #endif
321 static int mdio_read(struct net_device *dev, int phy_id, int location)
322 {
323- board_info_t *db = (board_info_t *)dev->priv;
324+ board_info_t *db = netdev_priv(dev);
325 return phy_read(db, location);
326 }
327
328 static void mdio_write(struct net_device *dev, int phy_id, int location, int val)
329 {
330- board_info_t *db = (board_info_t *)dev->priv;
331+ board_info_t *db = netdev_priv(dev);
332 phy_write(db, location, val);
333 }
334
335@@ -1519,7 +1602,7 @@
336 }
337 static int dmfe_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
338 {
339- board_info_t *db = (board_info_t *)dev->priv;
340+ board_info_t *db = netdev_priv(dev);
341 spin_lock_irq(&db->lock);
342 mii_ethtool_gset(&db->mii, cmd);
343 spin_unlock_irq(&db->lock);
344@@ -1527,7 +1610,7 @@
345 }
346 static int dmfe_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
347 {
348- board_info_t *db = (board_info_t *)dev->priv;
349+ board_info_t *db = netdev_priv(dev);
350 int rc;
351
352 spin_lock_irq(&db->lock);
353@@ -1540,7 +1623,7 @@
354 */
355 static u32 dmfe_get_link(struct net_device *dev)
356 {
357- board_info_t *db = (board_info_t *)dev->priv;
358+ board_info_t *db =netdev_priv(dev);
359 return mii_link_ok(&db->mii);
360 }
361
362@@ -1549,15 +1632,16 @@
363 */
364 static int dmfe_nway_reset(struct net_device *dev)
365 {
366- board_info_t *db = (board_info_t *)dev->priv;
367+ board_info_t *db =netdev_priv(dev);
368 return mii_nway_restart(&db->mii);
369 }
370 /*
371 * Get RX checksum offload state
372 */
373+ #if 0
374 static uint32_t dmfe_get_rx_csum(struct net_device *dev)
375 {
376- board_info_t *db = (board_info_t *)dev->priv;
377+ board_info_t *db = netdev_priv(dev);
378 return db->rx_csum;
379 }
380 /*
381@@ -1573,7 +1657,7 @@
382 static int dmfe_set_rx_csum(struct net_device *dev, uint32_t data)
383 {
384 #ifdef CHECKSUM
385- board_info_t *db = (board_info_t *)dev->priv;
386+ board_info_t *db = netdev_priv(dev);
387 db->rx_csum = data;
388
389 if(netif_running(dev)) {
390@@ -1586,6 +1670,7 @@
391 #endif
392 return 0;
393 }
394+
395 /*
396 * Enable/Disable TX checksum offload
397 */
398@@ -1602,6 +1687,7 @@
399
400 return 0;
401 }
402+ #endif
403 //=========================================
404 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,28) /* for kernel 2.4.28 */
405 static struct ethtool_ops dmfe_ethtool_ops = {
406@@ -1610,10 +1696,10 @@
407 .set_settings = dmfe_set_settings,
408 .get_link = dmfe_get_link,
409 .nway_reset = dmfe_nway_reset,
410- .get_rx_csum = dmfe_get_rx_csum,
411- .set_rx_csum = dmfe_set_rx_csum,
412- .get_tx_csum = dmfe_get_tx_csum,
413- .set_tx_csum = dmfe_set_tx_csum,
414+ //.get_rx_csum = dmfe_get_rx_csum,
415+ //.set_rx_csum = dmfe_set_rx_csum,
416+ //.get_tx_csum = dmfe_get_tx_csum,
417+ //.set_tx_csum = dmfe_set_tx_csum,
418 };
419 #endif
420
421@@ -1680,8 +1766,11 @@
422 * PMC[1:0] : 00-正常模式
423 *
424 */
425- *bankcon4 = (1<<8)|(1<<6); /* 对于DM9000C可以设Tacc为1, 对于DM9000E,Tacc要设大一点,比如最大值7 */
426- iounmap(bwscon);
427+ // *bankcon4 = (1<<8)|(1<<6); /* 对于DM9000C可以设Tacc为1, 对于DM9000E,Tacc要设大一点,比如最大值7 */
428+ *bankcon4 = (7<<8)|(1<<6); // performance not good,use this.
429+
430+
431+ iounmap(bwscon);
432 iounmap(bankcon4);
上面是补丁,可以清楚的看到与之前的区别,报错的地方很多,需要慢慢修改
end
今天解决错误算是解决了一天,有问题总比没问题强,希望加快速度
艾恩凝
写于大连
2021/7/12
吾心信其可行,
则移山填海之难,
终有成功之日!
——孙文
则移山填海之难,
终有成功之日!
——孙文
评论
0 评论