最近做了一个TF卡烧写MAC地址,方法额外增加一个驱动,驱动中实现对TF卡和本地mac文件的读写功能,让以太网驱动加载时调用读写函数进行设置mac地址,代码比较简单,如下:
/*
* setmac one chip USB 2.0 ethernet devices
*
* Author : yubo.wang
* Date : 2017-08-25
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "setmac.h"
#define SET_MAC_FILE "/system/etc/mac"
#define SET_MAC_MOUNT "/system/etc/tf_mac/mac"
int setmac_read_tf_mac(u8 *mac_addr)
{
u8 mac_buf[12] = {0,};
int i = 0;
struct file *fp;
mm_segment_t fs;
loff_t pos;
fp = filp_open(SET_MAC_MOUNT, O_RDONLY, 0);
if (IS_ERR(fp))
{
printk(KERN_ERR "read tf mac addr file error,return!\n");
return -1;
}
fs = get_fs();
set_fs(KERNEL_DS);
pos = 0;
vfs_read(fp, mac_buf, sizeof(mac_buf), &pos);
if(strlen(mac_buf) < 12)
{
printk(KERN_ERR "read tf mac addr len < 12,return!\n");
return -1;
}
mac_buf[12] = '\0';
printk(KERN_INFO "read tf mac:%s",mac_buf);
for (i=0; i<6; i++){
u8 mac_tmp[3]= {0,};
memcpy(mac_tmp, (char *)(mac_buf+i*2), 2);
mac_addr[i] = simple_strtoul(mac_tmp, NULL, 16);
}
filp_close(fp, NULL);
set_fs(fs);
return 0;
}
EXPORT_SYMBOL_GPL(setmac_read_tf_mac);
int setmac_write_tf_mac(u8 *mac_addr)
{
u8 mac_buf[12] = {0,};
int i = 0;
struct file *fp;
mm_segment_t fs;
loff_t pos;
fp = filp_open(SET_MAC_FILE, O_RDWR | O_CREAT, 0644);
if (IS_ERR(fp))
{
printk(KERN_ERR "write tf mac addr file error,return!\n");
return -1;
}
fs = get_fs();
set_fs(KERNEL_DS);
for (i=0; i<6; i++){
u8 mac_tmp[3]= {0,};
sprintf(mac_tmp, "%02x", mac_addr[i]);
strncat(mac_buf, mac_tmp, 2);
}
mac_buf[12] = '\0';
printk(KERN_INFO "write mac:%s",mac_buf);
pos = 0;
vfs_write(fp, mac_buf, sizeof(mac_buf), &pos);
vfs_fsync(fp, 0);
filp_close(fp, NULL);
set_fs(fs);
return 0;
}
EXPORT_SYMBOL_GPL(setmac_write_tf_mac);
int setmac_read_mac_addr(u8 *mac_addr)
{
u8 mac_buf[12] = {0,};
int i = 0;
struct file *fp;
mm_segment_t fs;
loff_t pos;
fp = filp_open(SET_MAC_FILE, O_RDONLY, 0);
if (IS_ERR(fp))
{
printk(KERN_ERR "read mac addr file error,return!\n");
return -1;
}
fs = get_fs();
set_fs(KERNEL_DS);
pos = 0;
vfs_read(fp, mac_buf, sizeof(mac_buf), &pos);
if(strlen(mac_buf) < 12)
{
printk(KERN_ERR "read mac addr len < 12,return!\n");
return -1;
}
mac_buf[12] = '\0';
printk(KERN_INFO "read mac:%s",mac_buf);
for (i=0; i<6; i++){
u8 mac_tmp[3]= {0,};
memcpy(mac_tmp, (char *)(mac_buf+i*2), 2);
mac_addr[i] = simple_strtoul(mac_tmp, NULL, 16);
}
filp_close(fp, NULL);
set_fs(fs);
return 0;
}
EXPORT_SYMBOL_GPL(setmac_read_mac_addr);
int setmac_write_mac_addr(u8 *mac_addr)
{
u8 mac_buf[12] = {0,};
int i = 0;
struct file *fp;
mm_segment_t fs;
loff_t pos;
fp = filp_open(SET_MAC_FILE, O_RDWR | O_CREAT, 0644);
if (IS_ERR(fp))
{
printk(KERN_ERR "write mac addr file error,return!\n");
return -1;
}
fs = get_fs();
set_fs(KERNEL_DS);
for (i=0; i<6; i++){
u8 mac_tmp[3]= {0,};
sprintf(mac_tmp, "%02x", mac_addr[i]);
strncat(mac_buf, mac_tmp, 2);
}
mac_buf[12] = '\0';
printk(KERN_INFO "write mac:%s",mac_buf);
pos = 0;
vfs_write(fp, mac_buf, sizeof(mac_buf), &pos);
vfs_fsync(fp, 0);
filp_close(fp, NULL);
set_fs(fs);
return 0;
}
EXPORT_SYMBOL_GPL(setmac_write_mac_addr);
MODULE_AUTHOR("yubo.wang ");
MODULE_DESCRIPTION("SETMAC one chip USB 2.0 ethernet devices");
MODULE_LICENSE("GPL");
预留问题:
1、量产多个mac地址递增还未实现,发现ops文件指针偏移不准导致读数据异常
2、没有对mac地址有效性检查,只检查了位数,且单播多播和OUI也没有检查