942 /* Save previous register address */
943 reg_save = inb(db->io_addr);
944
945 /* Disable all interrupt */
946 iow(db, DM9KS_IMR, DM9KS_DISINTR);
947
948 /* Got DM9000/DM9010 interrupt status */
949 int_status = ior(db, DM9KS_ISR); /* Got ISR */
950 iow(db, DM9KS_ISR, int_status); /* Clear ISR status */
951
952 /* Link status change */
953 if (int_status & DM9KS_LINK_INTR)
954 {
955 netif_stop_queue(dev);
956 for(i=0; i<500; i++) /*wait link OK, waiting time =0.5s */
957 {
958 phy_read(db,0x1);
959 if(phy_read(db,0x1) & 0x4) /*Link OK*/
960 {
961 /* wait for detected Speed */
962 for(i=0; i<200;i++)
963 udelay(1000);
964 /* set media speed */
965 if(phy_read(db,0)&0x2000) db->Speed =100;
966 else db->Speed =10;
967 break;
968 }
969 udelay(1000);
970 }
971 netif_wake_queue(dev);
972 //printk('[INTR]i=%d speed=%dn',i, (int)(db->Speed));
973 }
974 /* Received the coming packet */
975 if (int_status & DM9KS_RX_INTR)
976 dmfe_packet_receive(dev);
977
978 /* Trnasmit Interrupt check */
979 if (int_status & DM9KS_TX_INTR)
980 dmfe_tx_done(0);
981
982 if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
983 {
984 iow(db, DM9KS_IMR, 0xa2);
985 }
986 else
987 {
988 /* Re-enable interrupt mask */
989 iow(db, DM9KS_IMR, DM9KS_REGFF);
990 }
991
992 /* Restore previous register address */
993 outb(reg_save, db->io_addr);
994
995 spin_unlock(&db->lock);
996 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
997 return IRQ_HANDLED;
998 #endif
999 }
1000
1001 /*
1002 Get statistics from driver.
1003 */
1004 static struct net_device_stats * dmfe_get_stats(struct net_device *dev)
1005 {
1006 board_info_t *db = (board_info_t *)dev->priv;
1007 DMFE_DBUG(0, 'dmfe_get_stats', 0);
1008 return &db->stats;
1009 }
1010 /*
1011 * Process the ethtool ioctl command
1012 */
1013 static int dmfe_ethtool_ioctl(struct net_device *dev, void *useraddr)
1014 {
1015 //struct dmfe_board_info *db = dev->priv;
1016 struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
1017 u32 ethcmd;
1018
1019 if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd)))
1020 return -EFAULT;
1021
1022 switch (ethcmd)
1023 {
1024 case ETHTOOL_GDRVINFO:
1025 strcpy(info.driver, DRV_NAME);
1026 strcpy(info.version, DRV_VERSION);
1027
1028 sprintf(info.bus_info, 'ISA 0x%lx %d',dev->base_addr, dev->irq);
1029 if (copy_to_user(useraddr, &info, sizeof(info)))
1030 return -EFAULT;
1031 return 0;
1032 }
1033
1034 return -EOPNOTSUPP;
1035 }
1036 /*
1037 Process the upper socket ioctl command
1038 */
1039 static int dmfe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1040 {
1041 board_info_t *db = (board_info_t *)dev->priv;
1042 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) /* for kernel 2.6.7 */
1043 struct mii_ioctl_data *data=(struct mii_ioctl_data *)&ifr->ifr_data;
1044 #endif
1045 int rc=0;
1046
1047 DMFE_DBUG(0, 'dmfe_do_ioctl()', 0);
1048
1049 if (!netif_running(dev))
1050 return -EINVAL;
1051
1052 if (cmd == SIOCETHTOOL)
1053 rc = dmfe_ethtool_ioctl(dev, (void *) ifr->ifr_data);
1054 else {
1055 spin_lock_irq(&db->lock);
1056 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) /* for kernel 2.6.7 */
1057 rc = generic_mii_ioctl(&db->mii, data, cmd, NULL);
1058 #else
1059 rc = generic_mii_ioctl(&db->mii, if_mii(ifr), cmd, NULL);
1060 #endif
1061 spin_unlock_irq(&db->lock);
1062 }
1063
1064 return rc;
1065 }
1066
1067 /* Our watchdog timed out. Called by the networking layer */
1068 static void dmfe_timeout(struct net_device *dev)
1069 {
1070 board_info_t *db = (board_info_t *)dev->priv;
1071 int i;
1072
1073 DMFE_DBUG(0, 'dmfe_TX_timeout()', 0);
1074 printk('TX time-out -- dmfe_timeout().n');
1075 db->reset_tx_timeout++;
1076 db->stats.tx_errors++;
1077
1078 #if FALSE
1079 printk('TX packet count = %dn', db->tx_pkt_cnt);
1080 printk('TX timeout = %dn', db->reset_tx_timeout);
1081 printk('22H=0x%02x 23H=0x%02xn',ior(db,0x22),ior(db,0x23));
1082 printk('faH=0x%02x fbH=0x%02xn',ior(db,0xfa),ior(db,0xfb));
1083 #endif
1084
1085 i=0;
1086
1087 while((i++<100)&&(ior(db,DM9KS_TCR) & 0x01))
1088 {
1089 udelay(30);
1090 }
1091
1092 if(i<100)
1093 {
1094 db->tx_pkt_cnt = 0;
1095 netif_wake_queue(dev);
1096 }
1097 else
1098 {
1099 dmfe_reset(dev);
1100 }
1101
1102 }
1103
1104 static void dmfe_reset(struct net_device * dev)
1105 {
1106 board_info_t *db = (board_info_t *)dev->priv;
1107 u8 reg_save;
1108 int i;
1109 /* Save previous register address */
1110 reg_save = inb(db->io_addr);
1111
1112 netif_stop_queue(dev);
1113 db->reset_counter++;
1114 dmfe_init_dm9000(dev);
1115
1116 db->Speed =10;
1117 for(i=0; i<1000; i++) /*wait link OK, waiting time=1 second */
1118 {
1119 if(phy_read(db,0x1) & 0x4) /*Link OK*/
1120 {
1121 if(phy_read(db,0)&0x2000) db->Speed =100;
1122 else db->Speed =10;
1123 break;
1124 }
1125 udelay(1000);
1126 }
1127
1128 netif_wake_queue(dev);
1129
1130 /* Restore previous register address */
1131 outb(reg_save, db->io_addr);
1132
1133 }
1134 /*
1135 A periodic timer routine
1136 */
1137 static void dmfe_timer(unsigned long data)
1138 {
1139 struct net_device * dev = (struct net_device *)data;
1140 board_info_t *db = (board_info_t *)dev->priv;
1141 DMFE_DBUG(0, 'dmfe_timer()', 0);
1142
1143 if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
1144 {
1145 db->cont_rx_pkt_cnt=0;
上一篇:s3c2440的USB热插拔驱动问题
下一篇:S3C实现DMA驱动程序编写
推荐阅读最新更新时间:2024-11-13 23:25