<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Davicom公司DM9000A和DM9010 ISA NIC 以太網(wǎng)驅(qū)動(dòng)分析

          Davicom公司DM9000A和DM9010 ISA NIC 以太網(wǎng)驅(qū)動(dòng)分析

          作者: 時(shí)間:2012-11-02 來源:網(wǎng)絡(luò) 收藏

          #define check_rx_ready(a) ((a) == 0x01)

          #else

          inline u8 check_rx_ready(u8 rxbyte)

          {

          if (!(rxbyte 0x01))

          return 0;

          return ((rxbyte >> 4) | 0x01);

          }

          #endif

          /*

          Received a packet and pass to upper layer

          */

          static void dmfe_packet_receive(struct net_device *dev)

          {

          board_info_t *db = (board_info_t *)dev->priv;

          struct sk_buff *skb;

          u8 rxbyte, val;

          u16 i, GoodPacket, tmplen = 0, MDRAH, MDRAL;

          u32 tmpdata;

          rx_t rx;

          u16 * ptr = (u16*)rx;

          u8* rdptr;

          DMFE_DBUG(0, dmfe_packet_receive(), 0);

          do {

          /*store the value of Memory Data Read address register*/

          MDRAH=ior(db, DM9KS_MDRAH);

          MDRAL=ior(db, DM9KS_MDRAL);

          ior(db, DM9KS_MRCMDX); /* Dummy read */

          rxbyte = inb(db->io_data); /* Got most updated data */

          /* packet ready to receive check */

          if(!(val = check_rx_ready(rxbyte))) break;

          /* A packet ready now Get status/length */

          GoodPacket = TRUE;

          outb(DM9KS_MRCMD, db->io_addr);

          /* Read packet status length */

          switch (db->io_mode)

          {

          case DM9KS_BYTE_MODE:

          *ptr = inb(db->io_data) +

          (inb(db->io_data) 8);

          *(ptr+1) = inb(db->io_data) +

          (inb(db->io_data) 8);

          break;

          case DM9KS_WORD_MODE:

          *ptr = inw(db->io_data);

          *(ptr+1) = inw(db->io_data);

          break;

          case DM9KS_DWORD_MODE:

          tmpdata = inl(db->io_data);

          *ptr = tmpdata;

          *(ptr+1) = tmpdata >> 16;

          break;

          default:

          break;

          }

          /* Packet status check */

          if (rx.desc.status 0xbf)

          {

          GoodPacket = FALSE;

          if (rx.desc.status 0x01)

          {

          db->stats.rx_fifo_errors++;

          printk(n);

          }

          if (rx.desc.status 0x02)

          {

          db->stats.rx_crc_errors++;

          printk(n);

          }

          if (rx.desc.status 0x80)

          {

          db->stats.rx_length_errors++;

          printk(n);

          }

          if (rx.desc.status 0x08)

          printk(n);

          }

          if (!GoodPacket)

          {

          // drop this packet!!!

          switch (db->io_mode)

          {

          case DM9KS_BYTE_MODE:

          for (i=0; i

          inb(db->io_data);

          break;

          case DM9KS_WORD_MODE:

          tmplen = (rx.desc.length + 1) / 2;

          for (i = 0; i tmplen; i++)

          inw(db->io_data);

          break;

          case DM9KS_DWORD_MODE:

          tmplen = (rx.desc.length + 3) / 4;

          for (i = 0; i tmplen; i++)

          inl(db->io_data);

          break;

          }

          continue;/*next the packet*/

          }

          skb = dev_alloc_skb(rx.desc.length+4);

          if (skb == NULL )

          {

          printk(KERN_INFO %s: Memory squeeze.n, dev->name);

          /*re-load the value into Memory data read address register*/

          iow(db,DM9KS_MDRAH,MDRAH);

          iow(db,DM9KS_MDRAL,MDRAL);

          return;

          }

          else

          {

          /* Move data from DM9000 */

          skb->dev = dev;

          skb_reserve(skb, 2);

          rdptr = (u8*)skb_put(skb, rx.desc.length - 4);

          /* Read received packet from RX SARM */

          switch (db->io_mode)

          {

          case DM9KS_BYTE_MODE:

          for (i=0; i

          rdptr[i]=inb(db->io_data);

          break;

          case DM9KS_WORD_MODE:

          tmplen = (rx.desc.length + 1) / 2;

          for (i = 0; i tmplen; i++)

          ((u16 *)rdptr)[i] = inw(db->io_data);

          break;

          case DM9KS_DWORD_MODE:

          tmplen = (rx.desc.length + 3) / 4;

          for (i = 0; i tmplen; i++)

          ((u32 *)rdptr)[i] = inl(db->io_data);

          break;

          }

          /* Pass to upper layer */

          skb->protocol = eth_type_trans(skb,dev);

          #if defined(CHECKSUM)

          if (val == 0x01)

          skb->ip_summed = CHECKSUM_UNNECESSARY;

          #endif

          netif_rx(skb);

          dev->last_rx=jiffies;

          db->stats.rx_packets++;

          db->stats.rx_bytes += rx.desc.length;

          db->cont_rx_pkt_cnt++;

          if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)

          {

          dmfe_tx_done(0);

          break;

          }

          }

          }while((rxbyte 0x01) == DM9KS_PKT_RDY);

          DMFE_DBUG(0, [END]dmfe_packet_receive(), 0);

          }

          /*

          Read a word data from SROM

          */

          static u16 read_srom_word(board_info_t *db, int offset)

          {

          iow(db, DM9KS_EPAR, offset);

          iow(db, DM9KS_EPCR, 0x4);

          udelay(200);

          iow(db, DM9KS_EPCR, 0x0);

          pid控制相關(guān)文章:pid控制原理




          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();