Hi guys. i'm CHO
i'm using icplus 5port 10/100 ethernet intergrated switching chip .
i received this chip's implementation except mii interface that is cpu dependent part.
device driver is implemented like below. as belows, network device is registered and it appeared from console
with the command "ifconfig" . if when i know that how to write mii interface , it will be solved.
i spent three weeks to solve this problem. -.- ;;;
any advice and inform will be appreciated. pls some guide will be very helpful.
my enc is DM816x
thanks.
<code>
#define Write_Reg(phy,reg,val) phy_write(phy,reg,val) //modify this to MII interface
#define Read_Reg(phy,reg) phy_read(phy,reg) //modify this to MII interface
void phy_write(int phyaddr, int regaddr, int value) //modify this to MII interface
{
}
u16 phy_read(int phyaddr, int regaddr) //modify this to MII interface
{
return 0;
}
void write_reg_bits(u16 phyaddr,u16 regaddr,u16 bitnum,u16 bitstart,u16 value)
{
u16 reg_val=Read_Reg(phyaddr,regaddr);
u16 bitmsk=0,i;
for(i=0;i<bitnum;i++){
bitmsk|=(u16)0x1<<(i);
}
reg_val &= ~(bitmsk<<bitstart);
reg_val |= (value&bitmsk)<<bitstart;
Write_Reg(phyaddr,regaddr,reg_val);
}
u16 read_reg_bits(u16 phyaddr,u16 regaddr,u16 bitnum,u16 bitstart)
{
u16 reg_val=Read_Reg(phyaddr,regaddr);
u16 bitmsk=0,i;
for(i=0;i<bitnum;i++){
bitmsk|=(u16)0x1<<(i);
}
return (reg_val>>bitstart)&bitmsk;
}
static int os_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
...
}
static const struct net_device_ops ip_netdev_ops = {
.ndo_do_ioctl = os_do_ioctl,
};
struct net_device * __init linux_probe(void)
{
u8 MACID[6]={0x00,0x00,0x00,0x00,0x17,0x5d};
struct net_device* dev;
u16 register_err;
const struct net_device_ops *netdev_ops;
dev= alloc_etherdev(sizeof(*dev)); //get device name eth0
if(!dev) {
printk("\ndriver allocation fail");
return ERR_PTR(-ENOMEM);
}
pNet_dev=dev;
strcpy(dev->name,DRV_NAME);
dev->netdev_ops = &ip_netdev_ops;
memcpy(dev->dev_addr,MACID,sizeof(MACID));
printk("\nModule load!");
register_err=register_netdev(dev);
if( register_err ) //register netdevice fail
{ printk("\nregister netdev fail");
//release_region(dev->base_addr,2);
free_netdev(dev);
return(ERR_PTR(register_err));
}
return dev;
}
</code>
#if defined(MODVERSIONS)
#include <linux/modversions.h>
#endif
//#include <linux/config.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mii.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/version.h>
#include <asm/dma.h>
//#include "ip175d.h"
#define DRV_NAME "ip175d"
static struct net_device* pNet_dev=NULL;
#define Write_Reg(phy,reg,val) phy_write(phy,reg,val) //modify this to MII interface
#define Read_Reg(phy,reg) phy_read(phy,reg) //modify this to MII interface
void phy_write(int phyaddr, int regaddr, int value) //modify this to MII interface
{
}
u16 phy_read(int phyaddr, int regaddr) //modify this to MII interface
{
return 0;
}
void write_reg_bits(u16 phyaddr,u16 regaddr,u16 bitnum,u16 bitstart,u16 value)
{
u16 reg_val=Read_Reg(phyaddr,regaddr);
u16 bitmsk=0,i;
for(i=0;i<bitnum;i++){
bitmsk|=(u16)0x1<<(i);
}
reg_val &= ~(bitmsk<<bitstart);
reg_val |= (value&bitmsk)<<bitstart;
Write_Reg(phyaddr,regaddr,reg_val);
}
u16 read_reg_bits(u16 phyaddr,u16 regaddr,u16 bitnum,u16 bitstart)
{
u16 reg_val=Read_Reg(phyaddr,regaddr);
u16 bitmsk=0,i;
for(i=0;i<bitnum;i++){
bitmsk|=(u16)0x1<<(i);
}
return (reg_val>>bitstart)&bitmsk;
}
static int os_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
// struct mii_ioctl_data *mii = (struct mii_ioctl_data*)&ifr->ifr_data;
// printk(KERN_ERR "\n IP175d IOCTL called! (%08x)\n",cmd);
switch(cmd)
{
case SIOCSMIIREG: //WriteMDC
{
struct mii_ioctl_data *mii = (struct mii_ioctl_data*)&ifr->ifr_data;
printk(KERN_ERR"Phy:%d Reg:%d D:%04x",mii->phy_id,mii->reg_num,mii->val_in);
Write_Reg(mii->phy_id,mii->reg_num,mii->val_in);
}
return 0;
break;
case SIOCGMIIREG: //ReadMDC
{
struct mii_ioctl_data *mii = (struct mii_ioctl_data*)&ifr->ifr_data;
printk(KERN_ERR"Phy:%d Reg:%d",mii->phy_id,mii->reg_num);
mii->val_out=Read_Reg(mii->phy_id,mii->reg_num);
//printk(KERN_ERR"D:%04x",mii->val_out);
}
return 0;
break;
}
return -EOPNOTSUPP;
}
static const struct net_device_ops ip_netdev_ops = {
.ndo_do_ioctl = os_do_ioctl,
};
struct net_device * __init linux_probe(void)
{
u8 MACID[6]={0x00,0x00,0x00,0x00,0x17,0x5d};
struct net_device* dev;
u16 register_err;
const struct net_device_ops *netdev_ops;
dev= alloc_etherdev(sizeof(*dev)); //get device name eth0
if(!dev) {
printk("\ndriver allocation fail");
return ERR_PTR(-ENOMEM);
}
pNet_dev=dev;
strcpy(dev->name,DRV_NAME);
dev->netdev_ops = &ip_netdev_ops;
memcpy(dev->dev_addr,MACID,sizeof(MACID));
printk("\nModule load!");
register_err=register_netdev(dev);
if( register_err ) //register netdevice fail
{ printk("\nregister netdev fail");
//release_region(dev->base_addr,2);
free_netdev(dev);
return(ERR_PTR(register_err));
}
return dev;
}
int __init init_module(void)
{
linux_probe();
return 0;
}
void __exit cleanup_module(void)
{
printk(KERN_ERR "\nModule");
// printk("\nModule(%s)",pNet_dev->name);
unregister_netdev(pNet_dev);
free_netdev(pNet_dev);
printk(KERN_ERR " removed!\n");
}