linux-3.4.2 smsc911x 网卡移植

这个网卡驱动参考qt210 2.6.35内核移植过来,主要修改了网卡设备。

1. make menuconfig配置驱动

内核3.4.2内核版本已经支持smsc系列的网卡驱动,选择这一项


编译测试,发现网卡已经能够执行到probe,但是仍然错误。

定位在
if (!request_mem_region(res->start, res_size, SMSC_CHIPNAME)) {
retval = -EBUSY;
goto out_0;
}

返回的错误是16:

#define EBUSY16 /* Device or resource busy */

发现申请这块内存空间的时候总是失败。

因为QT210使用的SROM bank5, 地址是0xa8000000.

在mach-smdkv210.c发现dm9000使用的也是bank5,并且已经注册了。

static struct resource smdkv210_dm9000_resources[] = {
	[0] = {
		.start	= S5PV210_PA_SROM_BANK5,
		.end	= S5PV210_PA_SROM_BANK5,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= S5PV210_PA_SROM_BANK5 + 2,
		.end	= S5PV210_PA_SROM_BANK5 + 2,
		.flags	= IORESOURCE_MEM,
	},
	[2] = {
		.start	= IRQ_EINT(9),
		.end	= IRQ_EINT(9),
		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
	},
};

怪不得申请内存错误。


2. 注掉dm9000的设备资源,添加smsc911的设备资源

#ifdef CONFIG_SMSC911X

static struct smsc911x_platform_config smsc911x_config = {
    .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
    .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
    .flags          = SMSC911X_USE_32BIT,
    .phy_interface  = PHY_INTERFACE_MODE_MII,
    .dev_addr = {0x00,0x09,0xc0,0xff,0xec,0x48},
};

static struct resource smsc911x_resources[] = {
	[0] = {
		.start = S5PV210_PA_SMSC9220,
		.end   = S5PV210_PA_SMSC9220 + 0xFF,
		.flags = IORESOURCE_MEM,
	},
	[1] = {
		.start = IRQ_EINT9,
		.end   = IRQ_EINT9,
		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
	}
};

struct platform_device device_smsc911x = {
	.name		= "smsc911x",
	.id			=  0,
	.num_resources	= ARRAY_SIZE(smsc911x_resources),
	.resource	= smsc911x_resources,
	.dev		= {
		.platform_data = &smsc911x_config,
	}
};
static int __init ethaddr_setup(char *line)
{
        char *ep;
        int i;

        /* there should really be routines to do this stuff */
        for (i = 0; i < 6; i++) {
                smsc911x_config.dev_addr[i] = line ? simple_strtoul(line, &ep, 16) : 0;
                if (line)
                        line = (*ep) ? ep+1 : ep;
        }
        printk("crzteh ddddd User MAC address: %pM\n", smsc911x_config.dev_addr);
        return 0;
}
__setup("ethaddr=", ethaddr_setup);

static void __init smsc911x_set(void)
{
	unsigned int tmp;
	tmp = ((0<<28)|(4<<24)|(13<<16)|(1<<12)|(4<<8)|(6<<4)|(0<<0));
	__raw_writel(tmp, (S5P_SROM_BW + 0x18));

	tmp = __raw_readl(S5P_SROM_BW);
	tmp &= ~(0xf << 20);
	tmp |= (0x3 << 20);
    
	__raw_writel(tmp, S5P_SROM_BW);

	tmp = __raw_readl(S5PV210_MP01_BASE);
	tmp &= ~(0xf << 20);
	tmp |= (2 << 20);
	__raw_writel(tmp, S5PV210_MP01_BASE);
}
#else
static void __init smsc911x_set(void) {}
#endif


static struct platform_device *smdkv210_devices[] __initdata = {
	&s3c_device_adc,
	&s3c_device_cfcon,
	&s3c_device_fb,
	&s3c_device_hsmmc0,
	&s3c_device_hsmmc1,
	&s3c_device_hsmmc2,
	&s3c_device_hsmmc3,
	&s3c_device_i2c0,
	&s3c_device_i2c1,
	&s3c_device_i2c2,
	&s3c_device_rtc,
	&s3c_device_ts,
	&s3c_device_wdt,

#ifdef CONFIG_SMSC911X
	&device_smsc911x,
#endif
#ifdef CONFIG_MTD_NAND
	&s3c_device_nand,
#endif
	
	&s5p_device_fimc0,
	&s5p_device_fimc1,
	&s5p_device_fimc2,
	&s5p_device_fimc_md,
	&s5p_device_jpeg,
	&s5p_device_mfc,
	&s5p_device_mfc_l,
	&s5p_device_mfc_r,
	&s5pv210_device_ac97,
	&s5pv210_device_iis0,
	&s5pv210_device_spdif,
	&samsung_asoc_dma,
	&samsung_asoc_idma,
	&samsung_device_keypad,
//	&smdkv210_dm9000,
	&smdkv210_lcd_lte480wv,
};
#if 0
static void __init smdkv210_dm9000_init(void)
{
	unsigned int tmp;

	gpio_request(S5PV210_MP01(5), "nCS5");
	s3c_gpio_cfgpin(S5PV210_MP01(5), S3C_GPIO_SFN(2));
	gpio_free(S5PV210_MP01(5));

	tmp = (5 << S5P_SROM_BCX__TACC__SHIFT);
	__raw_writel(tmp, S5P_SROM_BC5);

	tmp = __raw_readl(S5P_SROM_BW);
	tmp &= (S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS5__SHIFT);
	tmp |= (1 << S5P_SROM_BW__NCS5__SHIFT);
	__raw_writel(tmp, S5P_SROM_BW);
}
#endif
static struct i2c_board_info smdkv210_i2c_devs0[] __initdata = {
	{ I2C_BOARD_INFO("24c08", 0x50), },     /* Samsung S524AD0XD1 */
	{ I2C_BOARD_INFO("wm8580", 0x1b), },
};

static struct i2c_board_info smdkv210_i2c_devs1[] __initdata = {
	/* To Be Updated */
};

static struct i2c_board_info smdkv210_i2c_devs2[] __initdata = {
	/* To Be Updated */
};

/* LCD Backlight data */
static struct samsung_bl_gpio_info smdkv210_bl_gpio_info = {
	.no = S5PV210_GPD0(3),
	.func = S3C_GPIO_SFN(2),
};

static struct platform_pwm_backlight_data smdkv210_bl_data = {
	.pwm_id = 3,
	.pwm_period_ns = 1000,
};

static void __init smdkv210_map_io(void)
{
	s5pv210_init_io(NULL, 0);
	s3c24xx_init_clocks(24000000);
	s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
}

static void __init smdkv210_reserve(void)
{
	s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
}

static void __init smdkv210_machine_init(void)
{
	s3c_pm_init();
#if 0
	smdkv210_dm9000_init();
#endif
	samsung_keypad_set_platdata(&smdkv210_keypad_data);
	s3c24xx_ts_set_platdata(NULL);

	s3c_i2c0_set_platdata(NULL);
	s3c_i2c1_set_platdata(NULL);
	s3c_i2c2_set_platdata(NULL);
	i2c_register_board_info(0, smdkv210_i2c_devs0,
			ARRAY_SIZE(smdkv210_i2c_devs0));
	i2c_register_board_info(1, smdkv210_i2c_devs1,
			ARRAY_SIZE(smdkv210_i2c_devs1));
	i2c_register_board_info(2, smdkv210_i2c_devs2,
			ARRAY_SIZE(smdkv210_i2c_devs2));

	s3c_ide_set_platdata(&smdkv210_ide_pdata);

	s3c_fb_set_platdata(&smdkv210_lcd0_pdata);

	samsung_bl_set(&smdkv210_bl_gpio_info, &smdkv210_bl_data);

	platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));

#ifdef CONFIG_SMSC911X
	smsc911x_set();
#endif

	
}


暂时注掉dm9000,虽然这样做不规范,但是为了调试,先这么做了,以后再改。

3. 修改smsc用到的寄存器

regs-srom.h

/* linux/arch/arm/plat-samsung/include/plat/regs-srom.h
 *
 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * S5P SROMC register definitions
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
*/

#ifndef __PLAT_SAMSUNG_REGS_SROM_H
#define __PLAT_SAMSUNG_REGS_SROM_H __FILE__

#include <mach/map.h>

#define S5P_SROMREG(x)		(S5P_VA_SROMC + (x))

#define S5P_SROM_BW		S5P_SROMREG(0x0)
#define S5P_SROM_BC0		S5P_SROMREG(0x4)
#define S5P_SROM_BC1		S5P_SROMREG(0x8)
#define S5P_SROM_BC2		S5P_SROMREG(0xc)
#define S5P_SROM_BC3		S5P_SROMREG(0x10)
#define S5P_SROM_BC4		S5P_SROMREG(0x14)
#define S5P_SROM_BC5		S5P_SROMREG(0x18)

/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */

#define S5P_SROM_BW__DATAWIDTH__SHIFT		0
#define S5P_SROM_BW__ADDRMODE__SHIFT		1
#define S5P_SROM_BW__WAITENABLE__SHIFT		2
#define S5P_SROM_BW__BYTEENABLE__SHIFT		3

#define S5P_SROM_BW__CS_MASK			0xf

#define S5P_SROM_BW__NCS0__SHIFT		0
#define S5P_SROM_BW__NCS1__SHIFT		4
#define S5P_SROM_BW__NCS2__SHIFT		8
#define S5P_SROM_BW__NCS3__SHIFT		12
#define S5P_SROM_BW__NCS4__SHIFT		16
#define S5P_SROM_BW__NCS5__SHIFT		20

/* applies to same to BCS0 - BCS3 */

#define S5P_SROM_BCX__PMC__SHIFT		0
#define S5P_SROM_BCX__TACP__SHIFT		4
#define S5P_SROM_BCX__TCAH__SHIFT		8
#define S5P_SROM_BCX__TCOH__SHIFT		12
#define S5P_SROM_BCX__TACC__SHIFT		16
#define S5P_SROM_BCX__TCOS__SHIFT		24
#define S5P_SROM_BCX__TACS__SHIFT		28

#endif /* __PLAT_SAMSUNG_REGS_SROM_H */

regs-gpio.h

/* linux/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
 *
 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * S5PV210 - GPIO (including EINT) register definitions
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
*/

#ifndef __ASM_ARCH_REGS_GPIO_H
#define __ASM_ARCH_REGS_GPIO_H __FILE__

#include <mach/map.h>

#define S5PV210_EINT30CON		(S5P_VA_GPIO + 0xE00)
#define S5P_EINT_CON(x)			(S5PV210_EINT30CON + ((x) * 0x4))

#define S5PV210_EINT30FLTCON0		(S5P_VA_GPIO + 0xE80)
#define S5P_EINT_FLTCON(x)		(S5PV210_EINT30FLTCON0 + ((x) * 0x4))

#define S5PV210_EINT30MASK		(S5P_VA_GPIO + 0xF00)
#define S5P_EINT_MASK(x)		(S5PV210_EINT30MASK + ((x) * 0x4))

#define S5PV210_EINT30PEND		(S5P_VA_GPIO + 0xF40)
#define S5P_EINT_PEND(x)		(S5PV210_EINT30PEND + ((x) * 0x4))

#define EINT_REG_NR(x)			(EINT_OFFSET(x) >> 3)

#define eint_irq_to_bit(irq)		(1 << (EINT_OFFSET(irq) & 0x7))

#define EINT_MODE		S3C_GPIO_SFN(0xf)

#define EINT_GPIO_0(x)		S5PV210_GPH0(x)
#define EINT_GPIO_1(x)		S5PV210_GPH1(x)
#define EINT_GPIO_2(x)		S5PV210_GPH2(x)
#define EINT_GPIO_3(x)		S5PV210_GPH3(x)

#define S5PV210_MP01_BASE		(S5P_VA_GPIO + 0x2E0)

#define S5PV210_GPH0_BASE		(S5P_VA_GPIO + 0xC00)
#define S5PV210_GPH1_BASE		(S5P_VA_GPIO + 0xC20)
#define S5PV210_GPH2_BASE		(S5P_VA_GPIO + 0xC40)
#define S5PV210_GPH3_BASE		(S5P_VA_GPIO + 0xC60)

#endif /* __ASM_ARCH_REGS_GPIO_H */


4. 最后输出log,显示成功,可以挂在nfs了

smsc911x: Driver version 2008-10-21
smsc911x-mdio: probed
smsc911x smsc911x.0: eth0: attached PHY driver [Generic PHY] (mii_bus:phy_addr=smsc911x-0:01, irq=-1)
smsc911x smsc911x.0: eth0: MAC Address: 52:34:5e:da:09:0f




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值