?? dm9000.c
字號:
{ return -EBUSY;
} /* Set the device copy of the Ethernet address */
memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
for(i = 0; i < 6; i++)
{
MyMacID[i] = mac_addr->sa_data[i];
}
device_init(dev);
return 0;
}
/*********************************************************************************************************
** Function name: net_tx
** Descriptions: send data to other machine
** Input: skb: save data for send
** dev: information of device
** Output: 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int net_tx(struct sk_buff *skb, struct net_device *dev){ unsigned long flag; int len;
u16 *data;
board_info_t *db = dev->priv;
netif_stop_queue(dev);
len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
data = (u16 *)skb->data; len = (len + 1) & (~1);
local_irq_save(flag);
iow(db, 0xff, 0x80);
outb(0xf8, db->ioaddr);
outsw(db->io_data, data, len >> 1);
iow(db, 0xfc, len & 0xff);
iow(db, 0xfd, (len >> 8) & 0xff);
iow(db, 0x2, 0x1); /* Cleared after TX complete */
/* Re-enable interrupt*/
iow(db, 0xff, 0x83);
dev->trans_start = jiffies;
local_irq_restore(flag);
dev_kfree_skb(skb);
return 0; /* Our simple device can not fail */}/*********************************************************************************************************
** Function name: net_open
** Descriptions: open device
** Input: dev: information of device
**
** Output: 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int net_open(struct net_device *dev){ unsigned long flag; u32 temp;
if (usage == 0)
{
local_irq_save(flag); temp = inl(PINSEL0); PinSel0Save = temp & (0x0f << (8 * 2)); temp |= (3 << (9 * 2)); temp &= ~(3 << (8 * 2)); outl(temp, PINSEL0);
temp = inl(IO0DIR); temp |= 1 << 8; outl(temp, IO0DIR); outl(1 << 8, IOCLR); device_init(dev); temp = inl(VPBDIV); temp = inl(VPBDIV); outl(0, VPBDIV); outl(inl(EXTMODE) & (~(1 << 3)), EXTMODE); outl(inl(EXTPOLAR) | (1 << 3), EXTPOLAR); outl(temp, VPBDIV); local_irq_restore(flag);
request_irq(dev->irq, net_irq_handle, SA_INTERRUPT | SA_SAMPLE_RANDOM, "eth0", dev);
} usage++; MOD_INC_USE_COUNT; netif_start_queue(dev);
return 0; /* success */} /*********************************************************************************************************
** Function name: net_release
** Descriptions: release device
** Input: dev: information of device
**
** Output: 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int net_release(struct net_device *dev) { unsigned long flag; u32 temp; netif_stop_queue(dev); MOD_DEC_USE_COUNT;
MOD_DEC_USE_COUNT; usage--;
if (usage == 0)
{
local_irq_save(flag); temp = inl(PINSEL0); temp &= ~(3 << (9 * 2)); temp |= PinSel0Save;
outl(temp, PINSEL0); local_irq_restore(flag);
free_irq(dev->irq, dev);
} return(0); } /*********************************************************************************************************
** Function name: net_rx
** Descriptions: transact receving data
** Input: dev: information of device
**
** Output: 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static void net_rx(struct net_device *dev, unsigned int length){ struct sk_buff *skb; u8 *dec;
board_info_t *db = dev->priv;
/* * The packet has been retrieved from the transmission * medium. Build an skb around it, so upper layers can handle it */ skb = dev_alloc_skb(length + 2); if (!skb) { return; } skb_reserve(skb, 2); /* align IP on 16B boundary */
skb_put(skb, length); dec = skb->data;
insw(db->io_data, dec, length >> 1);
if ((length & 0x01) != 0)
{
dec[length - 1] = inb(db->io_data);
}
/* Write metadata, and then pass to the receive level */ skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); skb->ip_summed = CHECKSUM_UNNECESSARY;
netif_rx(skb); dev->last_rx = jiffies; return;}/*********************************************************************************************************
** Function name: device_rx
** Descriptions: device receving data
** Input: dev: information of device
**
** Output: 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int device_rx(struct net_device *dev){ unsigned int i, RxStatus, RxLen, GoodPacket, tmplen;
unsigned int rxbyte;
board_info_t *db = dev->priv;
while (1) { ior(db, 0xf0); /* Dummy read *///set the address to 0xf0
rxbyte = inb(db->io_data); /* Got most updated data */
/* Status check: this byte must be 0 or 1 */
if (rxbyte > DM9000_PKT_RDY)
{
return -1;
}
if (rxbyte != DM9000_PKT_RDY)
{
break;
}
/* A packet ready now & Get status/length */
GoodPacket = TRUE;
outb(0xf2, db->ioaddr);//set the address to 0xf2
RxStatus = inw(db->io_data);
RxLen = inw(db->io_data);
/* Packet Status check */
if (RxLen < 60)
{ //Runt Packet
GoodPacket = FALSE;
}
if (RxLen > DM9000_PKT_MAX)
{ //long packet
return -1;
}
if (RxStatus & 0xbf00)
{//status err
GoodPacket = FALSE;
}
/* Move data from DM9000 */
if ( GoodPacket )
{
net_rx(dev, RxLen);
}
else
{
/* Without buffer or error packet */
tmplen = (RxLen + 1) / 2;
for (i = 0; i < tmplen; i++)
{
inw(db->io_data);
}
}
} return 0;}
/*********************************************************************************************************
** Function name: net_tasklet
** Descriptions: The tasklet for interrupt handler
** Input:
** Output none
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static void net_tasklet(unsigned long data)
{
struct net_device *dev;
dev = (struct net_device *)data;
device_init(dev);
}
/*********************************************************************************************************
** Function name: net_irq_handle
** Descriptions: The top-half interrupt handler
** Input:
** Output none
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static void net_irq_handle(int irq, void *dev_id, struct pt_regs *regs){ unsigned int int_status;
struct net_device *dev; board_info_t *db;
dev = (struct net_device *)dev_id;
db = dev->priv;
int_status = ior(db, 0xfe); /* Got ISR */
iow(db, 0xfe, int_status); /* Clear ISR status */
outl(1 << (dev->irq - 14), EXTINT);
if (int_status & DM9000_TX_INTR) //表示發送成功,判斷發送狀態寄存器TSR,決定是否出錯
{
netif_start_queue(dev);
}
if (int_status & DM9000_RX_INTR) /* 接收成功 */
{
if (device_rx(dev) == -1)
{
DM9000Dev = dev;
tasklet_schedule (&ZLG_net_tasklet);
}
}
}
/*********************************************************************************************************
** Function name: net_init_module
** Descriptions: init driver
** Input: none
**
** Output: 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int net_init_module(void){ int result; result = register_netdev(&net_net); if (result < 0) { printk(KERN_ERR "eth0: error %i registering device \"%s\"\n", result, net_net.name); return(result); } printk(KERN_ERR "eth0: init OK\n"); return(0); }/*********************************************************************************************************
** Function name: net_cleanup
** Descriptions: exit driver
** Input: none
**
** Output: 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void net_cleanup(void){ unregister_netdev(&net_net);}/*********************************************************************************************************** End Of File********************************************************************************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -