网卡从24c02获取设置mac地址

#include <linux/kernel.h>
#include <linux/types.h>

#include <linux/i2c.h>

unsigned char mac_read(unsigned char command)
{
	int ret;
	unsigned char buf;
	struct i2c_adapter *a = i2c_get_adapter(1);
	struct i2c_msg msg[2] = 
	{
		{ 
		.addr = 0x50, .flags = 0, .buf = &command, .len = 1
		},
		
		{
		.addr = 0x50, .flags = I2C_M_RD, .buf = &buf, 	.len = 1
		}
	};
	
	ret = i2c_transfer(a, msg, 2);
	if (ret < 0) {
		printk("[mac_write] i2c_transfer error\n");
	}

	return buf;
}
EXPORT_SYMBOL(mac_read);

int mac_write(unsigned char reg, unsigned char data)
{
	int ret;
	unsigned char buf [] = { reg, data };
	struct i2c_adapter *a = i2c_get_adapter(1);
	struct i2c_msg msg[1] = 
	{
		{ 
			.addr = 0x50, .flags = 0, .buf = buf, .len = 2 
		}
	};

	ret = i2c_transfer(a, msg, 1);
	if (ret < 0) {
		printk("[mac_write] i2c_transfer error\n");
	}

	return ret;
}
EXPORT_SYMBOL(mac_write);

写这个程序之前我在思考是网卡先驱动获取mac先呢,还是i2c子系统的i2c适配器先初始化好呢?

加了些打印语句判断之后,证明我的板子是i2c子系统的i2c适配器先初始化好,于是可以堂而皇之的用i2c接口的api

如果不是就得用__raw_writew,__raw_readw这些底层寄存器操作函数,像单片机一样来读取mac地址,

不然网卡获取不到固定mac,ip在dhcp获取中就会变动,

写入不着急可以等到i2c子系统初始化好再说

 

先修改makefile添加该c文件的依赖,让它编译进内核

(这里我调试板子使用nfs的,内核存放于sd卡中,正常逻辑我每次改内核就得把sd拿出来拷贝一次,相当的麻烦

我把sd卡挂载在/media/card中,内核编译后uImage自动复制一份到nfs目录中,超级终端中利用cp命令将unfs目录中的Image复制到挂载的/media/card目录下,替换掉旧的uImage)


在网卡驱动中添加声明

extern unsigned char mac_read(unsigned char command);
extern int mac_write(unsigned char reg, unsigned char data);

在网卡平台设备的probe中这样引用

for (i = 0; i < 6; i++)

    pdata->mac_addr[i] = mac_read(i+offset);   //读方法的调用

printk("eth%s MAC addr:",(offset==1)?"0":"1");
 printk("%pM\n", pdata->mac_addr);

双网卡的所以有个不同的offset偏移量,表示mac地址在24c02的偏移位置

 

下面有代码

 if (!is_valid_ether_addr(priv->mac_addr)) {    //判断mac地址是否存在,就是24c02是否写入了合适的mac地址了
  /* Use random MAC if none passed */
  random_ether_addr(priv->mac_addr);    //没有的话会产生随机的mac地址
  printk(KERN_WARNING "%s: using random MAC addr: %pM\n",
    __func__, priv->mac_addr);
  for (i = 0; i < 6; i++){

   mac_write(offset+i,priv->mac_addr[i]);   //那么就将随机分配的mac地址写入24c02中,省点事去往24c02烧mac地址
   msleep(1);  //加个延时 写太快 有时候会写失败
  }
 }

读方法会打印出来结果

写方法用i2c工具在应用层查看写入是否与自己期望值一样

移植i2c-tools

1.官方网站下载http://www.lm-sensors.org/wiki/I2CTools
i2c-tools-3.1.0.tar.bz2

2.解压
tar -xvf i2c-tools-3.1.0.tar.bz2
3.修改makefile
CC =gcc -> CC = arm-none-linux-gnueabi-gcc

4.make编译

5.将tools目录下i2cdetect、i2cdump、i2cget、i2cset拷贝到目标板文件系统/bin目录下

i2c工具介绍

i2cdetect – 用來列舉I2C bus和上面所有的裝置 
i2cdump – 顯示裝置上所有register的值 
i2cget – 讀取裝置上某個register的值 
i2cset – 寫入裝置上某個register 

加上-V参数可以查看工具的版本信息

用户:  i2cdetect [-y] [-a] [-q|-r] I2CBUS [FIRST LAST]
       i2cdetect -F I2CBUS
       i2cdetect -l
  I2CBUS是一个整数或提供的i2c总线名
  FIRST和LAST是限定的探测范围

先检测适配器

# i2cdetect -l
i2c-1   i2c             OMAP I2C adapter                        I2C adapter
i2c-2   i2c             OMAP I2C adapter                        I2C adapter

检测适配器功能

# i2cdetect -F 1
Functionalities implemented by /dev/i2c-1:
I2C                              yes
SMBus Quick Command              no    //不支持quick command -q参数就不能用
SMBus Send Byte                  yes
SMBus Receive Byte               yes
SMBus Write Byte                 yes
SMBus Read Byte                  yes
SMBus Write Word                 yes
SMBus Read Word                  yes
SMBus Process Call               yes
SMBus Block Write                yes
SMBus Block Read                 no
SMBus Block Process Call         no
SMBus PEC                        yes
I2C Block Write                  yes
I2C Block Read                   yes

扫描有哪些i2c设备

# i2cdetect -r 1
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-1 using read byte commands.
I will probe address range 0x03-0x77.
Continue? [Y/n] 

会询问按回车

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: 50 51 52 53 54 55 56 57 -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --   

如果嫌确认麻烦可以加上-y选项,该选项表示不用用户确认默认确定
0x50是我的24c02

用法: i2cdump [-f] [-y] [-r first-last] I2CBUS ADDRESS [MODE [BANK [BANKREG]]]
  I2CBUS是一个整数或提供的i2c总线名
  ADDRESS是一个整数(0x03 - 0x77)
  MODE是一下之一:
    b (字节, 默认)
    w (字)
    W (word on even register addresses)
    s (SMBus 块)
    i (I2C 块)
    c (连续字节)
    Append p for SMBus PEC

接着用i2cdump查看某设备的所有寄存器的数据

# i2cdump -y 1 0x50 b
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 00 72 f9 96 0d 75 ea 00 7f 92 b9 ea d4 12 fd 01    .r???u?.????????
10: 33 12 01 04 08 a0 5a 78 0a 01 c1 a0 57 47 98 27    3?????Zx????WG?'
20: 12 4c 4c a1 08 00 31 40 45 40 61 40 81 80 a9 40    ?LL??.1@E@a@???@
30: 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c    ???????:??q8-@X,
40: 46 00 40 84 63 00 00 1e 66 21 50 b0 51 00 1b 30    F.@?c..?f!P?Q.?0
50: 40 70 36 00 40 84 63 00 00 1e 00 00 00 fd 00 39    @p6.@?c..?...?.9
60: 3f 1e 50 0f 00 0a 20 20 20 20 20 20 00 00 00 fc    ??P?.?      ...?
70: 00 4c 43 44 54 56 31 34 0a 20 20 20 20 20 00 c2    .LCDTV14?     .?
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................

i2c获取和设置的工具

用法: i2cget [-f] [-y] I2CBUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]
  I2CBUS是一个整数或提供的i2c总线名
  ADDRESS是一个整数(0x03 - 0x77)
  MODE是一下之一:
    b (读字节数据,默认)
    w (读字数据)
    c (写字节/读字节)
    Append p for SMBus PEC
用法: i2cset [-f] [-y] [-m MASK] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] [MODE]
  I2CBUS是一个整数或提供的i2c总线名
  ADDRESS是一个整数(0x03 - 0x77)
  MODE是一下之一:
    c (字节,无值)
    b (字节数据,默认)
    w (字数据)
    Append p for SMBus PEC

获取寄存器数据

# i2cget -y 1 0x50 0x10
0x33

设置寄存器数据

# i2cset -y 1 0x50 0x10 0xAB

再次获取

# i2cget -y 1 0x50 0x10
0xab

值已经变了








你可能感兴趣的:(linux,mac,网卡,i2c,24c02)