📄 enetlib.c-fjj-bak
字号:
e_frame=(struct enet_frame *)outbarp; (void)memset(e_frame->dest_addr, 0xFF, ENET_ADDR_LENGTH); e_frame->type=ENET_ARPTYPE; a_frame=(struct arp_frame *)e_frame->enet_data; (void)memset(a_frame, 0x00, sizeof(struct arp_frame)); a_frame->ar_hrd=1; a_frame->ar_pro=0x800; a_frame->ar_hln=6; a_frame->ar_pln=4; (void)memcpy(a_frame->ar_tpa, &target_address, a_frame->ar_pln); (void)memcpy(a_frame->ar_sha, hwd_addr, a_frame->ar_hln); (void)memcpy(a_frame->ar_spa, ip_addr, a_frame->ar_pln); a_frame->ar_op=ARP_REQUEST; /*--------------------------------------------------------------------+ | Stack current frame in holding pen (-2 for XLC sizeof). +--------------------------------------------------------------------*/ outframe_len=len+ sizeof(struct enet_frame)- 2; (void)memcpy(datap, p, len); if (enet_send_macframe((char *)outbarp, sizeof(outbarp))) { (void)s1printf("%s: ENETSEND: send frame error.\n",dev.name); } (void)ppcMtmsr(msr); return(-1); } } // (void)s1printf("\n###########send 2 packet###########\n"); (void)memcpy(datap, p, len); fake_length=len+ sizeof(struct enet_frame)- 2; if (fake_length<ENET_MINPACKET) { fake_length=ENET_MINPACKET; } if (enet_send_macframe((char *)outframe, fake_length)) { (void)s1printf("%s: ENETSEND: send frame error.\n",dev.name); (void)ppcMtmsr(msr); return(-1); } (void)ppcMtmsr(msr); return(len+ sizeof(struct enet_frame)- 2);}/*-------------------------------------------------------------------- . . This is the main routine of the driver, to handle the device when . it needs some attention. . . So: . first, save state of the chipset . branch off into routines to handle each case, and acknowledge . each to the interrupt register . and finally restore state. . ---------------------------------------------------------------------*/int enetInt(){ unsigned char status; unsigned int card_stats; unsigned char mask; int timeout; unsigned int saved_bank; unsigned int saved_pointer; unsigned int data_len = 0; int int_status; u8 reg_save; int i; char temp_char; struct ip *ip_ptr; struct enet_frame *ef_ptr; struct arp_frame *af_p; // s1printf("%s: interrupt started \n", dev.name); if ( dev.interrupt ) { s1printf("%s: interrupt inside interrupt.\n", dev.name); return(1); } dev.interrupt = 1; /* Save previous register address */ reg_save = in16(ENET_IO_ADDR)&0xff; /* Disable all interrupt */ iow(DM9KS_IMR, DM9KS_DISINTR); timeout=10; /* Got DM9000A/DM9010 interrupt status */ //s1printf("\njump into interrupt!!!!!!!\n"); do { int_status = ior(DM9KS_ISR); /* Got ISR */ if ((int_status & 0x3) == 0) break; //s1printf("\n interrupt status is %x\n",int_status); iow(DM9KS_ISR, int_status); /* Clear ISR status */ /* Received the coming packet */ if (int_status & DM9KS_RX_INTR) { //s1printf("\nThis is receive interrupt\n"); data_len = enet_rcv_packet(inframe[flih_bufnum].data, ENET_MAX_MTU); for (i = 0; i < data_len; i++) { temp_char=inframe[flih_bufnum].data[i*2]; inframe[flih_bufnum].data[i*2]=inframe[flih_bufnum].data[i*2+1]; inframe[flih_bufnum].data[i*2+1]=temp_char; } //(void)dump(inframe[flih_bufnum].data,data_len); //inframe[flih_bufnum].inframe_len = data_len; /* if(data_len==60) { dump(inframe,data_len); }*/ } /* Trnasmit Interrupt check */ if (int_status & DM9KS_TX_INTR) { // s1printf("\nThis is transmit interrupt\n"); ior(DM9KS_NSR); tx_num=0; } }while(timeout--); /**lp change 2005-6-10 04:44下午///s1printf("\njump out of interrupt!!!!!!!\n"); /* Restore previous register address */ out16(ENET_IO_ADDR,reg_save); /*spin_unlock(&db->lock);*/ if(data_len > 0) { ef_ptr=(struct enet_frame *)&inframe[flih_bufnum].data[0]; // s1printf("Handle packet length = %d, type = %4x\n", data_len, ef_ptr->type); switch(ef_ptr->type) { /*-----------------------------------------------------------------+ | Forward packet to OS Open if destined for that IP address. +-----------------------------------------------------------------*/ case ENET_ARPTYPE: af_p=(struct arp_frame *)ef_ptr->enet_data; // (void)s1printf("\n22222222222222\n"); if ((osopen_enet.ip_addr!=0x0) && (memcmp(af_p->ar_tpa, &osopen_enet.ip_addr, af_p->ar_pln)==0)) { _callxlc((int)(*osopen_enet.recv_function),(char *)ef_ptr, data_len); // (void)s1printf("\n3333333333333\n"); } else { if (af_p->ar_op==ARP_REQUEST) { // (void)s1printf("\n555555555555555555555\n"); /*--------------------------------------------------------+ | If ARP_REQUEST is looking for us then send response. +--------------------------------------------------------*/ if (memcmp(af_p->ar_tpa, ip_addr, af_p->ar_pln)==0) { // (void)s1printf("\n111111111111111111111\n"); (void)enetarp_input(af_p); /*-----------------------------------------------------+ | Formulate reply, using same buffer. +-----------------------------------------------------*/ (void)memcpy(af_p->ar_tha, af_p->ar_sha, af_p->ar_hln); (void)memcpy(af_p->ar_tpa, af_p->ar_spa, af_p->ar_pln); (void)memcpy(af_p->ar_sha, hwd_addr, af_p->ar_hln); (void)memcpy(af_p->ar_spa, ip_addr, af_p->ar_pln); af_p->ar_op=ARP_REPLY; (void)memcpy(ef_ptr->dest_addr, af_p->ar_tha, ENET_ADDR_LENGTH); if (enet_send_macframe((char *)ef_ptr, data_len)) { (void)s1printf("ENET: send frame error.\n"); } } } else if (af_p->ar_op==ARP_REPLY) { // (void)s1printf("\n6666666666666666\n"); (void)enetarp_input(af_p); /*--------------------------------------------------------+ | Real arp processing here, try retransmission if a packet | is in the holding pen. +--------------------------------------------------------*/ ef_ptr=(struct enet_frame *)outframe; ip_ptr=(struct ip *)ef_ptr->enet_data; if ((outframe_len!=0) && (memcmp(&ip_ptr->ip_dst, af_p->ar_spa, sizeof(ip_ptr->ip_dst))==0)) { (void)memcpy(ef_ptr->dest_addr, af_p->ar_sha, ENET_ADDR_LENGTH); if (enet_send_macframe((char *)outframe, outframe_len)) { (void)s1printf("ENET: send frame error.\n"); } else { outframe_len=0; } } } } break; /*-----------------------------------------------------------------+ | Some kind of IP packet. +-----------------------------------------------------------------*/ case ENET_IPTYPE: ip_ptr=(struct ip *)ef_ptr->enet_data; if(ip_ptr->ip_p==0x11) ip_packet=1; if ((osopen_enet.ip_addr!=0x0) && (memcmp(&ip_ptr->ip_dst.s_addr, &osopen_enet.ip_addr, sizeof(ip_ptr->ip_dst.s_addr))==0)) { //(void)s1printf("\n22222222222222\n"); _callxlc((int)(*osopen_enet.recv_function), (char *)ef_ptr, data_len); } else if (memcmp(&ip_ptr->ip_dst.s_addr, ip_addr, sizeof(ip_ptr->ip_dst.s_addr))==0 || ( (*ip_addr == 0) && (memcmp(ef_ptr->dest_addr, hwd_addr, // YYD ENET_ADDR_LENGTH)==0) )) { // (void)s1printf("\n333333333333333\n"); // enable to get packet when ip is not set if ((route_packet((char *)ip_ptr, data_len, (int *)&ef_ptr->dest_addr)==0) && (memcmp(ef_ptr->dest_addr,brd_addr, ENET_ADDR_LENGTH)!=0)) { //(void)s1printf("\n444444444444444444\n"); inframe[flih_bufnum].inframe_len=data_len; flih_bufnum=(flih_bufnum+ 1)% NUMRECV_BUFF; /* flih_bufnum=flih_bufnum+1; if(flih_bufnum==100) flih_bufnum=0;*/ } } break; /*-----------------------------------------------------------------+ | Not IP or ARP discard it. +-----------------------------------------------------------------*/ default: // (void)s1printf("\n#####nothing!!!!!!!\n"); break; } }//s1printf("\ndata >0 is over!!!!\n"); dev.interrupt = 0; /* clear interrupt bit in universal interrupt controller */ ppcMtuicsr(0x80000000>>ENET_INT);// s1printf("%s: Interrupt done\n", dev.name);/* Re-enable interrupt mask */ iow(DM9KS_IMR, DM9KS_REGFF); return(0);} u16 phy_read(int reg){#ifdef DEBUG_MSG_PHYREAD s1printf("\nentern phy read!!!!\n"); #endif /* Fill the phyxcer register into REG_0C */ iow(DM9KS_EPAR, DM9KS_PHY | reg); iow(DM9KS_EPCR, 0xc); /* Issue phyxcer read command */ nsdelay(10000); /* Wait read complete */ iow(DM9KS_EPCR, 0x0); /* Clear phyxcer read command */ /* The read data keeps on REG_0D & REG_0E */ return ( ior(DM9KS_EPDRH) << 8 ) | ior(DM9KS_EPDRL); }/* Write a word to phyxcer*/ void phy_write(int reg, u16 value){#ifdef DEBUG_MSG_PHYWRITE s1printf("\nentern phy write!!!!\n"); #endif /* Fill the phyxcer register into REG_0C */ iow(DM9KS_EPAR, DM9KS_PHY | reg); /* Fill the written data into REG_0D & REG_0E */ iow(DM9KS_EPDRL, (value & 0xff)); iow(DM9KS_EPDRH, ( (value >> 8) & 0xff)); iow(DM9KS_EPCR, 0xa); /* Issue phyxcer write command */ nsdelay(50000); /* Wait write complete */ iow(DM9KS_EPCR, 0x0); /* Clear phyxcer write command */}/* Set PHY operationg mode*/void set_PHY_mode(unsigned char mode){ u16 phy_reg0 = 0x1200; /* Auto-negotiation & Restart Auto-negotiation */ u16 phy_reg4 = 0x01e1; /* Default flow control disable*/ if ( !(mode & DM9KS_AUTO) ) // op_mode didn't auto sense */ { switch(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(0, 0x8000);//soft reset phy_write(0,0x0); //phy_write(0, phy_reg0); phy_write(4, phy_reg4); phy_write(20, 0x0010);} /*Set DM9000A/DM9010 multicast address*/void dm9000_hash_table(){ u16 i, oft, hash_table[4]; /*DMFE_DBUG(0, "dm9000_hash_table()", 0);*/ /* Set Node address */ for (i = 0, oft = 0x10; i < 6; i++, oft++) iow(oft, dev.dev_addr[i]); /* Clear Hash Table */ for (i = 0; i < 4; i++) hash_table[i] = 0x0; /* broadcast address */ hash_table[3] = 0x8000; /* Write the hash table to MAC MD table */ for (i = 0, oft = 0x16; i < 4; i++) { iow(oft++, hash_table[i] & 0xff); iow(oft++, (hash_table[i] >> 8) & 0xff); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -