[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);

上面是补丁,可以清楚的看到与之前的区别,报错的地方很多,需要慢慢修改

driver2.png

end

今天解决错误算是解决了一天,有问题总比没问题强,希望加快速度

艾恩凝

写于大连

2021/7/12


    


公众号'艾恩凝'
个人公众号
个人微信
个人微信
    吾心信其可行,
          则移山填海之难,
                  终有成功之日!
                                  ——孙文
    评论
    0 评论
avatar

取消