⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_dm9000.c

📁 dm9000的技术资料(包括数据手册和标准电路图)以及基于arm的开发程序
💻 C
📖 第 1 页 / 共 2 页
字号:
435 {
436     struct eth_drv_sc *sc;
437     struct dm9000 *priv;
438     int i;
439     unsigned id;
440     unsigned short u16tab[64];
441 
442     sc = (struct eth_drv_sc *)ndp->device_instance;
443     priv = (struct dm9000 *)sc->driver_private;
444 
445     priv->sc = sc;
446 
447 #ifdef CYG_HAL_DM9000_PRESENT
448     if (!CYG_HAL_DM9000_PRESENT())
449         return 0;
450 #endif
451 
452     id = getreg(priv, DM_VIDL);
453     id |= getreg(priv, DM_VIDH) << 8;
454     id |= getreg(priv, DM_PIDL) << 16;
455     id |= getreg(priv, DM_PIDH) << 24;
456 
457     if (id != 0x90000A46)
458         return 0;
459 
460     for (i = 0; i < 64; i++)
461         u16tab[i] = eeprom_read(priv, i);
462 
463     u16tab[3] &= ~0xc;
464     u16tab[3] |= 4;
465     u16tab[6] &= 0xfe00;
466     u16tab[6] |= 6;
467 
468 #if 0
469     eeprom_write(priv, 6, u16tab[6]);
470     eeprom_write(priv, 3, u16tab[3]);
471 #endif
472 
473     eeprom_reload(priv);
474 
475     do {
476         for (i = 0; i < 64; i++)
477             u16tab[i] = eeprom_read(priv, i);
478     } while ((u16tab[0] | u16tab[1] | u16tab[2]) == 0);
479 
480     priv->mac_address[0] = u16tab[0];
481     priv->mac_address[1] = u16tab[0] >> 8;
482     priv->mac_address[2] = u16tab[1];
483     priv->mac_address[3] = u16tab[1] >> 8;
484     priv->mac_address[4] = u16tab[2];
485     priv->mac_address[5] = u16tab[2] >> 8;
486 
487     if (!initialize_nic(priv))
488         return 0;
489 
490     // Initialize upper level driver
491     (sc->funs->eth_drv->init)(sc, &(priv->mac_address[0]) );
492     return 1;
493 }
494 
495 // ------------------------------------------------------------------------
496 //
497 //  API Function : dm9000_start
498 //
499 // ------------------------------------------------------------------------
500 static void 
501 dm9000_start( struct eth_drv_sc *sc, unsigned char *enaddr, int flags )
502 {
503     struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
504 
505     // turn on receiver
506     putreg(priv, DM_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
507 
508     // unmask interrupt
509     putreg(priv, DM_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
510 
511     priv->active = 1;
512 }
513 
514 // ------------------------------------------------------------------------
515 //
516 //  API Function : dm9000_stop
517 //
518 // ------------------------------------------------------------------------
519 static void
520 dm9000_stop( struct eth_drv_sc *sc )
521 {
522     struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
523 
524     // turn on receiver
525     putreg(priv, DM_RCR, 0);
526 
527     // mask interrupts
528     putreg(priv, DM_IMR, IMR_PAR);
529 
530     priv->active = 0;
531 }
532 
533 
534 // ------------------------------------------------------------------------
535 //
536 //  API Function : dm9000_recv
537 //
538 // ------------------------------------------------------------------------
539 static void 
540 dm9000_recv( struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len )
541 {
542     struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
543     struct eth_drv_sg *sg = sg_list;
544     cyg_uint8   tmpbuf[4];
545     char *p;
546     int len, total_len, nread, n, leftover;
547 
548     total_len = priv->rxlen;
549     nread = leftover = 0;
550 
551 //    diag_printf("dm9000_recv: total_len=%d\n", total_len);
552 
553     do {
554         p = (char *)sg->buf;
555         len = sg->len;
556 
557 //      diag_printf("recv: buf=%p len=%d to_read=%d, leftover=%d\n", p, len, total_len - nread, leftover);
558 
559         if ((nread + len) > total_len)
560             len = total_len - nread;
561 
562         if (leftover) {
563             if (leftover <= len) {
564                 memcpy(p, tmpbuf + (sizeof(tmpbuf) - leftover), leftover);
565                 p += leftover;
566                 len -= leftover;
567                 nread += leftover;
568                 leftover = 0;
569             } else {
570                 memcpy(p, tmpbuf + (sizeof(tmpbuf) - leftover), len);
571                 leftover -= len;
572                 p += len;
573                 nread += len;
574                 len = 0;
575             }
576         }
577 
578         while (len >= sizeof(tmpbuf)) {
579             n = priv->read_data(priv, p);
580             nread += n;
581             len -= n;
582             p += n;
583         }
584 
585         while (len > 0) {
586             n = priv->read_data(priv, tmpbuf);
587             if (n <= len) {
588                 memcpy(p, tmpbuf, n);
589                 len -= n;
590                 nread += n;
591                 p += n;
592             } else {
593                 memcpy(p, tmpbuf, len);
594                 nread += len;
595                 leftover = n - len;
596                 len = 0;
597             } 
598         }
599         
600         ++sg;
601     } while (nread < total_len);
602 
603 #if 0
604     // dump packet
605     for (sg = sg_list; sg < (sg_list + sg_len); sg++) {
606         diag_printf("\n");
607         diag_dump_buf(sg->buf, sg->len);
608     }
609 #endif
610 }
611 
612 // ------------------------------------------------------------------------
613 //
614 //  API Function : dm9000_can_send
615 //
616 // ------------------------------------------------------------------------
617 static int 
618 dm9000_can_send(struct eth_drv_sc *sc)
619 {
620     struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
621 
622     if (!priv->active || priv->txbusy || priv->reset_pending)
623         return 0;
624 
625     return 1;
626 }
627 
628 
629 // ------------------------------------------------------------------------
630 //
631 //  API Function : dm9000_send
632 //
633 // ------------------------------------------------------------------------
634 static void 
635 dm9000_send(struct eth_drv_sc *sc,
636             struct eth_drv_sg *sg_list, int sg_len,
637             int total_len, unsigned long key)
638 {
639     struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
640     struct eth_drv_sg *sg = sg_list;
641     cyg_uint8 tmpbuf[4];
642     int i, len, extra, n, save_len;
643     char *p;
644 
645     if (0) {
646         diag_printf("dm9000_send: NCR[%02x] NSR[%02x] TPL[%02x]\n",
647                     getreg(priv, DM_NCR), getreg(priv, DM_NSR),
648                     getreg(priv, DM_TRPAL) | (getreg(priv, DM_TRPAH) << 8)
649             );
650     }
651 
652     priv->txbusy = 1;
653 
654     save_len = total_len;
655     extra = 0;
656 
657     HAL_WRITE_UINT8(priv->io_addr, DM_MWCMD);
658 
659     while (total_len > 0) {
660         len = sg->len;
661         if (len > total_len)
662             len = total_len;
663         p = (char *)sg->buf;
664 
665         if (extra) {
666             n = sizeof(tmpbuf) - extra;
667             memcpy(tmpbuf + extra, p, n);
668             p += n;
669             len -= n;
670             for (i = 0; i < sizeof(tmpbuf) && total_len > 0; i += n) {
671                 n = priv->write_data(priv, tmpbuf + i);
672                 total_len -= n;
673             }
674             extra = 0;
675         }
676         
677         while (len >= sizeof(tmpbuf) && total_len > 0) {
678             n = priv->write_data(priv, p);
679             len -= n;
680             total_len -= n;
681             p += n;
682         }
683 
684         if (len > 0 && total_len > 0) {
685             extra = len;
686             memcpy(tmpbuf, p, extra);
687 
688             if ((total_len - extra) <= 0) {
689                 // go ahead and write it now
690                 for (i = 0; total_len > 0; i += n, total_len -= n) {
691                     n = priv->write_data(priv, tmpbuf + i);
692                     total_len = 0;
693                 }
694                 break;
695             }
696         }
697         sg++;
698     }
699 
700     priv->txkey = key;
701 
702     putreg(priv, DM_TXPLL, save_len);
703     putreg(priv, DM_TXPLH, save_len >> 8);
704 
705     putreg(priv, DM_TCR, TCR_TXREQ);
706 
707     return;
708 }
709 
710 // ------------------------------------------------------------------------
711 //
712 //  API Function : dm9000_poll
713 //
714 // ------------------------------------------------------------------------
715 static void
716 dm9000_poll(struct eth_drv_sc *sc)
717 {
718     struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
719     cyg_uint8 status, rxstat, rx1;
720     cyg_uint16 pkt_stat, pkt_len;
721     int i;
722 
723     // mask interrupts
724     putreg(priv, DM_IMR, IMR_PAR);
725 
726     // get and clear staus
727     status = getreg(priv, DM_ISR);
728     putreg(priv, DM_ISR, status);
729 
730     // check for rx done
731     if (1 /*status & ISR_PRS*/) {
732 
733         rx1 = getreg(priv, DM_MRCMDX);
734         HAL_READ_UINT8(priv->io_data, rxstat);
735 
736         // check for packet ready
737         if (rxstat == 1) {
738             cyg_uint16 u16[2];
739             cyg_uint8 *cp;
740 
741             HAL_WRITE_UINT8(priv->io_addr, DM_MRCMD);
742             for (i = 0, cp = (cyg_uint8 *)u16; i < 4; )
743                 i += priv->read_data(priv, cp + i);
744 
745             u16[0] = CYG_LE16_TO_CPU(u16[0]);
746             u16[1] = CYG_LE16_TO_CPU(u16[1]);
747 
748 #if (CYG_BYTEORDER == CYG_MSBFIRST)
749             pkt_stat = u16[0];
750             pkt_len = u16[1];
751 #else
752             pkt_stat = u16[1];
753             pkt_len = u16[0];
754 #endif
755 
756 #ifdef DEBUG
757             diag_printf("pkt_stat=%04x pkt_len=%04x\n", pkt_stat, pkt_len);
758 #endif
759 
760             if (pkt_len < 0x40) {
761                 diag_printf("packet too short: %d (0x%04x)\n", pkt_len, pkt_len);
762                 i = 0;
763                 while (i < pkt_len)
764                     i += priv->read_data(priv, cp);
765             } else if (pkt_len > 1536) {
766                 priv->reset_pending = 1;
767                 diag_printf("packet too long: %d (0x%04x)\n", pkt_len, pkt_len);
768             } else if (pkt_stat & 0xbf00) {
769                 diag_printf("bad packet status: 0x%04x\n", pkt_stat);
770                 i = 0;
771                 while (i < pkt_len)
772                     i += priv->read_data(priv, cp);
773             } else {
774                 // receive packet
775                 priv->rxlen = pkt_len;
776                 (sc->funs->eth_drv->recv)(sc, pkt_len);
777             }
778 
779         } else if (rxstat > 1) {
780             // this should never happen.
781             diag_printf("unknown rxstat byte: %d\n", rxstat);
782             priv->reset_pending = 1;
783         }
784     }
785 
786 
787     // check transmit status
788     if (status & ISR_PTS) {
789         cyg_uint8 txstat;
790 
791         txstat = getreg(priv, DM_NSR);
792 
793         if (txstat & (NSR_TX1END | NSR_TX2END)) {
794             if (txstat & NSR_TX1END)
795                 txstat = getreg(priv, DM_TSRI);
796             else
797                 txstat = getreg(priv, DM_TSRII);
798 
799             if (txstat & TSR_COL) {
800                 // collision
801             }
802 
803             if (getreg(priv, DM_TRPAL) & 3) {
804                 // NIC bug detected. Need to reset.
805                 priv->reset_pending = 1;
806                 diag_printf("NIC collision bug detected!\n");
807             }
808 
809             (sc->funs->eth_drv->tx_done)(sc, priv->txkey, 0);
810             priv->txbusy = 0;
811         }
812     }
813 
814     if (priv->reset_pending && !priv->txbusy) {
815         initialize_nic(priv);
816 
817         // turn on receiver
818         putreg(priv, DM_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
819 
820         priv->reset_pending = 0;
821     }
822 
823     // unmask interrupts
824     putreg(priv, DM_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
825 }
826 
827 
828 // ------------------------------------------------------------------------
829 //
830 //  API Function : dm9000_deliver
831 //
832 // ------------------------------------------------------------------------
833 static void
834 dm9000_deliver(struct eth_drv_sc *sc)
835 {
836     dm9000_poll(sc);
837 }
838 
839 // ------------------------------------------------------------------------
840 //
841 //  API Function : dm9000_int_vector
842 //
843 // ------------------------------------------------------------------------
844 static int
845 dm9000_int_vector(struct eth_drv_sc *sc)
846 {
847     struct dm9000 *priv;
848     priv = (struct dm9000 *)sc->driver_private;
849 
850     return -1;
851 }
852 
853 
854 // ------------------------------------------------------------------------
855 //
856 //  API Function : dm9000_ioctl
857 //
858 // ------------------------------------------------------------------------
859 static int
860 dm9000_ioctl(struct eth_drv_sc *sc, unsigned long key,
861           void *data, int data_length)
862 {
863     return -1;
864 }
865 
866 // ------------------------------------------------------------------------
867 // EOF if_dm9000.c

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -