📄 dm9008_8bit_mode.c
字号:
db->stats.tx_bytes+=skb->len;
netif_stop_queue(dev);
/* Disable all interrupt */
iow(db, 0xff, DM9KS_DISINTR);
/* Move data to TX SRAM */
data_ptr = (DATA_TYPE *)skb->data;
dmfe_outb(0xf8, db->io_addr); // Write data into SRAM trigger
db->sent_pkt_len = skb->len;
// tmplen = (skb->len + IO_MODE - 1) / IO_MODE;
tmplen = skb->len ;
for (i = 0; i < tmplen; i++)
dmfe_outb(((DATA_TYPE *)data_ptr)[i], db->io_data);
/* TX control: First packet immediately send, second packet queue*/
if (db->tx_pkt_cnt < 2)
{
/* First packet */
db->tx_pkt_cnt++;
/* Set TX length to reg. 0xfc & 0xfd */
iow(db, 0xfc, (skb->len & 0xff));
iow(db, 0xfd, (skb->len >> 8) & 0xff);
/* Issue TX polling command */
iow(db, DM9KS_TCR, 0x1); /* Cleared after TX complete*/
/* Saved the time stamp */
dev->trans_start = jiffies;
}
/* Free this SKB */
dev_kfree_skb(skb);
/* Re-enable resource check */
if (db->tx_pkt_cnt < 2)
netif_wake_queue(dev);
/* Re-enable interrupt */
iow(db, DM9KS_IMR, DM9KS_REGFF);
return 0;
}
/* Set PHY operationg mode
*/
static void set_PHY_mode(board_info_t *db)
{
// printk("set_PHY-mode \n");
u16 phy_reg0 = 0x1200; /* Auto-negotiation & duplux disable */
u16 phy_reg4 = 0x01e1; /* Default flow control disable*/
// Set by dd ,we choose 10M base Full speed
// if ( !(db->op_mode & DM9KS_AUTO) ) // op_mode didn't auto sense */
// {
// switch(db->op_mode) {
// case DM9KS_10MHD: phy_reg4 = 0x21;
// phy_reg0 = 0x1000;
// break;
// case DM9KS_10MFD:
phy_reg4 = 0x41;
phy_reg0 = 0x1100;
// break;
// case DM9KS_100MHD: phy_reg4 = 0x81;
// phy_reg0 = 0x3000;
// break;
// case DM9KS_100MFD: phy_reg4 = 0x101;
// phy_reg0 = 0x3100;
// break;
// default:
// break;
// } // end of switch
// } // end of if
phy_write(db, 0, phy_reg0);
phy_write(db, 4, phy_reg4);
}
/*
Initilize dm9000 board
*/
static void dmfe_init_dm9000(struct net_device *dev)
{
unsigned char isr;//imr;
// printk("dmfe_init_dm9000 \n");
board_info_t *db = (board_info_t *)dev->priv;
DMFE_DBUG(0, "dmfe_init_dm9000()", 0);
//add by dd
isr=ior(db,0xfe);
//imr=ior(db,0xff);
// printk("ISR=%x \n",ISR);
// printk("SCU_FLAG=%x \n",SCU_FLAG);
// printk("isr=%x \n",isr);
/* set the internal PHY power-on, GPIOs normal, and wait 2ms */
//add by dd ,06.08.12
iow(db, 0x1F, 1);
udelay(500);
//
iow(db, 0x1F, 0); /* GPR (reg_1Fh)bit GPIO0=0 pre-activate PHY */
udelay(20); /* wait 2ms for PHY power-on ready */
/* do a software reset and wait 20us */
iow(db, DM9KS_NCR, 3);
udelay(20); /* wait 20us at least for software reset ok */
iow(db, DM9KS_NCR, 3); /* NCR (reg_00h) bit[0] RST=1 & Loopback=1, reset on. Added by SPenser */
udelay(20); /* wait 20us at least for software reset ok */
/* I/O mode */
db->io_mode = ior(db, DM9KS_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */
// printk("io_mode=%d \n",db->io_mode);
/* Set PHY */
db->op_mode = 4;
set_PHY_mode(db);
/* Program operating register */
iow(db, DM9KS_NCR, 0);
iow(db, DM9KS_TCR, 0); /* TX Polling clear */
iow(db, 0x08, 0x3f); /* Less 3kb, 600us */
iow(db, 0x2f, 0); /* Special Mode */
iow(db, DM9KS_NSR, 0x2c); /* clear TX status */
iow(db, DM9KS_ISR, 0x0f); /* Clear interrupt status */
//#if defined(CHECKSUM)
// iow(db, DM9KS_ETCR, 0); /* Early transmit disable */
// iow(db, DM9KS_TCCR, 0x07); /* TX UDP/TCP/IP checksum enable */
// iow(db, DM9KS_RCSR, 0x03); /*Receive checksum enable & discard checksum error packet */
//#endif
/* Set address filter table */
dm9000_hash_table(dev);
/* Activate DM9000A/DM9010 */
iow(db, DM9KS_RXCR, DM9KS_REG05 | 1); /* RX enable */
//modi by dd ,06.08.16
iow(db, DM9KS_IMR, DM9KS_REGFF); // Enable TX/RX interrupt mask
/* Init Driver variable */
db->link_failed = 1;
db->tx_pkt_cnt = 0;
db->queue_pkt_len = 0;
dev->trans_start = 0;
db->flowcontrol_p = 1;
netif_carrier_on(dev);
spin_lock_init(&db->lock);
}
/*
Reset dm9000 board due to 32bits mode while excess collision or late collision.
*/
static void dmfe_reset_dm9000(struct net_device *dev)
{
board_info_t *db = (board_info_t *)dev->priv;
DMFE_DBUG(0, "dmfe_reset_dm9000()", 0);
iow(db, 0, 1); /* NCR (reg_00h) bit[0] RST=1, reset on. Added by SPenser */
udelay(1); /* wait 20us at least for software reset ok */
iow(db, 0, 0);
/* software reset 2 times */
iow(db, DM9KS_NCR, 3);
udelay(20);
iow(db, DM9KS_NCR, 3);
udelay(20);
/* Program operating register */
iow(db, DM9KS_NCR, 0);
iow(db, DM9KS_TCR, 0); /* TX Polling clear */
iow(db, 0x08, 0x3f); /* Less 3Kb, 600us */
iow(db, 0x2f, 0); /* Special Mode */
iow(db, DM9KS_NSR, 0x2c); /* clear TX status */
iow(db, DM9KS_ISR, 0x0f); /* Clear interrupt status */
/* Activate DM9000A/DM9010 */
iow(db, DM9KS_RXCR, DM9KS_REG05 | 1); /* RX enable */
iow(db, DM9KS_IMR, DM9KS_REGFF); // Enable TX/RX interrupt mask
/* Init Driver variable */
db->link_failed = 1;
db->tx_pkt_cnt = 0;
db->queue_pkt_len = 0;
dev->trans_start = 0;
netif_carrier_on(dev);
}
/*
Hardware start transmission.
Send a packet to media from the upper layer.
*/
//if(0)
//static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev)
//{
//
// board_info_t *db = (board_info_t *)dev->priv;
//// DATA_TYPE * data_ptr;
// u8 * data_ptr;
// int i;
//// int tmplen;
//// printk("db_tx_pkt_cnt1=%d",db->tx_pkt_cnt);
// DMFE_DBUG(0, "dmfe_start_xmit", 0);
// // modi by dd ,06.08.12
//// db->speed=10;
//// if(db->speed==10)
//
//// {
// if (db->tx_pkt_cnt >= 2) return 1;
//// }
//
//// else
//// {if (db->tx_pkt_cnt >= 2) return 1;}
//
// //add by dd,06.08.12
//// db->tx_pkt_cnt++;
//
////
// db->stats.tx_packets++;
// db->stats.tx_bytes+=skb->len;
//
// //modi by dd 06.08.17
//// if(db->speed==10)
//// {
//// if (db->tx_pkt_cnt >=1) netif_stop_queue(dev);
//// }
//// else
//// {
//// if (db->tx_pkt_cnt >=2)
// netif_stop_queue(dev);
//// }
//
//// netif_stop_queue(dev);
//
// /* Disable all interrupt */
// iow(db, 0xff, DM9KS_DISINTR);
//
// /*set TX length to reg.0xfc & 0xfd */
// //add by dd .06.08.12
//// iow(db,0xfc,(skb->len & 0xff));
//// iow(db,0xfd,(skb->len >>8) & 0xff);
// //
// /* Move data to TX SRAM */
// //modi by dd ,06.08.12
//// data_ptr = (DATA_TYPE *)skb->data;
// data_ptr = (u8 *)skb->data;
//
////
// dmfe_outb(0xf8, db->io_addr); // Write data into SRAM trigger
//
//// modi by dd
// db->sent_pkt_len = skb->len;
//
//// tmplen = (skb->len + IO_MODE - 1) / IO_MODE;
////modi by dd
// // tmplen = (skb->len + 2 - 1) / 2;
//// for (i = 0; i < tmplen; i++)
//// VALOUT(((DATA_TYPE *)data_ptr)[i], db->io_data);
// for (i=0;i<skb->len;i++)
// dmfe_outb((data_ptr[i] & 0xff),db->io_data);
//
// /* TX control: First packet immediately send, second packet queue*/
////modi by dd ,06.08.17
// if (db->tx_pkt_cnt < 2)
// {
// //printk("db->tx_pkt_cnt2=%d",db->tx_pkt_cnt);
// /* First packet */
// db->tx_pkt_cnt++;
//
// /* Set TX length to reg. 0xfc & 0xfd */
// iow(db, 0xfc, (skb->len & 0xff));
// iow(db, 0xfd, (skb->len >> 8) & 0xff);
//
// /* Issue TX pollidng command */
// iow(db, DM9KS_TCR, 0x1); /* Cleared after TX complete*/
//// while(!ior(db->io_addr,0x01)&(4|8));
// /* Saved the time stamp */
// dev->trans_start = jiffies;
// }
//
// /* Free this SKB */
// dev_kfree_skb(skb);
//
// /* Re-enable resource check */
// if (db->tx_pkt_cnt < 2)
// netif_wake_queue(dev);
//
// /* Re-enable interrupt */
// iow(db, DM9KS_IMR, DM9KS_REGFF);
// printk("send packet \n");
// return 0;
//}
//endif
/*
Stop the interface.
The interface is stopped when it is brought.
*/
static int dmfe_stop(struct net_device *dev)
{
board_info_t *db = (board_info_t *)dev->priv;
// DMFE_DBUG(0, "dmfe_stop", 0);
/* deleted timer */
del_timer(&db->timer);
netif_stop_queue(dev);
/* free interrupt */
free_irq(dev->irq, dev);
/* RESET devie */
phy_write(db, 0x00, 0x8000); /* PHY RESET */
iow(db, DM9KS_GPR, 0x01); /* Power-Down PHY */
iow(db, DM9KS_IMR, DM9KS_DISINTR); /* Disable all interrupt */
iow(db, DM9KS_RXCR, 0x00); /* Disable RX */
MOD_DEC_USE_COUNT;
/* Dump Statistic counter */
#if FALSE
printk("\nRX FIFO OVERFLOW %lx\n", db->stats.rx_fifo_errors);
printk("RX CRC %lx\n", db->stats.rx_crc_errors);
printk("RX LEN Err %lx\n", db->stats.rx_length_errors);
printk("RX LEN < 64byte %x\n", db->runt_length_counter);
printk("RX LEN > 1514byte %x\n", db->long_length_counter);
printk("RESET %x\n", db->reset_counter);
printk("RESET: TX Timeout %x\n", db->reset_tx_timeout);
printk("RESET: RX Status Wrong %x\n", db->reset_rx_status);
#endif
return 0;
}
static void dmfe_tx_done(unsigned long unused)
{
struct net_device *dev = dmfe_dev;
board_info_t *db = (board_info_t *)dev->priv;
// DMFE_DBUG(0, "dmfe_tx_done()", 0);
int txends, nsr;
nsr = ior(db, 0x01); /* Got TX status */
// printk("nsr=%d",nsr);
txends = nsr = (nsr>>2) & 0x03;
for(;txends; txends>>=1)
{
if(txends&1)
db->tx_pkt_cnt--;
} // of txends
if(nsr) netif_wake_queue(dev);
return;
}
/*
DM9102 insterrupt handler
receive the packet to upper layer, free the transmitted packet
*/
static void dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
// printk("dmfe_int \n");
struct net_device *dev = dev_id;
board_info_t *db;
int int_status;
u8 reg_save;
// printk(".");
// DMFE_DBUG(0, "dmfe_interrupt()", 0);
// if (!dev) {
// DMFE_DBUG(1, "dmfe_interrupt() without DEVICE arg", 0);
// return;
// }
/* A real interrupt coming */
db = (board_info_t *)dev->priv;
spin_lock(&db->lock);
/* Save previous register address */
reg_save = dmfe_inb(db->io_addr);
/* Disable all interrupt */
iow(db, DM9KS_IMR, DM9KS_DISINTR);
//*KAIDA_SYSINTIER&= ~0x4000; // user int 1
//*KAIDA_SCUMASK&=~0x04; // close ISA int
*KAIDA_SCUFLAG&=~0x04;
//*KAIDA_SYSINTICR=*KAIDA_SYSINTICR|0xE000;
/* Got DM9000A/DM9010 interrupt status */
int_status = ior(db, DM9KS_ISR); /* Got ISR */
iow(db, DM9KS_ISR, int_status); /* Clear ISR status */
/* Received the coming packet */
if (int_status & DM9KS_RX_INTR)
dmfe_packet_receive(dev);
/* Trnasmit Interrupt check */
if (int_status & DM9KS_TX_INTR)
tasklet_schedule(&dmfe_tx_tasklet);
/* Re-enable interrupt mask */
iow(db, DM9KS_IMR, DM9KS_REGFF);
//dmfe_int();
/* Restore previous register address */
dmfe_outb(reg_save, db->io_addr);
spin_unlock(&db->lock);
}
/*
Get statistics from driver.
*/
static struct net_device_stats * dmfe_get_stats(struct net_device *dev)
{
board_info_t *db = (board_info_t *)dev->priv;
DMFE_DBUG(0, "dmfe_get_stats", 0);
return &db->stats;
}
/*
Process the upper socket ioctl command, we not used this fun ,set by dd
*/
static int dmfe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
DMFE_DBUG(0, "dmfe_do_ioctl()", 0);
return 0;
}
/*
A periodic timer routine
Dynamic media sense, allocated Rx buffer...
*/
static void dmfe_timer(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
board_info_t *db = (board_info_t *)dev->priv;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -