📄 eth.c
字号:
/* * Copyright (c) 2000 Blue Mug, Inc. All Rights Reserved. */#include <target/assert.h>#include <target/buffer.h>#include <target/herrno.h>#include <target/htypes.h>#include <target/io.h>#include <target/scan.h>#include <target/xfer.h>#include "cs8900.h"#include "eth.h"int ether_init(void){ volatile int i; /* check chip ID */ if (0 && get_reg(PP_ChipID) != 0x630e) { errdata.msg = "CS8900 chip ID mismatch"; return -H_ECUSTOM; } /* reset */ put_reg(PP_SelfCTL, PP_SelfCTL_Reset); for (i=100000; i; --i) /* nada */; /* XXX should be 10ms */ while ((get_reg(PP_SelfSTAT) & PP_SelfSTAT_InitD) == 0); /* enable receiver mode */ put_reg(PP_RxCFG, PP_RxCFG_RxOK); put_reg(PP_RxCTL, PP_RxCTL_RxOK | PP_RxCTL_IA); put_reg(PP_LineCTL, PP_LineCTL_Rx); return 0;}static int ether_mac_cmdfunc(int argc, char *argv[]){ unsigned char macaddr [6]; char *p; word_t word; int i; i = ether_init(); if (i < 0) return i; if (argc == 1) { /* print current MAC address */ for (i=0; i<6; i+=2) { unsigned short sh = get_reg(PP_IA+i); hprintf("%b:%b%c", sh & 0xff, sh >> 8, (i < 4) ? ':' : '\n'); } return 0; } if (argc != 2) return -H_EUSAGE; /* parse given MAC address */ p = *++argv; for (i = 0; *p && (i < 6); i++) { scan_hex(p, &word); macaddr[i] = (unsigned char) word; while (*p && (*p != ':')) ++p; ++p; /* increment past colon */ } if (i < 6) return -H_EUSAGE; /* write address to Ethernet controller */ for (i = 0; i < 6; i += 2) { unsigned short sh = (((unsigned short) macaddr[i+1]) << 8) | macaddr[i]; put_reg(PP_IA+i, sh); } return 0;}const command_t ether_mac_command = { "mac", "[<MAC address>]", "get/set Ethernet MAC address", ðer_mac_cmdfunc };int ether_read(unsigned char *buf, int bufsize){ unsigned short i, rxlen; int length; /* wait for data */ while (!(get_reg(PP_RER) & PP_RER_RxOK)); CS8900_RTDATA; /* stat */ rxlen = CS8900_RTDATA; /* len */ /* 14 bytes for dst, src, and type; 6 for our header */ assert(rxlen > 20); /* read and discard ethernet frame header */ for (i=0; i<7; i++) CS8900_RTDATA; rxlen -= 14; /* byte swap next 2 bytes to get length */ i = CS8900_RTDATA; rxlen -= 2; i = (i << 8) | (i >> 8); length = (unsigned) i; /* read and discard sequence number (should use for assertions) */ CS8900_RTDATA; CS8900_RTDATA; rxlen -= 4; /* read entire frame; store 'bufsize' bytes only */ for (i=0; i<rxlen; i+=2) { unsigned short w = CS8900_RTDATA; if (bufsize-- > 0) *buf++ = w & 0xff; if (bufsize-- > 0) *buf++ = w >> 8; } /* ack current packet */ hputchar('K'); return length;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -