//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Interrupt-driven Ethernet MAC test code for use on board ////
|
//// OpenCores 10/100 Ethernet MAC test and diagnosis program ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// Controllable ping program - also responds to ARP requests ////
|
//// Controllable ping program - also responds to ARP requests ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - jb, jb@orsoc.se, with parts taken from Linux kernel ////
|
//// - Julius Baxter, julius@opencores.org ////
|
//// open_eth driver. ////
|
//// Parts from old Linux open_eth driver. ////
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2009,2011 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
#include "cpu-utils.h"
|
#include "cpu-utils.h"
|
#include "board.h"
|
#include "board.h"
|
#include "int.h"
|
#include "int.h"
|
#include "uart.h"
|
#include "uart.h"
|
#include "ethmac.h"
|
#include "ethmac.h"
|
#include "printf.h"
|
#include "printf.h"
|
#include "eth-phy-mii.h"
|
#include "eth-phy-mii.h"
|
|
|
|
|
volatile unsigned tx_done;
|
volatile unsigned tx_done;
|
static int next_tx_buf_num;
|
static int next_tx_buf_num;
|
|
|
#define OUR_IP_BYTES 0xc0,0xa8,0x64,0x9b // 192.168.100.155
|
#define OUR_IP_BYTES 0xc0,0xa8,0x64,0x9b // 192.168.100.155
|
#define OUR_IP_LONG 0xc0a8649b
|
#define OUR_IP_LONG 0xc0a8649b
|
|
|
//#define OUR_IP_BYTES 0xc0,0xa8,0x0,0x5a // 192.168.0.90
|
//#define OUR_IP_BYTES 0xc0,0xa8,0x0,0x5a // 192.168.0.90
|
//#define OUR_IP_LONG 0xc0a8005a
|
//#define OUR_IP_LONG 0xc0a8005a
|
|
|
//#define OUR_IP_BYTES 0xc0,0xa8,0x1,0x22 // 192.168.1.34
|
//#define OUR_IP_BYTES 0xc0,0xa8,0x1,0x22 // 192.168.1.34
|
//#define OUR_IP_LONG 0xc0a80122
|
//#define OUR_IP_LONG 0xc0a80122
|
|
|
//#define OUR_IP_BYTES 0xc0,0xa8,0x1,0x2 // 192.168.1.2
|
//#define OUR_IP_BYTES 0xc0,0xa8,0x1,0x2 // 192.168.1.2
|
//#define OUR_IP_LONG 0xc0a80102
|
//#define OUR_IP_LONG 0xc0a80102
|
|
|
//#define OUR_IP_BYTES 0xac,0x1e,0x0,0x2 // 172.30.0.2
|
//#define OUR_IP_BYTES 0xac,0x1e,0x0,0x2 // 172.30.0.2
|
//#define OUR_IP_LONG 0xac1e0002
|
//#define OUR_IP_LONG 0xac1e0002
|
|
|
//#define OUR_IP_BYTES 0xa,0x0,0x0,0x14 // 10.0.0.20
|
//#define OUR_IP_BYTES 0xa,0x0,0x0,0x14 // 10.0.0.20
|
//#define OUR_IP_LONG 0x0a000014
|
//#define OUR_IP_LONG 0x0a000014
|
|
|
|
|
static char our_ip[4] = {OUR_IP_BYTES};
|
static char our_ip[4] = {OUR_IP_BYTES};
|
|
|
#define DEST_IP_BYTES 0xc0,0xa8,0x64,0x69 // 192 .168.100.105
|
#define DEST_IP_BYTES 0xc0,0xa8,0x64,0x69 // 192 .168.100.105
|
//#define DEST_IP_BYTES 0xc0,0xa8,0x01,0x08 // 192 .168.1.8
|
//#define DEST_IP_BYTES 0xc0,0xa8,0x01,0x08 // 192 .168.1.8
|
//#define DEST_IP_BYTES 0xc0,0xa8,0x00,0x0f // 192 .168.0.15
|
//#define DEST_IP_BYTES 0xc0,0xa8,0x00,0x0f // 192 .168.0.15
|
//#define DEST_IP_BYTES 0xac,0x1e,0x0,0x01 // 172.30.0.1
|
//#define DEST_IP_BYTES 0xac,0x1e,0x0,0x01 // 172.30.0.1
|
//#define DEST_IP_BYTES 0xa,0x0,0x0,0x1 // 10.0.0.1
|
//#define DEST_IP_BYTES 0xa,0x0,0x0,0x1 // 10.0.0.1
|
|
|
#define BCAST_DEST_IP_BYTES 0xc0,0xa8,0x64,0xff // 192.168.100.255
|
#define BCAST_DEST_IP_BYTES 0xc0,0xa8,0x64,0xff // 192.168.100.255
|
//#define BCAST_DEST_IP_BYTES 0xc0,0xa8,0x01,0xff // 192.168.1.255
|
//#define BCAST_DEST_IP_BYTES 0xc0,0xa8,0x01,0xff // 192.168.1.255
|
//#define BCAST_DEST_IP_BYTES 0xc0,0xa8,0x00,0xff // 192.168.0.255
|
//#define BCAST_DEST_IP_BYTES 0xc0,0xa8,0x00,0xff // 192.168.0.255
|
//#define BCAST_DEST_IP_BYTES 0xa,0x0,0x0,0xff // 10.0.0.255
|
//#define BCAST_DEST_IP_BYTES 0xa,0x0,0x0,0xff // 10.0.0.255
|
|
|
/* Functions in this file */
|
/* Functions in this file */
|
void ethmac_setup(void);
|
void ethmac_setup(void);
|
void oeth_printregs(void);
|
void oeth_printregs(void);
|
void ethphy_init(void);
|
void ethphy_init(void);
|
void oeth_dump_bds();
|
void oeth_dump_bds();
|
/* Interrupt functions */
|
/* Interrupt functions */
|
void oeth_interrupt(void);
|
void oeth_interrupt(void);
|
static void oeth_rx(void);
|
static void oeth_rx(void);
|
static void oeth_tx(void);
|
static void oeth_tx(void);
|
/* Function to calculate checksum of ping responses we send */
|
/* Function to calculate checksum of ping responses we send */
|
unsigned short calculate_checksum(char* dats, unsigned int len) ;
|
unsigned short calculate_checksum(char* dats, unsigned int len) ;
|
|
|
// Global used to control whether we print out packets as we receive them
|
// Global used to control whether we print out packets as we receive them
|
int print_packet_contents;
|
int print_packet_contents;
|
int packet_inspect_debug;
|
int packet_inspect_debug;
|
int print_ethmac_debug_reg;
|
int print_ethmac_debug_reg;
|
|
|
/* Let the ethernet packets use a space beginning here for buffering */
|
/* Let the ethernet packets use a space beginning here for buffering */
|
#define ETH_BUFF_BASE 0x01000000
|
#define ETH_BUFF_BASE 0x01000000
|
|
|
|
|
#define RXBUFF_PREALLOC 1
|
#define RXBUFF_PREALLOC 1
|
#define TXBUFF_PREALLOC 1
|
#define TXBUFF_PREALLOC 1
|
//#undef RXBUFF_PREALLOC
|
//#undef RXBUFF_PREALLOC
|
//#undef TXBUFF_PREALLOC
|
//#undef TXBUFF_PREALLOC
|
|
|
/* The transmitter timeout
|
/* The transmitter timeout
|
*/
|
*/
|
#define TX_TIMEOUT (2*HZ)
|
#define TX_TIMEOUT (2*HZ)
|
|
|
/* Buffer number (must be 2^n)
|
/* Buffer number (must be 2^n)
|
*/
|
*/
|
#define OETH_RXBD_NUM 124
|
#define OETH_RXBD_NUM 124
|
#define OETH_TXBD_NUM 4
|
#define OETH_TXBD_NUM 4
|
#define OETH_RXBD_NUM_MASK (OETH_RXBD_NUM-1)
|
#define OETH_RXBD_NUM_MASK (OETH_RXBD_NUM-1)
|
#define OETH_TXBD_NUM_MASK (OETH_TXBD_NUM-1)
|
#define OETH_TXBD_NUM_MASK (OETH_TXBD_NUM-1)
|
|
|
/* Buffer size
|
/* Buffer size
|
*/
|
*/
|
#define OETH_RX_BUFF_SIZE 2048
|
#define OETH_RX_BUFF_SIZE 2048
|
#define OETH_TX_BUFF_SIZE 2048
|
#define OETH_TX_BUFF_SIZE 2048
|
|
|
/* Buffer size (if not XXBUF_PREALLOC
|
/* Buffer size (if not XXBUF_PREALLOC
|
*/
|
*/
|
#define MAX_FRAME_SIZE 0x600
|
#define MAX_FRAME_SIZE 0x600
|
//#define MAX_FRAME_SIZE 2500
|
//#define MAX_FRAME_SIZE 2500
|
|
|
/* The buffer descriptors track the ring buffers.
|
/* The buffer descriptors track the ring buffers.
|
*/
|
*/
|
struct oeth_private {
|
struct oeth_private {
|
//struct sk_buff* rx_skbuff[OETH_RXBD_NUM];
|
//struct sk_buff* rx_skbuff[OETH_RXBD_NUM];
|
//struct sk_buff* tx_skbuff[OETH_TXBD_NUM];
|
//struct sk_buff* tx_skbuff[OETH_TXBD_NUM];
|
|
|
unsigned short tx_next;/* Next buffer to be sent */
|
unsigned short tx_next;/* Next buffer to be sent */
|
unsigned short tx_last;/* Next buffer to be checked if packet sent */
|
unsigned short tx_last;/* Next buffer to be checked if packet sent */
|
unsigned short tx_full;/* Buffer ring fuul indicator */
|
unsigned short tx_full;/* Buffer ring fuul indicator */
|
unsigned short rx_cur; /* Next buffer to be checked if packet received */
|
unsigned short rx_cur; /* Next buffer to be checked if packet received */
|
|
|
oeth_regs *regs; /* Address of controller registers. */
|
oeth_regs *regs; /* Address of controller registers. */
|
oeth_bd *rx_bd_base; /* Address of Rx BDs. */
|
oeth_bd *rx_bd_base; /* Address of Rx BDs. */
|
oeth_bd *tx_bd_base; /* Address of Tx BDs. */
|
oeth_bd *tx_bd_base; /* Address of Tx BDs. */
|
|
|
// struct net_device_stats stats;
|
// struct net_device_stats stats;
|
};
|
};
|
|
|
|
int ethphy_found = -1;
|
|
|
#define PRINT_BIT_NAME(bit,name) printf("%02d:"name" %d\n",bit,!!(reg&(1<<bit)))
|
#define PRINT_BIT_NAME(bit,name) printf("%02d:"name" %d\n",bit,!!(reg&(1<<bit)))
|
void oeth_print_moder(unsigned long reg)
|
void oeth_print_moder(unsigned long reg)
|
{
|
{
|
PRINT_BIT_NAME(16,"RECSMALL");
|
PRINT_BIT_NAME(16,"RECSMALL");
|
PRINT_BIT_NAME(15,"PAD");
|
PRINT_BIT_NAME(15,"PAD");
|
PRINT_BIT_NAME(14,"HUGEN");
|
PRINT_BIT_NAME(14,"HUGEN");
|
PRINT_BIT_NAME(13,"CRCEN");
|
PRINT_BIT_NAME(13,"CRCEN");
|
PRINT_BIT_NAME(12,"DLYCRCEN");
|
PRINT_BIT_NAME(12,"DLYCRCEN");
|
PRINT_BIT_NAME(10,"FULLD");
|
PRINT_BIT_NAME(10,"FULLD");
|
PRINT_BIT_NAME(9,"EXDFREN");
|
PRINT_BIT_NAME(9,"EXDFREN");
|
PRINT_BIT_NAME(8,"NOBCKOF");
|
PRINT_BIT_NAME(8,"NOBCKOF");
|
PRINT_BIT_NAME(7,"LOOPBCK");
|
PRINT_BIT_NAME(7,"LOOPBCK");
|
PRINT_BIT_NAME(6,"IFG");
|
PRINT_BIT_NAME(6,"IFG");
|
PRINT_BIT_NAME(5,"PRO");
|
PRINT_BIT_NAME(5,"PRO");
|
PRINT_BIT_NAME(4,"IAM");
|
PRINT_BIT_NAME(4,"IAM");
|
PRINT_BIT_NAME(3,"BRO");
|
PRINT_BIT_NAME(3,"BRO");
|
PRINT_BIT_NAME(2,"NOPRE");
|
PRINT_BIT_NAME(2,"NOPRE");
|
PRINT_BIT_NAME(1,"TXEN");
|
PRINT_BIT_NAME(1,"TXEN");
|
PRINT_BIT_NAME(0,"RXEN");
|
PRINT_BIT_NAME(0,"RXEN");
|
}
|
}
|
|
|
void oeth_print_intsource(unsigned long reg)
|
void oeth_print_intsource(unsigned long reg)
|
{
|
{
|
PRINT_BIT_NAME(6,"RXCtrlFrame");
|
PRINT_BIT_NAME(6,"RXCtrlFrame");
|
PRINT_BIT_NAME(5,"TXCtrlFrame");
|
PRINT_BIT_NAME(5,"TXCtrlFrame");
|
PRINT_BIT_NAME(4,"BUSY");
|
PRINT_BIT_NAME(4,"BUSY");
|
PRINT_BIT_NAME(3,"RXE");
|
PRINT_BIT_NAME(3,"RXE");
|
PRINT_BIT_NAME(2,"RXB");
|
PRINT_BIT_NAME(2,"RXB");
|
PRINT_BIT_NAME(1,"TXE");
|
PRINT_BIT_NAME(1,"TXE");
|
PRINT_BIT_NAME(0,"TXB");
|
PRINT_BIT_NAME(0,"TXB");
|
}
|
}
|
|
|
void oeth_print_ctrlmoder(unsigned long reg)
|
void oeth_print_ctrlmoder(unsigned long reg)
|
{
|
{
|
PRINT_BIT_NAME(2,"TXFLOW");
|
PRINT_BIT_NAME(2,"TXFLOW");
|
PRINT_BIT_NAME(1,"RXFLOW");
|
PRINT_BIT_NAME(1,"RXFLOW");
|
PRINT_BIT_NAME(0,"PASSALL");
|
PRINT_BIT_NAME(0,"PASSALL");
|
}
|
}
|
|
|
void oeth_print_txbuf(unsigned long reg)
|
void oeth_print_txbuf(unsigned long reg)
|
{
|
{
|
printf("RD%d ",!!(reg&(1<<15)));
|
printf("RD%d ",!!(reg&(1<<15)));
|
printf("IQ%d ",!!(reg&(1<<14)));
|
printf("IQ%d ",!!(reg&(1<<14)));
|
printf("WP%d ",!!(reg&(1<<13)));
|
printf("WP%d ",!!(reg&(1<<13)));
|
printf("PD%d ",!!(reg&(1<<12)));
|
printf("PD%d ",!!(reg&(1<<12)));
|
printf("CC%d ",!!(reg&(1<<11)));
|
printf("CC%d ",!!(reg&(1<<11)));
|
printf("UN%d ",!!(reg&(1<<8)));
|
printf("UN%d ",!!(reg&(1<<8)));
|
printf("RY%d ",!!(reg&(1<<3)));
|
printf("RY%d ",!!(reg&(1<<3)));
|
printf("LC%d ",!!(reg&(1<<2)));
|
printf("LC%d ",!!(reg&(1<<2)));
|
printf("DF%d ",!!(reg&(1<<1)));
|
printf("DF%d ",!!(reg&(1<<1)));
|
printf("CS%d ",!!(reg&(1<<0)));
|
printf("CS%d ",!!(reg&(1<<0)));
|
printf("\n");
|
printf("\n");
|
|
|
}
|
}
|
|
|
|
|
void oeth_print_rxbuf(unsigned long reg)
|
void oeth_print_rxbuf(unsigned long reg)
|
{
|
{
|
printf("EM%d ",!!(reg&(1<<15)));
|
printf("EM%d ",!!(reg&(1<<15)));
|
printf("IQ%d ",!!(reg&(1<<14)));
|
printf("IQ%d ",!!(reg&(1<<14)));
|
printf("WP%d ",!!(reg&(1<<13)));
|
printf("WP%d ",!!(reg&(1<<13)));
|
printf("PD%d ",!!(reg&(1<<12)));
|
printf("PD%d ",!!(reg&(1<<12)));
|
printf("CF%d ",!!(reg&(1<<8)));
|
printf("CF%d ",!!(reg&(1<<8)));
|
//printf("MS%d ",!!(reg&(1<<7)));
|
//printf("MS%d ",!!(reg&(1<<7)));
|
printf("OR%d ",!!(reg&(1<<6)));
|
printf("OR%d ",!!(reg&(1<<6)));
|
printf("IS%d ",!!(reg&(1<<5)));
|
printf("IS%d ",!!(reg&(1<<5)));
|
printf("DN%d ",!!(reg&(1<<4)));
|
printf("DN%d ",!!(reg&(1<<4)));
|
printf("TL%d ",!!(reg&(1<<3)));
|
printf("TL%d ",!!(reg&(1<<3)));
|
printf("SF%d ",!!(reg&(1<<2)));
|
printf("SF%d ",!!(reg&(1<<2)));
|
printf("CE%d ",!!(reg&(1<<1)));
|
printf("CE%d ",!!(reg&(1<<1)));
|
printf("LC%d ",!!(reg&(1<<0)));
|
printf("LC%d ",!!(reg&(1<<0)));
|
printf("\n");
|
printf("\n");
|
|
|
}
|
}
|
|
|
// PRINT_BIT_NAME(,"");
|
// PRINT_BIT_NAME(,"");
|
void oeth_printregs(void)
|
void oeth_printregs(void)
|
{
|
{
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
printf("Oeth regs: Mode Register : 0x%lx\n",
|
printf("Oeth regs: Mode Register : 0x%lx\n",
|
(unsigned long) regs->moder); /* Mode Register */
|
(unsigned long) regs->moder); /* Mode Register */
|
oeth_print_moder((unsigned long) regs->moder);
|
oeth_print_moder((unsigned long) regs->moder);
|
printf("Oeth regs: Interrupt Source Register 0x%lx\n",
|
printf("Oeth regs: Interrupt Source Register 0x%lx\n",
|
(unsigned long) regs->int_src); /* Interrupt Source Register */
|
(unsigned long) regs->int_src); /* Interrupt Source Register */
|
oeth_print_intsource((unsigned long) regs->int_src);
|
oeth_print_intsource((unsigned long) regs->int_src);
|
printf("Oeth regs: Interrupt Mask Register 0x%lx\n",
|
printf("Oeth regs: Interrupt Mask Register 0x%lx\n",
|
(unsigned long) regs->int_mask); /* Interrupt Mask Register */
|
(unsigned long) regs->int_mask); /* Interrupt Mask Register */
|
printf("Oeth regs: Back to Bak Inter Packet Gap Register 0x%lx\n",
|
printf("Oeth regs: Back to Bak Inter Packet Gap Register 0x%lx\n",
|
(unsigned long) regs->ipgt); /* Back to Bak Inter Packet Gap Register */
|
(unsigned long) regs->ipgt); /* Back to Bak Inter Packet Gap Register */
|
printf("Oeth regs: Non Back to Back Inter Packet Gap Register 1 0x%lx\n",
|
printf("Oeth regs: Non Back to Back Inter Packet Gap Register 1 0x%lx\n",
|
(unsigned long) regs->ipgr1); /* Non Back to Back Inter Packet Gap Register 1 */
|
(unsigned long) regs->ipgr1); /* Non Back to Back Inter Packet Gap Register 1 */
|
printf("Oeth regs: Non Back to Back Inter Packet Gap Register 2 0x%lx\n",
|
printf("Oeth regs: Non Back to Back Inter Packet Gap Register 2 0x%lx\n",
|
(unsigned long) regs->ipgr2); /* Non Back to Back Inter Packet Gap Register 2 */
|
(unsigned long) regs->ipgr2); /* Non Back to Back Inter Packet Gap Register 2 */
|
printf("Oeth regs: Packet Length Register (min. and max.) 0x%lx\n",
|
printf("Oeth regs: Packet Length Register (min. and max.) 0x%lx\n",
|
(unsigned long) regs->packet_len); /* Packet Length Register (min. and max.) */
|
(unsigned long) regs->packet_len); /* Packet Length Register (min. and max.) */
|
printf("Oeth regs: Collision and Retry Configuration Register 0x%lx\n",
|
printf("Oeth regs: Collision and Retry Configuration Register 0x%lx\n",
|
(unsigned long) regs->collconf); /* Collision and Retry Configuration Register */
|
(unsigned long) regs->collconf); /* Collision and Retry Configuration Register */
|
printf("Oeth regs: Transmit Buffer Descriptor Number Register 0x%lx\n",
|
printf("Oeth regs: Transmit Buffer Descriptor Number Register 0x%lx\n",
|
(unsigned long) regs->tx_bd_num); /* Transmit Buffer Descriptor Number Register */
|
(unsigned long) regs->tx_bd_num); /* Transmit Buffer Descriptor Number Register */
|
printf("Oeth regs: Control Module Mode Register 0x%lx\n",
|
printf("Oeth regs: Control Module Mode Register 0x%lx\n",
|
(unsigned long) regs->ctrlmoder); /* Control Module Mode Register */
|
(unsigned long) regs->ctrlmoder); /* Control Module Mode Register */
|
oeth_print_ctrlmoder((unsigned long) regs->ctrlmoder);
|
oeth_print_ctrlmoder((unsigned long) regs->ctrlmoder);
|
printf("Oeth regs: MII Mode Register 0x%lx\n",
|
printf("Oeth regs: MII Mode Register 0x%lx\n",
|
(unsigned long) regs->miimoder); /* MII Mode Register */
|
(unsigned long) regs->miimoder); /* MII Mode Register */
|
printf("Oeth regs: MII Command Register 0x%lx\n",
|
printf("Oeth regs: MII Command Register 0x%lx\n",
|
(unsigned long) regs->miicommand); /* MII Command Register */
|
(unsigned long) regs->miicommand); /* MII Command Register */
|
printf("Oeth regs: MII Address Register 0x%lx\n",
|
printf("Oeth regs: MII Address Register 0x%lx\n",
|
(unsigned long) regs->miiaddress); /* MII Address Register */
|
(unsigned long) regs->miiaddress); /* MII Address Register */
|
printf("Oeth regs: MII Transmit Data Register 0x%lx\n",
|
printf("Oeth regs: MII Transmit Data Register 0x%lx\n",
|
(unsigned long) regs->miitx_data); /* MII Transmit Data Register */
|
(unsigned long) regs->miitx_data); /* MII Transmit Data Register */
|
printf("Oeth regs: MII Receive Data Register 0x%lx\n",
|
printf("Oeth regs: MII Receive Data Register 0x%lx\n",
|
(unsigned long) regs->miirx_data); /* MII Receive Data Register */
|
(unsigned long) regs->miirx_data); /* MII Receive Data Register */
|
printf("Oeth regs: MII Status Register 0x%lx\n",
|
printf("Oeth regs: MII Status Register 0x%lx\n",
|
(unsigned long) regs->miistatus); /* MII Status Register */
|
(unsigned long) regs->miistatus); /* MII Status Register */
|
printf("Oeth regs: MAC Individual Address Register 0 0x%lx\n",
|
printf("Oeth regs: MAC Individual Address Register 0 0x%lx\n",
|
(unsigned long) regs->mac_addr0); /* MAC Individual Address Register 0 */
|
(unsigned long) regs->mac_addr0); /* MAC Individual Address Register 0 */
|
printf("Oeth regs: MAC Individual Address Register 1 0x%lx\n",
|
printf("Oeth regs: MAC Individual Address Register 1 0x%lx\n",
|
(unsigned long) regs->mac_addr1); /* MAC Individual Address Register 1 */
|
(unsigned long) regs->mac_addr1); /* MAC Individual Address Register 1 */
|
printf("Oeth regs: Hash Register 0 0x%lx\n",
|
printf("Oeth regs: Hash Register 0 0x%lx\n",
|
(unsigned long) regs->hash_addr0); /* Hash Register 0 */
|
(unsigned long) regs->hash_addr0); /* Hash Register 0 */
|
printf("Oeth regs: Hash Register 1 0x%lx\n",
|
printf("Oeth regs: Hash Register 1 0x%lx\n",
|
(unsigned long) regs->hash_addr1); /* Hash Register 1 */
|
(unsigned long) regs->hash_addr1); /* Hash Register 1 */
|
printf("Oeth regs: TXCTRL 0x%lx\n",
|
printf("Oeth regs: TXCTRL 0x%lx\n",
|
(unsigned long) regs->txctrl); /* TX ctrl reg */
|
(unsigned long) regs->txctrl); /* TX ctrl reg */
|
printf("Oeth regs: RXCTRL 0x%lx\n",
|
printf("Oeth regs: RXCTRL 0x%lx\n",
|
(unsigned long) regs->rxctrl); /* RX ctrl reg */
|
(unsigned long) regs->rxctrl); /* RX ctrl reg */
|
printf("Oeth regs: WBDBG 0x%lx\n",
|
printf("Oeth regs: WBDBG 0x%lx\n",
|
(unsigned long) regs->wbdbg); /* Wishbone debug reg */
|
(unsigned long) regs->wbdbg); /* Wishbone debug reg */
|
|
|
}
|
}
|
|
|
void oeth_print_wbdebug(void)
|
void oeth_print_wbdebug(void)
|
{
|
{
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
printf("Oeth regs: WBDBG 0x%lx\n",
|
printf("Oeth regs: WBDBG 0x%lx\n",
|
(unsigned long) regs->wbdbg); /* Wishbone debug reg */
|
(unsigned long) regs->wbdbg); /* Wishbone debug reg */
|
}
|
}
|
|
|
static int last_char;
|
static int last_char;
|
|
|
void spin_cursor(void)
|
void spin_cursor(void)
|
{
|
{
|
#ifdef RTLSIM
|
#ifdef RTLSIM
|
return;
|
return;
|
#endif
|
#endif
|
volatile unsigned int i; // So the loop doesn't get optimised away
|
volatile unsigned int i; // So the loop doesn't get optimised away
|
printf(" \r");
|
printf("\r");
|
if (last_char == 0)
|
if (last_char == 0)
|
printf("/");
|
printf("/");
|
else if (last_char == 1)
|
else if (last_char == 1)
|
printf("-");
|
printf("-");
|
else if (last_char == 2)
|
else if (last_char == 2)
|
printf("\\");
|
printf("\\");
|
else if (last_char == 3)
|
else if (last_char == 3)
|
printf("|");
|
printf("|");
|
else if (last_char == 4)
|
else if (last_char == 4)
|
printf("/");
|
printf("/");
|
else if (last_char == 5)
|
else if (last_char == 5)
|
printf("-");
|
printf("-");
|
else if (last_char == 6)
|
else if (last_char == 6)
|
printf("\\");
|
printf("\\");
|
else if (last_char == 7)
|
else if (last_char == 7)
|
{
|
{
|
printf("|");
|
printf("|");
|
last_char=-1;
|
last_char=-1;
|
}
|
}
|
|
printf("\r");
|
last_char++;
|
last_char++;
|
|
|
for(i=0;i<150000;i++);
|
for(i=0;i<150000;i++);
|
|
|
}
|
}
|
|
|
#define PHYNUM 7
|
static inline void ethphy_smi_read(void)
|
|
{
|
|
|
|
volatile oeth_regs *regs;
|
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
|
regs->miicommand = OETH_MIICOMMAND_RSTAT;
|
|
/* Wait for command to be registered*/
|
|
while(!(regs->miistatus & OETH_MIISTATUS_BUSY));
|
|
|
|
regs->miicommand = 0;
|
|
|
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
|
}
|
|
|
|
|
|
void
|
|
eth_mii_write(char phynum, short regnum, short data)
|
|
{
|
|
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
|
|
regs->miiaddress = (regnum << 8) | phynum;
|
|
regs->miitx_data = data;
|
|
regs->miicommand = OETH_MIICOMMAND_WCTRLDATA;
|
|
regs->miicommand = 0;
|
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
|
}
|
|
|
|
short
|
|
eth_mii_read(char phynum, short regnum)
|
|
{
|
|
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
|
|
regs->miiaddress = (regnum << 8) | phynum;
|
|
regs->miicommand = OETH_MIICOMMAND_RSTAT;
|
|
regs->miicommand = 0;
|
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
|
|
|
return regs->miirx_data;
|
|
}
|
|
|
|
|
/* Scan the MIIM bus for PHYs */
|
/* Scan the MIIM bus for PHYs */
|
void scan_ethphys(void)
|
void scan_ethphys(void)
|
{
|
{
|
unsigned int phynum,regnum, i;
|
unsigned int phynum,regnum, i;
|
|
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
regs->miitx_data = 0;
|
regs->miitx_data = 0;
|
|
|
|
printf("Locating Ethernet PHYs on MDIO bus\n");
|
|
|
for(phynum=0;phynum<32;phynum++)
|
for(phynum=0;phynum<32;phynum++)
|
{
|
{
|
for (regnum=0;regnum<8;regnum++)
|
for (regnum=0;regnum<8;regnum++)
|
{
|
{
|
printf("scan_ethphys: phy %d r%d ",phynum, regnum);
|
|
|
|
/* Now actually perform the read on the MIIM bus*/
|
/* Now actually perform the read on the MIIM bus*/
|
regs->miiaddress = (regnum << 8) | phynum; /* Basic Control Register */
|
regs->miiaddress = (regnum << 8) | phynum; /* Basic Control Register */
|
regs->miicommand = OETH_MIICOMMAND_RSTAT;
|
ethphy_smi_read();
|
|
|
while(!(regs->miistatus & OETH_MIISTATUS_BUSY)); /* Wait for command to be registered*/
|
//printf("%x\n",regs->miirx_data);
|
|
|
regs->miicommand = 0;
|
// Remember first phy found
|
|
if (regnum==0 && regs->miirx_data!=0xffff)
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
{
|
|
// Save found phy address in global variable ethphy_found
|
|
// for use elsewhere.
|
|
ethphy_found = phynum;
|
|
printf("PHY detected at address %d\n",phynum);
|
|
return;
|
|
}
|
|
|
printf("%x\n",regs->miirx_data);
|
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
|
|
/* Scan the MIIM bus for PHYs */
|
/* Scan the MIIM bus for PHYs */
|
void scan_ethphy(unsigned int phynum)
|
void scan_ethphy(unsigned int phynum)
|
{
|
{
|
unsigned int regnum, i;
|
unsigned int regnum, i;
|
|
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
regs->miitx_data = 0;
|
regs->miitx_data = 0;
|
|
|
for (regnum=0;regnum<32;regnum++)
|
for (regnum=0;regnum<32;regnum++)
|
{
|
{
|
printf("scan_ethphy%d: r%x ",phynum, regnum);
|
printf("scan_ethphy%d: r%x ",phynum, regnum);
|
|
|
/* Now actually perform the read on the MIIM bus*/
|
/* Now actually perform the read on the MIIM bus*/
|
regs->miiaddress = (regnum << 8) | phynum; /* Basic Control Register */
|
regs->miiaddress = (regnum << 8) | phynum; /* Basic Control Register */
|
regs->miicommand = OETH_MIICOMMAND_RSTAT;
|
|
|
|
while(!(regs->miistatus & OETH_MIISTATUS_BUSY)); /* Wait for command to be registered*/
|
ethphy_smi_read();
|
|
|
regs->miicommand = 0;
|
printf("%x\n",regs->miirx_data);
|
|
}
|
|
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
}
|
|
|
|
|
|
void ethphy_toggle_loopback(void)
|
|
{
|
|
volatile oeth_regs *regs;
|
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
|
// First read the loopback bit from the basic control reg
|
|
if (eth_mii_read(ethphy_found%0xff, 0) & (1<<14))
|
|
{
|
|
printf("Disabling PHY loopback\n");
|
|
eth_mii_write(ethphy_found, 0,
|
|
eth_mii_read(ethphy_found,0) & ~(1<<14));
|
|
}
|
|
else
|
|
{
|
|
printf("Enabling PHY loopback\n");
|
|
eth_mii_write(ethphy_found, 0,
|
|
eth_mii_read(ethphy_found,0) | (1<<14));
|
|
}
|
|
|
printf("%x\n",regs->miirx_data);
|
|
}
|
}
|
|
|
|
void marvell_phy_toggle_delay(void)
|
|
{
|
|
volatile oeth_regs *regs;
|
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
|
// First read the loopback bit from the basic control reg
|
|
if (eth_mii_read(ethphy_found%0xff, 20) & (1<<1))
|
|
{
|
|
printf("Disabling PHY GTX_CLK delay\n");
|
|
eth_mii_write(ethphy_found, 20,
|
|
eth_mii_read(ethphy_found,20) & ~(1<<1));
|
|
}
|
|
else
|
|
{
|
|
printf("Enabling PHY GTX_CLK delay\n");
|
|
eth_mii_write(ethphy_found, 20,
|
|
eth_mii_read(ethphy_found,20) | (1<<1));
|
|
}
|
|
|
|
}
|
|
|
|
void ethphy_toggle_gigadvertise()
|
|
{
|
|
volatile oeth_regs *regs;
|
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
// Are we advertising gige?
|
|
if (eth_mii_read(ethphy_found%0xff, 9) & (1<<8))
|
|
{
|
|
printf("Disabling 1000base-t advertisement\n");
|
|
eth_mii_write(ethphy_found, 9,
|
|
eth_mii_read(ethphy_found,9) & ~((1<<8)|(1<<9)));
|
|
}
|
|
else
|
|
{
|
|
printf("Enabling 1000base-t advertisement\n");
|
|
eth_mii_write(ethphy_found, 9,
|
|
eth_mii_read(ethphy_found,9) | ((1<<8)|(1<<9)));
|
}
|
}
|
|
|
|
|
|
|
|
}
|
|
|
void ethmac_scanstatus(void)
|
void ethmac_scanstatus(void)
|
{
|
{
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
|
|
printf("Oeth: regs->miistatus %x regs->miirx_data %x\n",regs->miistatus, regs->miirx_data);
|
printf("Oeth: regs->miistatus %x regs->miirx_data %x\n",regs->miistatus, regs->miirx_data);
|
regs->miiaddress = 0;
|
regs->miiaddress = 0;
|
regs->miitx_data = 0;
|
regs->miitx_data = 0;
|
regs->miicommand = OETH_MIICOMMAND_SCANSTAT;
|
regs->miicommand = OETH_MIICOMMAND_SCANSTAT;
|
printf("Oeth: regs->miiaddress %x regs->miicommand %x\n",regs->miiaddress, regs->miicommand);
|
printf("Oeth: regs->miiaddress %x regs->miicommand %x\n",regs->miiaddress, regs->miicommand);
|
//regs->miicommand = 0;
|
//regs->miicommand = 0;
|
volatile int i; for(i=0;i<1000;i++);
|
volatile int i; for(i=0;i<1000;i++);
|
while(regs->miistatus & OETH_MIISTATUS_BUSY) ;
|
while(regs->miistatus & OETH_MIISTATUS_BUSY) ;
|
//spin_cursor();
|
//spin_cursor();
|
//printf("\r");
|
//printf("\r");
|
//or32_exit(0);
|
//or32_exit(0);
|
}
|
}
|
|
|
void
|
|
eth_mii_write(char phynum, short regnum, short data)
|
|
{
|
|
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
|
|
regs->miiaddress = (regnum << 8) | phynum;
|
|
regs->miitx_data = data;
|
|
regs->miicommand = OETH_MIICOMMAND_WCTRLDATA;
|
|
regs->miicommand = 0;
|
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
|
}
|
|
|
|
short
|
|
eth_mii_read(char phynum, short regnum)
|
|
{
|
|
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
|
|
regs->miiaddress = (regnum << 8) | phynum;
|
|
regs->miicommand = OETH_MIICOMMAND_RSTAT;
|
|
regs->miicommand = 0;
|
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
|
|
|
return regs->miirx_data;
|
|
}
|
|
|
|
|
|
void
|
void
|
ethphy_reset(int phynum)
|
ethphy_reset(int phynum)
|
{
|
{
|
eth_mii_write(phynum, MII_BMCR,
|
eth_mii_write(phynum, MII_BMCR,
|
(eth_mii_read(phynum,MII_BMCR)|BMCR_RESET));
|
(eth_mii_read(phynum,MII_BMCR)|BMCR_RESET));
|
}
|
}
|
|
|
|
|
void
|
void
|
ethphy_reneg(int phynum)
|
ethphy_reneg(int phynum)
|
{
|
{
|
eth_mii_write(phynum, MII_BMCR,
|
eth_mii_write(phynum, MII_BMCR,
|
(eth_mii_read(phynum,MII_BMCR)|BMCR_ANRESTART));
|
(eth_mii_read(phynum,MII_BMCR)|BMCR_ANRESTART));
|
}
|
}
|
|
|
void
|
void
|
ethphy_set_10mbit(int phynum)
|
ethphy_set_10mbit(int phynum)
|
{
|
{
|
// Hardset PHY to just use 10Mbit mode
|
// Hardset PHY to just use 10Mbit mode
|
short cr = eth_mii_read(phynum, MII_BMCR);
|
short cr = eth_mii_read(phynum, MII_BMCR);
|
cr &= ~BMCR_ANENABLE; // Clear auto negotiate bit
|
cr &= ~BMCR_ANENABLE; // Clear auto negotiate bit
|
cr &= ~BMCR_SPEED100; // Clear fast eth. bit
|
cr &= ~BMCR_SPEED100; // Clear fast eth. bit
|
eth_mii_write(phynum, MII_BMCR, cr);
|
eth_mii_write(phynum, MII_BMCR, cr);
|
}
|
}
|
|
|
void
|
void
|
ethphy_set_100mbit(int phynum)
|
ethphy_set_100mbit(int phynum)
|
{
|
{
|
// Hardset PHY to just use 10Mbit mode
|
// Hardset PHY to just use 10Mbit mode
|
short cr = eth_mii_read(phynum, MII_BMCR);
|
short cr = eth_mii_read(phynum, MII_BMCR);
|
cr &= !BMCR_ANENABLE; // Clear auto negotiate bit
|
cr &= ~(1<<6);
|
cr |= BMCR_SPEED100; // Clear fast eth. bit
|
cr |= (1<<13);
|
eth_mii_write(phynum, MII_BMCR, cr);
|
eth_mii_write(phynum, MII_BMCR, cr);
|
}
|
}
|
|
|
void
|
void
|
ethphy_set_autoneg(int phynum)
|
ethphy_toggle_autoneg(int phynum)
|
{
|
{
|
// Hardset PHY to just use 10Mbit mode
|
|
short cr = eth_mii_read(phynum, MII_BMCR);
|
|
cr |= BMCR_ANENABLE; // Clear auto negotiate bit
|
|
eth_mii_write(phynum, MII_BMCR, cr);
|
|
}
|
|
|
|
|
|
|
|
void m88e111_config_init(int phyaddr)
|
|
{
|
|
short ctl;
|
|
short adv;
|
|
#if 1
|
|
// Soft reset
|
|
eth_mii_write(phyaddr, MII_BMCR, BMCR_RESET);
|
|
while(eth_mii_read(phyaddr, MII_BMCR) & BMCR_RESET);
|
|
|
|
ctl = eth_mii_read(phyaddr, MII_BMCR);
|
|
ctl &= ~(BMCR_SPD2);
|
|
eth_mii_write(phyaddr, MII_BMCR, ctl);
|
|
|
|
eth_mii_read(phyaddr, MII_ADVERTISE);
|
|
adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_1000XFULL
|
|
|ADVERTISE_1000XHALF | ADVERTISE_1000XPAUSE |
|
|
ADVERTISE_1000XPSE_ASYM);
|
|
adv |= ADVERTISE_10HALF;
|
|
adv |= ADVERTISE_10FULL;
|
|
adv |= ADVERTISE_100HALF;
|
|
adv |= ADVERTISE_100FULL;
|
|
eth_mii_write(phyaddr, MII_ADVERTISE, adv);
|
|
// Disable gigabit???
|
|
adv = eth_mii_read(phyaddr, MII_M1011_PHY_SPEC_CONTROL);
|
|
adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
|
|
MII_1000BASETCONTROL_HALFDUPLEXCAP);
|
|
eth_mii_write(phyaddr, MII_M1011_PHY_SPEC_CONTROL, adv);
|
|
// Even more disable gigabit?!
|
|
adv = eth_mii_read(phyaddr, MII_CTRL1000);
|
|
adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
|
|
eth_mii_write(phyaddr, MII_CTRL1000, adv);
|
|
|
|
// Restart autoneg
|
|
printf("Resetting phy...\n");
|
|
eth_mii_write(phyaddr, MII_BMCR, BMCR_RESET);
|
|
ctl = eth_mii_read(phyaddr, MII_BMCR);
|
|
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
|
|
eth_mii_write(phyaddr, MII_BMCR, ctl);
|
|
#endif
|
|
|
|
#if 0
|
|
// Adapted from kernel: drivers/net/phy/marvell.c
|
|
// Soft reset
|
|
eth_mii_write(phyaddr, MII_BMCR, BMCR_RESET);
|
|
|
|
eth_mii_write(phyaddr, 0x1d, 0x1f);
|
|
eth_mii_write(phyaddr, 0x1e, 0x200c);
|
|
eth_mii_write(phyaddr, 0x1d, 0x5);
|
|
eth_mii_write(phyaddr, 0x1e, 0);
|
|
eth_mii_write(phyaddr, 0x1e, 0x100);
|
|
#define MII_M1011_PHY_SCR 0x10
|
|
#define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060
|
|
eth_mii_write(phyaddr, MII_M1011_PHY_SCR,
|
|
MII_M1011_PHY_SCR_AUTO_CROSS);
|
|
#define MII_M1111_PHY_LED_CONTROL 0x18
|
|
#define MII_M1111_PHY_LED_DIRECT 0x4100
|
|
eth_mii_write(phyaddr, MII_M1111_PHY_LED_CONTROL,
|
|
MII_M1111_PHY_LED_DIRECT);
|
|
|
|
adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
|
|
ADVERTISE_PAUSE_ASYM);
|
|
adv |= ADVERTISE_10HALF;
|
|
adv |= ADVERTISE_10FULL;
|
|
adv |= ADVERTISE_100HALF;
|
|
adv |= ADVERTISE_100FULL;
|
|
adv |= ADVERTISE_PAUSE_CAP;
|
|
adv |= ADVERTISE_PAUSE_ASYM;
|
|
eth_mii_write(phyaddr, MII_ADVERTISE, adv);
|
|
|
|
|
|
ctl = eth_mii_read(phyaddr, MII_BMCR);
|
short cr = eth_mii_read(phynum, MII_BMCR);
|
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
|
if (cr & BMCR_ANENABLE)
|
eth_mii_write(phyaddr, MII_BMCR, ctl);
|
printf("Disabling PHY autonegotiation\n");
|
|
else
|
#endif
|
printf("Enabling PHY autonegotiation\n");
|
|
|
#if 0
|
|
ctl = eth_mii_read(phyaddr, MII_BMCR);
|
|
ctl &= ~(BMCR_ANENABLE); // Disable autoneg...
|
|
// Try forcing config
|
|
ctl = BMCR_SPEED100 | BMCR_FULLDPLX;
|
|
eth_mii_write(phyaddr, MII_BMCR, ctl);
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
cr ^= BMCR_ANENABLE; // Toggle auto negotiate bit
|
|
eth_mii_write(phynum, MII_BMCR, cr);
|
}
|
}
|
|
|
|
|
void ethphy_print_status(int phyaddr)
|
void ethphy_print_status(int phyaddr)
|
{
|
{
|
short regnum, ctl;
|
short regnum, value;
|
int bitnum;
|
int bitnum;
|
int bitset;
|
int bitset;
|
|
short reg2;
|
printf("phyaddr %d\n",phyaddr);
|
printf("phyaddr %d\n",phyaddr);
|
for (regnum = 0;regnum<16; regnum++)
|
for (regnum = 0;regnum<16; regnum++)
|
{
|
{
|
ctl = eth_mii_read(phyaddr, regnum);
|
value = eth_mii_read(phyaddr, regnum);
|
printf("\treg 0x%x: ", regnum);
|
printf("\treg 0x%x: ", regnum);
|
switch(regnum)
|
switch(regnum)
|
{
|
{
|
case 0:
|
case 0:
|
printf("basic control\n");
|
printf("basic control\n");
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 0:
|
case 0:
|
printf("\t\tbit%d:\t%d \t(disable transmitter)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(disable transmitter)\n",bitnum,bitset);
|
break;
|
break;
|
case 6:
|
case 6:
|
printf("\t\tbit%d:\t%d \t(msb speed (1000))\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(msb speed (1000))\n",bitnum,bitset);
|
break;
|
break;
|
case 7:
|
case 7:
|
printf("\t\tbit%d:\t%d \t(collision test)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(collision test)\n",bitnum,bitset);
|
break;
|
break;
|
case 8:
|
case 8:
|
printf("\t\tbit%d:\t%d \t(duplex mode)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(duplex mode)\n",bitnum,bitset);
|
break;
|
break;
|
case 9:
|
case 9:
|
printf("\t\tbit%d:\t%d \t(restart autoneg)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(restart autoneg)\n",bitnum,bitset);
|
break;
|
break;
|
case 10:
|
case 10:
|
printf("\t\tbit%d:\t%d \t(isloate)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(isloate)\n",bitnum,bitset);
|
break;
|
break;
|
case 11:
|
case 11:
|
printf("\t\tbit%d:\t%d \t(power down)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(power down)\n",bitnum,bitset);
|
break;
|
break;
|
case 12:
|
case 12:
|
printf("\t\tbit%d:\t%d \t(autoneg enable)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(autoneg enable)\n",bitnum,bitset);
|
break;
|
break;
|
case 13:
|
case 13:
|
printf("\t\tbit%d:\t%d \t(speed select)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(speed select)\n",bitnum,bitset);
|
break;
|
break;
|
case 14:
|
case 14:
|
printf("\t\tbit%d:\t%d \t(loop back)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(loop back)\n",bitnum,bitset);
|
break;
|
break;
|
case 15:
|
case 15:
|
printf("\t\tbit%d:\t%d \t(reset)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(reset)\n",bitnum,bitset);
|
break;
|
break;
|
default:
|
default:
|
break;
|
break;
|
}
|
}
|
}
|
}
|
break;
|
break;
|
case 1:
|
case 1:
|
printf("basic status\n");
|
printf("basic status\n");
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 0:
|
case 0:
|
printf("\t\tbit%d:\t%d \t(extend capability)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(extend capability)\n",bitnum,bitset);
|
break;
|
break;
|
case 1:
|
case 1:
|
printf("\t\tbit%d:\t%d \t(jabber detect)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(jabber detect)\n",bitnum,bitset);
|
break;
|
break;
|
case 2:
|
case 2:
|
printf("\t\tbit%d:\t%d \t(link status)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(link status)\n",bitnum,bitset);
|
break;
|
break;
|
case 3:
|
case 3:
|
printf("\t\tbit%d:\t%d \t(autoneg capability)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(autoneg capability)\n",bitnum,bitset);
|
break;
|
break;
|
case 4:
|
case 4:
|
printf("\t\tbit%d:\t%d \t(remote fault)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(remote fault)\n",bitnum,bitset);
|
break;
|
break;
|
case 5:
|
case 5:
|
printf("\t\tbit%d:\t%d \t(autoneg complete)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(autoneg complete)\n",bitnum,bitset);
|
break;
|
break;
|
case 6:
|
case 6:
|
printf("\t\tbit%d:\t%d \t(no preamble)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(no preamble)\n",bitnum,bitset);
|
break;
|
break;
|
case 11:
|
case 11:
|
printf("\t\tbit%d:\t%d \t(10base-t half dup.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(10base-t half dup.)\n",bitnum,bitset);
|
break;
|
break;
|
case 12:
|
case 12:
|
printf("\t\tbit%d:\t%d \t(10base-t full dup.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(10base-t full dup.)\n",bitnum,bitset);
|
break;
|
break;
|
case 13:
|
case 13:
|
printf("\t\tbit%d:\t%d \t(100base-t half dup.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(100base-t half dup.)\n",bitnum,bitset);
|
break;
|
break;
|
case 14:
|
case 14:
|
printf("\t\tbit%d:\t%d \t(100base-t full dup.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(100base-t full dup.)\n",bitnum,bitset);
|
break;
|
break;
|
case 15:
|
case 15:
|
printf("\t\tbit%d:\t%d \t(100base-t4)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(100base-t4)\n",bitnum,bitset);
|
break;
|
break;
|
default:
|
default:
|
break;
|
break;
|
|
|
}
|
}
|
}
|
}
|
break;
|
break;
|
|
case 2:
|
|
// We'll do presentation of phy ID in reg 3
|
|
reg2 = value;
|
|
printf("\n");
|
|
break;
|
|
case 3:
|
|
printf("\t\tPHY Identifier (regs 2,3)\n");
|
|
printf("\t\tOrganizationally Unique Identifier (OUI): 0x%06x\n",
|
|
((reg2<<6) | ((value>>10)&0x3f)));
|
|
printf("\t\tManufacturer's Model: 0x%02x\n",(value>>4)&0x3f);
|
|
printf("\t\tRevision number: 0x%01x\n",value&0xf);
|
|
break;
|
case 4:
|
case 4:
|
printf("autoneg advertise reg\n");
|
printf("autoneg advertise reg\n");
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 5:
|
case 5:
|
printf("\t\tbit%d:\t%d \t(10mbps cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(10mbps cap.)\n",bitnum,bitset);
|
break;
|
break;
|
case 6:
|
case 6:
|
printf("\t\tbit%d:\t%d \t(10base-5 full dup. cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(10base-5 full dup. cap.)\n",bitnum,bitset);
|
break;
|
break;
|
case 7:
|
case 7:
|
printf("\t\tbit%d:\t%d \t(100base-tx cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(100base-tx cap.)\n",bitnum,bitset);
|
break;
|
break;
|
case 8:
|
case 8:
|
printf("\t\tbit%d:\t%d \t(100base-tx full dup. cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(100base-tx full dup. cap.)\n",bitnum,bitset);
|
break;
|
break;
|
case 9:
|
case 9:
|
printf("\t\tbit%d:\t%d \t(100base-t4 cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(100base-t4 cap.)\n",bitnum,bitset);
|
break;
|
break;
|
case 10:
|
case 10:
|
printf("\t\tbit%d:\t%d \t(pause cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(pause cap.)\n",bitnum,bitset);
|
break;
|
break;
|
case 13:
|
case 13:
|
printf("\t\tbit%d:\t%d \t(remote fault sup.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(remote fault sup.)\n",bitnum,bitset);
|
break;
|
break;
|
case 15:
|
case 15:
|
printf("\t\tbit%d:\t%d \t(next page cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(next page cap.)\n",bitnum,bitset);
|
break;
|
break;
|
|
|
default:
|
default:
|
break;
|
break;
|
}
|
}
|
}
|
}
|
break;
|
break;
|
case 5:
|
case 5:
|
printf("autoneg link partner ability\n");
|
printf("autoneg link partner ability\n");
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 5:
|
case 5:
|
printf("\t\tbit%d:\t%d \t(10mbps cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(10mbps cap.)\n",bitnum,bitset);
|
break;
|
break;
|
case 6:
|
case 6:
|
printf("\t\tbit%d:\t%d \t(10base-5 full dup. cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(10base-5 full dup. cap.)\n",bitnum,bitset);
|
break;
|
break;
|
case 7:
|
case 7:
|
printf("\t\tbit%d:\t%d \t(100base-tx cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(100base-tx cap.)\n",bitnum,bitset);
|
break;
|
break;
|
case 8:
|
case 8:
|
printf("\t\tbit%d:\t%d \t(100base-tx full dup. cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(100base-tx full dup. cap.)\n",bitnum,bitset);
|
break;
|
break;
|
case 9:
|
case 9:
|
printf("\t\tbit%d:\t%d \t(100base-t4 cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(100base-t4 cap.)\n",bitnum,bitset);
|
break;
|
break;
|
case 10:
|
case 10:
|
printf("\t\tbit%d:\t%d \t(pause cap bit0)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(pause cap bit0)\n",bitnum,bitset);
|
break;
|
break;
|
case 11:
|
case 11:
|
printf("\t\tbit%d:\t%d \t(pause cap bit1)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(pause cap bit1)\n",bitnum,bitset);
|
break;
|
break;
|
|
|
case 13:
|
case 13:
|
printf("\t\tbit%d:\t%d \t(remote fault sup.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(remote fault sup.)\n",bitnum,bitset);
|
break;
|
break;
|
case 14:
|
case 14:
|
printf("\t\tbit%d:\t%d \t(acknowledge)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(acknowledge)\n",bitnum,bitset);
|
break;
|
break;
|
case 15:
|
case 15:
|
printf("\t\tbit%d:\t%d \t(next page cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(next page cap.)\n",bitnum,bitset);
|
break;
|
break;
|
|
|
default:
|
default:
|
break;
|
break;
|
}
|
}
|
}
|
}
|
break;
|
break;
|
case 9:
|
case 9:
|
printf("1000mbit advertise\n");
|
printf("1000mbit advertise\n");
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 8:
|
case 8:
|
printf("\t\tbit%d:\t%d \t(1000base-t half dup)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(1000base-t half dup)\n",bitnum,bitset);
|
break;
|
break;
|
case 9:
|
case 9:
|
printf("\t\tbit%d:\t%d \t(1000base-t full dup)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(1000base-t full dup)\n",bitnum,bitset);
|
break;
|
break;
|
default:
|
default:
|
break;
|
break;
|
}
|
}
|
}
|
}
|
break;
|
break;
|
case 0xf:
|
case 0xf:
|
printf("extended status\n");
|
printf("extended status\n");
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 12:
|
case 12:
|
printf("\t\tbit%d:\t%d \t(1000mb half dup.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(1000mb half dup.)\n",bitnum,bitset);
|
break;
|
break;
|
case 13:
|
case 13:
|
printf("\t\tbit%d:\t%d \t(1000mb full dup.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(1000mb full dup.)\n",bitnum,bitset);
|
break;
|
break;
|
default:
|
default:
|
break;
|
break;
|
}
|
}
|
}
|
}
|
break;
|
break;
|
/* case 1:
|
/* case 1:
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 0:
|
case 0:
|
printf("\t\tbit%d:\t%d \t()\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t()\n",bitnum,bitset);
|
break;
|
break;
|
default:
|
default:
|
break;
|
break;
|
}
|
}
|
}
|
}
|
break;
|
break;
|
*/
|
*/
|
default:
|
default:
|
printf("ignored\n");
|
printf("ignored\n");
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|
|
|
|
|
}
|
}
|
|
|
void ethphy_init(void)
|
void ethphy_init(void)
|
{
|
{
|
|
short ctl;
|
/* Init the Alaska 88E1111 Phy */
|
scan_ethphys();
|
char alaska88e1111_ml501_phynum = 0x7;
|
|
m88e111_config_init(alaska88e1111_ml501_phynum);
|
|
|
|
return;
|
|
|
|
/* Init, reset */
|
|
short ctl = eth_mii_read(alaska88e1111_ml501_phynum, MII_BMCR);
|
|
ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE);
|
|
ctl |= BMCR_SPEED100; // 100MBit
|
|
ctl |= BMCR_FULLDPLX; // Full duplex
|
|
eth_mii_write(alaska88e1111_ml501_phynum, MII_BMCR, ctl);
|
|
|
|
// Setup Autoneg
|
|
short adv = eth_mii_read(alaska88e1111_ml501_phynum, MII_ADVERTISE);
|
|
adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_1000XFULL
|
|
|ADVERTISE_1000XHALF | ADVERTISE_1000XPAUSE |
|
|
ADVERTISE_1000XPSE_ASYM);
|
|
adv |= ADVERTISE_10HALF;
|
|
adv |= ADVERTISE_10FULL;
|
|
adv |= ADVERTISE_100HALF;
|
|
adv |= ADVERTISE_100FULL;
|
|
eth_mii_write(alaska88e1111_ml501_phynum, MII_ADVERTISE, adv);
|
|
// Disable gigabit???
|
|
adv = eth_mii_read(alaska88e1111_ml501_phynum, MII_M1011_PHY_SPEC_CONTROL);
|
|
adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
|
|
MII_1000BASETCONTROL_HALFDUPLEXCAP);
|
|
eth_mii_write(alaska88e1111_ml501_phynum, MII_M1011_PHY_SPEC_CONTROL, adv);
|
|
// Even more disable gigabit?!
|
|
adv = eth_mii_read(alaska88e1111_ml501_phynum, MII_CTRL1000);
|
|
adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
|
|
eth_mii_write(alaska88e1111_ml501_phynum, MII_CTRL1000, adv);
|
|
|
|
// Restart autoneg
|
// Restart autoneg
|
printf("Resetting phy...\n");
|
printf("Resetting phy...\n");
|
ctl = eth_mii_read(alaska88e1111_ml501_phynum, MII_BMCR);
|
ctl = eth_mii_read(ethphy_found, MII_BMCR);
|
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
|
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
|
eth_mii_write(alaska88e1111_ml501_phynum, MII_BMCR, ctl);
|
eth_mii_write(ethphy_found, MII_BMCR, ctl);
|
|
|
printf("\nOeth: PHY control reg: 0x%.4x\n",
|
printf("\nOeth: PHY control reg: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_BMCR));
|
eth_mii_read(ethphy_found, MII_BMCR));
|
printf("Oeth: PHY control reg: 0x%.4x\n",
|
printf("Oeth: PHY control reg: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_BMSR));
|
eth_mii_read(ethphy_found, MII_BMSR));
|
printf("Oeth: PHY id0: 0x%.4x\n",
|
printf("Oeth: PHY id0: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_PHYSID1));
|
eth_mii_read(ethphy_found, MII_PHYSID1));
|
printf("Oeth: PHY id1: 0x%.4x\n",
|
printf("Oeth: PHY id1: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_PHYSID2));
|
eth_mii_read(ethphy_found, MII_PHYSID2));
|
printf("Oeth: PHY adv: 0x%.4x\n",
|
printf("Oeth: PHY adv: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_ADVERTISE));
|
eth_mii_read(ethphy_found, MII_ADVERTISE));
|
printf("Oeth: PHY lpa: 0x%.4x\n",
|
printf("Oeth: PHY lpa: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_LPA));
|
eth_mii_read(ethphy_found, MII_LPA));
|
printf("Oeth: PHY physpec: 0x%.4x\n",
|
printf("Oeth: PHY physpec: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_M1011_PHY_SPEC_CONTROL));
|
eth_mii_read(ethphy_found, MII_M1011_PHY_SPEC_CONTROL));
|
printf("Oeth: PHY expansion: 0x%.4x\n",
|
printf("Oeth: PHY expansion: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_EXPANSION ));
|
eth_mii_read(ethphy_found, MII_EXPANSION ));
|
printf("Oeth: PHY ctrl1000: 0x%.4x\n",
|
printf("Oeth: PHY ctrl1000: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_CTRL1000));
|
eth_mii_read(ethphy_found, MII_CTRL1000));
|
printf("Oeth: PHY stat1000: 0x%.4x\n",
|
printf("Oeth: PHY stat1000: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_STAT1000));
|
eth_mii_read(ethphy_found, MII_STAT1000));
|
printf("Oeth: PHY estatus: 0x%.4x\n",
|
printf("Oeth: PHY estatus: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_ESTATUS));
|
eth_mii_read(ethphy_found, MII_ESTATUS));
|
|
|
|
|
}
|
}
|
|
|
|
|
void ethmac_setup(void)
|
void ethmac_setup(void)
|
{
|
{
|
// from arch/or32/drivers/open_eth.c
|
// from arch/or32/drivers/open_eth.c
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
|
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
/*printf("\nbefore reset\n\n");
|
/*printf("\nbefore reset\n\n");
|
oeth_printregs();*/
|
oeth_printregs();*/
|
|
|
/* Reset MII mode module */
|
/* Reset MII mode module */
|
regs->miimoder = OETH_MIIMODER_RST; /* MII Reset ON */
|
regs->miimoder = OETH_MIIMODER_RST; /* MII Reset ON */
|
regs->miimoder &= ~OETH_MIIMODER_RST; /* MII Reset OFF */
|
regs->miimoder &= ~OETH_MIIMODER_RST; /* MII Reset OFF */
|
regs->miimoder = 0x64; /* Clock divider for MII Management interface */
|
regs->miimoder = 0x64; /* Clock divider for MII Management interface */
|
|
|
/* Reset the controller.
|
/* Reset the controller.
|
*/
|
*/
|
regs->moder = OETH_MODER_RST; /* Reset ON */
|
regs->moder = OETH_MODER_RST; /* Reset ON */
|
regs->moder &= ~OETH_MODER_RST; /* Reset OFF */
|
regs->moder &= ~OETH_MODER_RST; /* Reset OFF */
|
|
|
//printf("\nafter reset\n\n");
|
//printf("\nafter reset\n\n");
|
//oeth_printregs();
|
//oeth_printregs();
|
|
|
/* Setting TXBD base to OETH_TXBD_NUM.
|
/* Setting TXBD base to OETH_TXBD_NUM.
|
*/
|
*/
|
regs->tx_bd_num = OETH_TXBD_NUM;
|
regs->tx_bd_num = OETH_TXBD_NUM;
|
|
|
|
|
/* Set min/max packet length
|
/* Set min/max packet length
|
*/
|
*/
|
//regs->packet_len = 0x00400600;
|
//regs->packet_len = 0x00400600;
|
regs->packet_len = (0x0040 << 16) | (MAX_FRAME_SIZE & 0xffff);
|
regs->packet_len = (0x0040 << 16) | (MAX_FRAME_SIZE & 0xffff);
|
|
|
/* Set IPGT register to recomended value
|
/* Set IPGT register to recomended value
|
*/
|
*/
|
regs->ipgt = 0x12;
|
regs->ipgt = 0x12;
|
|
|
/* Set IPGR1 register to recomended value
|
/* Set IPGR1 register to recomended value
|
*/
|
*/
|
regs->ipgr1 = 0x0000000c;
|
regs->ipgr1 = 0x0000000c;
|
|
|
/* Set IPGR2 register to recomended value
|
/* Set IPGR2 register to recomended value
|
*/
|
*/
|
regs->ipgr2 = 0x00000012;
|
regs->ipgr2 = 0x00000012;
|
|
|
/* Set COLLCONF register to recomended value
|
/* Set COLLCONF register to recomended value
|
*/
|
*/
|
regs->collconf = 0x000f003f;
|
regs->collconf = 0x000f003f;
|
|
|
/* Set control module mode
|
/* Set control module mode
|
*/
|
*/
|
#if 0
|
#if 0
|
regs->ctrlmoder = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW;
|
regs->ctrlmoder = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW;
|
#else
|
#else
|
regs->ctrlmoder = 0;
|
regs->ctrlmoder = 0;
|
#endif
|
#endif
|
|
|
/* Clear MIIM registers */
|
/* Clear MIIM registers */
|
regs->miitx_data = 0;
|
regs->miitx_data = 0;
|
regs->miiaddress = 0;
|
regs->miiaddress = 0;
|
regs->miicommand = 0;
|
regs->miicommand = 0;
|
|
|
regs->mac_addr1 = ETH_MACADDR0 << 8 | ETH_MACADDR1;
|
regs->mac_addr1 = ETH_MACADDR0 << 8 | ETH_MACADDR1;
|
regs->mac_addr0 = ETH_MACADDR2 << 24 | ETH_MACADDR3 << 16 |
|
regs->mac_addr0 = ETH_MACADDR2 << 24 | ETH_MACADDR3 << 16 |
|
ETH_MACADDR4 << 8 | ETH_MACADDR5;
|
ETH_MACADDR4 << 8 | ETH_MACADDR5;
|
|
|
/* Clear all pending interrupts
|
/* Clear all pending interrupts
|
*/
|
*/
|
regs->int_src = 0xffffffff;
|
regs->int_src = 0xffffffff;
|
|
|
/* Promisc, IFG, CRCEn
|
/* Promisc, IFG, CRCEn
|
*/
|
*/
|
regs->moder |= OETH_MODER_PRO | OETH_MODER_PAD | OETH_MODER_IFG |
|
regs->moder |= OETH_MODER_PRO | OETH_MODER_PAD | OETH_MODER_IFG |
|
OETH_MODER_CRCEN | OETH_MODER_FULLD;
|
OETH_MODER_CRCEN | OETH_MODER_FULLD;
|
|
|
/* Enable interrupt sources.
|
/* Enable interrupt sources.
|
*/
|
*/
|
|
|
regs->int_mask = OETH_INT_MASK_TXB |
|
regs->int_mask = OETH_INT_MASK_TXB |
|
OETH_INT_MASK_TXE |
|
OETH_INT_MASK_TXE |
|
OETH_INT_MASK_RXF |
|
OETH_INT_MASK_RXF |
|
OETH_INT_MASK_RXE |
|
OETH_INT_MASK_RXE |
|
OETH_INT_MASK_BUSY |
|
OETH_INT_MASK_BUSY |
|
OETH_INT_MASK_TXC |
|
OETH_INT_MASK_TXC |
|
OETH_INT_MASK_RXC;
|
OETH_INT_MASK_RXC;
|
|
|
// Buffer setup stuff
|
// Buffer setup stuff
|
volatile oeth_bd *tx_bd, *rx_bd;
|
volatile oeth_bd *tx_bd, *rx_bd;
|
int i,j,k;
|
int i,j,k;
|
|
|
/* Initialize TXBD pointer
|
/* Initialize TXBD pointer
|
*/
|
*/
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
|
|
|
/* Initialize RXBD pointer
|
/* Initialize RXBD pointer
|
*/
|
*/
|
rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
|
rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
|
|
|
/* Preallocated ethernet buffer setup */
|
/* Preallocated ethernet buffer setup */
|
unsigned long mem_addr = ETH_BUFF_BASE; /* Defined at top */
|
unsigned long mem_addr = ETH_BUFF_BASE; /* Defined at top */
|
|
|
// Setup TX Buffers
|
// Setup TX Buffers
|
for(i = 0; i < OETH_TXBD_NUM; i++) {
|
for(i = 0; i < OETH_TXBD_NUM; i++) {
|
//tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ;
|
//tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ;
|
tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC;
|
tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC;
|
tx_bd[i].addr = mem_addr;
|
tx_bd[i].addr = mem_addr;
|
mem_addr += OETH_TX_BUFF_SIZE;
|
mem_addr += OETH_TX_BUFF_SIZE;
|
}
|
}
|
tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP;
|
tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP;
|
|
|
// Setup RX buffers
|
// Setup RX buffers
|
for(i = 0; i < OETH_RXBD_NUM; i++) {
|
for(i = 0; i < OETH_RXBD_NUM; i++) {
|
rx_bd[i].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; // Init. with IRQ
|
rx_bd[i].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; // Init. with IRQ
|
rx_bd[i].addr = mem_addr;
|
rx_bd[i].addr = mem_addr;
|
mem_addr += OETH_RX_BUFF_SIZE;
|
mem_addr += OETH_RX_BUFF_SIZE;
|
}
|
}
|
rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; // Last buffer wraps
|
rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; // Last buffer wraps
|
|
|
/* Enable receiver and transmiter
|
/* Enable receiver and transmiter
|
*/
|
*/
|
regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN;
|
regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN;
|
|
|
next_tx_buf_num = 0; // init tx buffer pointer
|
next_tx_buf_num = 0; // init tx buffer pointer
|
|
|
return;
|
return;
|
}
|
}
|
|
|
void oeth_ctrlmode_switch(void)
|
void oeth_ctrlmode_switch(void)
|
{
|
{
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
|
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
if (regs->ctrlmoder & (OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW))
|
if (regs->ctrlmoder & (OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW))
|
{
|
{
|
printf("Disabling TX/RX flow control");
|
printf("Disabling TX/RX flow control");
|
|
|
regs->ctrlmoder = 0;
|
regs->ctrlmoder = 0;
|
}
|
}
|
else
|
else
|
{
|
{
|
printf("Enabling TX/RX flow control");
|
printf("Enabling TX/RX flow control");
|
|
|
regs->ctrlmoder = (OETH_CTRLMODER_TXFLOW |
|
regs->ctrlmoder = (OETH_CTRLMODER_TXFLOW |
|
OETH_CTRLMODER_RXFLOW);
|
OETH_CTRLMODER_RXFLOW);
|
|
|
}
|
}
|
|
|
}
|
}
|
|
|
void
|
void
|
oeth_toggle_promiscuous(void)
|
oeth_toggle_promiscuous(void)
|
{
|
{
|
// from arch/or32/drivers/open_eth.c
|
// from arch/or32/drivers/open_eth.c
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
if ( regs->moder & OETH_MODER_PRO )
|
if ( regs->moder & OETH_MODER_PRO )
|
{
|
{
|
printf("Disabling ");
|
printf("Disabling ");
|
regs->moder &= ~OETH_MODER_PRO;
|
regs->moder &= ~OETH_MODER_PRO;
|
|
|
}
|
}
|
else
|
else
|
{
|
{
|
printf("Enabling ");
|
printf("Enabling ");
|
regs->moder |= OETH_MODER_PRO;
|
regs->moder |= OETH_MODER_PRO;
|
|
|
}
|
}
|
printf("promisucous mode\n");
|
printf("promisucous mode\n");
|
}
|
}
|
|
|
void oeth_transmit_pause(void)
|
void oeth_transmit_pause(void)
|
{
|
{
|
|
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs->txctrl = 0x1fffe;
|
regs->txctrl = 0x1fffe;
|
}
|
}
|
|
|
|
|
void
|
void
|
ethmac_togglehugen(void)
|
ethmac_togglehugen(void)
|
{
|
{
|
|
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
regs->moder ^= OETH_MODER_HUGEN; // Toggle huge packet enable
|
regs->moder ^= OETH_MODER_HUGEN; // Toggle huge packet enable
|
|
|
if (regs->moder & OETH_MODER_HUGEN) // If we just enabled huge packets
|
if (regs->moder & OETH_MODER_HUGEN) // If we just enabled huge packets
|
regs->packet_len = (0x0040 << 16) | (((64*1024)-4) & 0xffff);
|
regs->packet_len = (0x0040 << 16) | (((64*1024)-4) & 0xffff);
|
else
|
else
|
// back to normal
|
// back to normal
|
regs->packet_len = (0x0040 << 16) | (MAX_FRAME_SIZE & 0xffff);
|
regs->packet_len = (0x0040 << 16) | (MAX_FRAME_SIZE & 0xffff);
|
|
|
return;
|
return;
|
|
|
}
|
}
|
|
|
void
|
void
|
oeth_reset_tx_bd_pointer(void)
|
oeth_reset_tx_bd_pointer(void)
|
{
|
{
|
printf("Resetting TX BD pointer\n");
|
printf("Resetting TX BD pointer\n");
|
// from arch/or32/drivers/open_eth.c
|
// from arch/or32/drivers/open_eth.c
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
// Toggle TXEN bit, resetting TX BD number
|
// Toggle TXEN bit, resetting TX BD number
|
regs->moder &= OETH_MODER_TXEN;
|
regs->moder &= OETH_MODER_TXEN;
|
regs->moder |= OETH_MODER_TXEN;
|
regs->moder |= OETH_MODER_TXEN;
|
|
|
next_tx_buf_num = 0; // init tx buffer pointer
|
next_tx_buf_num = 0; // init tx buffer pointer
|
|
|
}
|
}
|
|
|
|
|
|
|
/* Find the next available transmit buffer */
|
/* Find the next available transmit buffer */
|
struct oeth_bd* get_next_tx_bd()
|
struct oeth_bd* get_next_tx_bd()
|
{
|
{
|
|
|
int i;
|
int i;
|
volatile oeth_bd *tx_bd;
|
volatile oeth_bd *tx_bd;
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
|
|
|
/* Go through the TX buffs, search for unused one */
|
/* Go through the TX buffs, search for unused one */
|
for(i = next_tx_buf_num; i < OETH_TXBD_NUM; i++) {
|
for(i = next_tx_buf_num; i < OETH_TXBD_NUM; i++) {
|
|
|
if(!(tx_bd[i].len_status & OETH_TX_BD_READY)) /* Looking for buffer NOT ready for transmit. ie we can manipulate it */
|
if(!(tx_bd[i].len_status & OETH_TX_BD_READY)) /* Looking for buffer NOT ready for transmit. ie we can manipulate it */
|
{
|
{
|
if (print_packet_contents)
|
if (print_packet_contents)
|
printf("Oeth: Using TX_bd at 0x%lx\n",(unsigned long)&tx_bd[i]);
|
printf("Oeth: Using TX_bd at 0x%lx\n",(unsigned long)&tx_bd[i]);
|
|
|
if (next_tx_buf_num == OETH_TXBD_NUM-1) next_tx_buf_num = 0;
|
if (next_tx_buf_num == OETH_TXBD_NUM-1) next_tx_buf_num = 0;
|
else next_tx_buf_num++;
|
else next_tx_buf_num++;
|
|
|
return (struct oeth_bd*) &tx_bd[i];
|
return (struct oeth_bd*) &tx_bd[i];
|
}
|
}
|
|
|
if ((i == OETH_TXBD_NUM-1) && (next_tx_buf_num != 0))
|
if ((i == OETH_TXBD_NUM-1) && (next_tx_buf_num != 0))
|
i = 0;
|
i = 0;
|
|
|
}
|
}
|
|
|
printf("No free tx buffers\n");
|
printf("No free tx buffers\n");
|
/* Set to null our returned buffer */
|
/* Set to null our returned buffer */
|
tx_bd = (volatile oeth_bd *) 0;
|
tx_bd = (volatile oeth_bd *) 0;
|
return (struct oeth_bd*) tx_bd;
|
return (struct oeth_bd*) tx_bd;
|
|
|
}
|
}
|
|
|
/* print packet contents */
|
/* print packet contents */
|
static void
|
static void
|
oeth_print_packet(int bd, unsigned long add, int len)
|
oeth_print_packet(int bd, unsigned long add, int len)
|
{
|
{
|
|
|
int truncate = (len > 256);
|
int truncate = (len > 256);
|
int length_to_print = truncate ? 256 : len;
|
int length_to_print = truncate ? 256 : len;
|
|
|
int i;
|
int i;
|
printf("\nbd%03d packet: add = %lx len = %d\n", bd,add, len);
|
printf("\nbd%03d packet: add = %lx len = %d\n", bd,add, len);
|
for(i = 0; i < length_to_print; i++) {
|
for(i = 0; i < length_to_print; i++) {
|
if(!(i % 8))
|
if(!(i % 8))
|
printf(" ");
|
printf(" ");
|
if(!(i % 16))
|
if(!(i % 16))
|
printf("\n");
|
printf("\n");
|
printf(" %.2x", *(((unsigned char *)add) + i));
|
printf(" %.2x", *(((unsigned char *)add) + i));
|
|
|
}
|
}
|
printf("\n");
|
printf("\n");
|
|
|
if (truncate)
|
if (truncate)
|
printf("\ttruncated....\n");
|
printf("\ttruncated....\n");
|
|
|
}
|
}
|
|
|
/* Setup buffer descriptors with data */
|
/* Setup buffer descriptors with data */
|
/* length is in BYTES */
|
/* length is in BYTES */
|
void tx_packet(void* data, int length)
|
void tx_packet(void* data, int length)
|
{
|
{
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
volatile oeth_bd *tx_bd;
|
volatile oeth_bd *tx_bd;
|
volatile int i;
|
volatile int i;
|
|
|
|
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
|
tx_bd = (struct oeth_bd*) &tx_bd[next_tx_buf_num];
|
tx_bd = (struct oeth_bd*) &tx_bd[next_tx_buf_num];
|
|
|
/*if((tx_bd = (volatile oeth_bd *) get_next_tx_bd()) == NULL)
|
/*if((tx_bd = (volatile oeth_bd *) get_next_tx_bd()) == NULL)
|
{
|
{
|
printf("No more TX buffers available\n");
|
printf("No more TX buffers available\n");
|
return;
|
return;
|
}
|
}
|
*/
|
*/
|
if (print_packet_contents)
|
if (print_packet_contents)
|
printf("Oeth: Using TX_bd buffer address: 0x%lx\n",(unsigned long) tx_bd->addr);
|
printf("Oeth: Using TX_bd buffer address: 0x%lx\n",(unsigned long) tx_bd->addr);
|
|
|
/* Clear all of the status flags.
|
/* Clear all of the status flags.
|
*/
|
*/
|
tx_bd->len_status &= ~OETH_TX_BD_STATS;
|
tx_bd->len_status &= ~OETH_TX_BD_STATS;
|
|
|
/* If the frame is short, tell CPM to pad it.
|
/* If the frame is short, tell CPM to pad it.
|
*/
|
*/
|
#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
|
#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
|
if (length <= ETH_ZLEN)
|
if (length <= ETH_ZLEN)
|
tx_bd->len_status |= OETH_TX_BD_PAD;
|
tx_bd->len_status |= OETH_TX_BD_PAD;
|
else
|
else
|
tx_bd->len_status &= ~OETH_TX_BD_PAD;
|
tx_bd->len_status &= ~OETH_TX_BD_PAD;
|
|
|
//printf("Oeth: Copying %d bytes from 0x%lx to TX_bd buffer at 0x%lx\n",length,(unsigned long) data,(unsigned long) tx_bd->addr);
|
//printf("Oeth: Copying %d bytes from 0x%lx to TX_bd buffer at 0x%lx\n",length,(unsigned long) data,(unsigned long) tx_bd->addr);
|
|
|
/* Copy the data into the transmit buffer, byte at a time */
|
/* Copy the data into the transmit buffer, byte at a time */
|
char* data_p = (char*) data;
|
char* data_p = (char*) data;
|
char* data_b = (char*) tx_bd->addr;
|
char* data_b = (char*) tx_bd->addr;
|
for(i=0;i<length;i++)
|
for(i=0;i<length;i++)
|
{
|
{
|
data_b[i] = data_p[i];
|
data_b[i] = data_p[i];
|
}
|
}
|
//printf("Oeth: Data copied to buffer\n");
|
//printf("Oeth: Data copied to buffer\n");
|
|
|
/* Set the length of the packet's data in the buffer descriptor */
|
/* Set the length of the packet's data in the buffer descriptor */
|
tx_bd->len_status = (tx_bd->len_status & 0x0000ffff) |
|
tx_bd->len_status = (tx_bd->len_status & 0x0000ffff) |
|
((length&0xffff) << 16);
|
((length&0xffff) << 16);
|
|
|
//oeth_print_packet(tx_bd->addr, (tx_bd->len_status >> 16));
|
//oeth_print_packet(tx_bd->addr, (tx_bd->len_status >> 16));
|
|
|
/* Send it on its way. Tell controller its ready, interrupt when sent
|
/* Send it on its way. Tell controller its ready, interrupt when sent
|
* and to put the CRC on the end.
|
* and to put the CRC on the end.
|
*/
|
*/
|
tx_bd->len_status |= (OETH_TX_BD_READY | OETH_TX_BD_CRC | OETH_TX_BD_IRQ);
|
tx_bd->len_status |= (OETH_TX_BD_READY | OETH_TX_BD_CRC | OETH_TX_BD_IRQ);
|
|
|
//next_tx_buf_num = (next_tx_buf_num + 1) & OETH_TXBD_NUM_MASK;
|
//next_tx_buf_num = (next_tx_buf_num + 1) & OETH_TXBD_NUM_MASK;
|
next_tx_buf_num++;
|
next_tx_buf_num++;
|
if (next_tx_buf_num == OETH_TXBD_NUM)
|
if (next_tx_buf_num == OETH_TXBD_NUM)
|
{
|
{
|
next_tx_buf_num = 0;
|
next_tx_buf_num = 0;
|
}
|
}
|
|
|
|
|
return;
|
return;
|
|
|
|
|
}
|
}
|
|
|
/* enable RX, loop waiting for arrived packets and print them out */
|
/* enable RX, loop waiting for arrived packets and print them out */
|
void oeth_monitor_rx(void)
|
void oeth_monitor_rx(void)
|
{
|
{
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
/* Set RXEN in MAC MODER */
|
/* Set RXEN in MAC MODER */
|
regs->moder = OETH_MODER_RXEN | regs->moder;
|
regs->moder = OETH_MODER_RXEN | regs->moder;
|
|
|
|
|
volatile oeth_bd *rx_bd;
|
volatile oeth_bd *rx_bd;
|
rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
|
rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
|
|
|
volatile int i;
|
volatile int i;
|
|
|
for(i=0;i<OETH_RXBD_NUM;i++)
|
for(i=0;i<OETH_RXBD_NUM;i++)
|
{
|
{
|
if (!(rx_bd[i].len_status & OETH_RX_BD_EMPTY)) /* Not empty */
|
if (!(rx_bd[i].len_status & OETH_RX_BD_EMPTY)) /* Not empty */
|
{
|
{
|
// Something in this buffer!
|
// Something in this buffer!
|
printf("Oeth: RX in buf %d - len_status: 0x%lx\n",i, rx_bd[i].len_status);
|
printf("Oeth: RX in buf %d - len_status: 0x%lx\n",i, rx_bd[i].len_status);
|
oeth_print_packet(i,rx_bd[i].addr, rx_bd[i].len_status >> 16);
|
oeth_print_packet(i,rx_bd[i].addr, rx_bd[i].len_status >> 16);
|
/* Clear recieved bit */
|
/* Clear recieved bit */
|
rx_bd[i].len_status |= OETH_RX_BD_EMPTY;
|
rx_bd[i].len_status |= OETH_RX_BD_EMPTY;
|
printf("\t end of packet\n\n");
|
printf("\t end of packet\n\n");
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
#include "spr-defs.h"
|
#include "spr-defs.h"
|
|
|
/* Print out all buffer descriptors */
|
/* Print out all buffer descriptors */
|
void oeth_dump_bds()
|
void oeth_dump_bds()
|
{
|
{
|
// Disable interrupts
|
// Disable interrupts
|
mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_IEE);
|
mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_IEE);
|
|
|
unsigned long* bd_base = (unsigned long*) OETH_BD_BASE;
|
unsigned long* bd_base = (unsigned long*) OETH_BD_BASE;
|
|
|
int i;
|
int i;
|
for(i=0;i<OETH_TXBD_NUM;i++)
|
for(i=0;i<OETH_TXBD_NUM;i++)
|
{
|
{
|
printf("TXBD%03d len_status %08lx ",i,*bd_base);
|
printf("TXBD%03d len_status %08lx ",i,*bd_base);
|
oeth_print_txbuf(*bd_base++);
|
oeth_print_txbuf(*bd_base++);
|
//printf("addr: %lx\n", *bd_base++);
|
//printf("addr: %lx\n", *bd_base++);
|
*bd_base++;
|
*bd_base++;
|
}
|
}
|
|
|
for(i=0;i<OETH_RXBD_NUM;i++)
|
for(i=0;i<OETH_RXBD_NUM;i++)
|
{
|
{
|
printf("RXBD%03d len_status %08lx ",i,*bd_base);
|
printf("RXBD%03d len_status %08lx ",i,*bd_base);
|
oeth_print_rxbuf(*bd_base++);
|
oeth_print_rxbuf(*bd_base++);
|
*bd_base++;
|
*bd_base++;
|
|
|
//printf("addr: %lx\n", *bd_base++);
|
//printf("addr: %lx\n", *bd_base++);
|
}
|
}
|
|
|
// Enable interrupts
|
// Enable interrupts
|
mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_IEE);
|
mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_IEE);
|
|
|
}
|
}
|
|
|
|
|
|
|
char broadcast_ping_packet[] = {
|
char broadcast_ping_packet[] = {
|
0xff,0xff,0xff,0xff,0xff,0xff, /*SRC MAC*/
|
0xff,0xff,0xff,0xff,0xff,0xff, /*SRC MAC*/
|
0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, /*SRC MAC*/
|
0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, /*SRC MAC*/
|
0x08,0x00,
|
0x08,0x00,
|
0x45,
|
0x45,
|
0x00,
|
0x00,
|
// 0x00,0x54, /* length */
|
// 0x00,0x54, /* length */
|
0x01,0x1c, /* length */
|
0x01,0x1c, /* length */
|
0x00,0x00,
|
0x00,0x00,
|
0x40,
|
0x40,
|
0x00,
|
0x00,
|
0x40,
|
0x40,
|
0x01,
|
0x01,
|
0xb5,0x8f,
|
0xb5,0x8f,
|
OUR_IP_BYTES, /* Source IP */
|
OUR_IP_BYTES, /* Source IP */
|
BCAST_DEST_IP_BYTES, /* Dest. IP */
|
BCAST_DEST_IP_BYTES, /* Dest. IP */
|
/* ICMP Message body */
|
/* ICMP Message body */
|
0x08,0x00,0x7d,0x65,0xa7,0x20,0x00,0x01,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
|
0x08,0x00,0x7d,0x65,0xa7,0x20,0x00,0x01,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
|
15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
|
15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
|
40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
|
40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
|
65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,
|
65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,
|
90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,
|
90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,
|
111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,
|
111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,
|
130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,
|
130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,
|
149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,
|
149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,
|
168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,
|
168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,
|
187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,
|
187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,
|
206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
|
206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
|
225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,
|
225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,
|
244,245,246,247,248,249,250,251,252,253,254,255};
|
244,245,246,247,248,249,250,251,252,253,254,255};
|
|
|
|
|
char big_ping_packet[] = {
|
char big_ping_packet[] = {
|
0x00, 0x24, 0xe8, 0x91, 0x7c, 0x0d, /*DST MAC*/
|
0x00, 0x24, 0xe8, 0x91, 0x7c, 0x0d, /*DST MAC*/
|
//0xff,0xff,0xff,0xff,0xff,0xff, /*SRC MAC*/
|
//0xff,0xff,0xff,0xff,0xff,0xff, /*SRC MAC*/
|
0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, /*SRC MAC*/
|
0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, /*SRC MAC*/
|
0x08,0x00,
|
0x08,0x00,
|
0x45,
|
0x45,
|
0x00,
|
0x00,
|
0x05,0xdc, /* length */
|
0x05,0xdc, /* length */
|
0x00,0x00,
|
0x00,0x00,
|
0x40,
|
0x40,
|
0x00,
|
0x00,
|
0x40,
|
0x40,
|
0x01,
|
0x01,
|
0xea,0xcb, /* Header checksum */
|
0xea,0xcb, /* Header checksum */
|
OUR_IP_BYTES, /* Source IP */
|
OUR_IP_BYTES, /* Source IP */
|
DEST_IP_BYTES, /* Dest. IP */
|
DEST_IP_BYTES, /* Dest. IP */
|
/* ICMP Message body */
|
/* ICMP Message body */
|
0x08,0x00, /* Type */
|
0x08,0x00, /* Type */
|
0x04,0x48, /* ICMP checksum */
|
0x04,0x48, /* ICMP checksum */
|
0x02,0x00, /* Identifier */
|
0x02,0x00, /* Identifier */
|
0x3a,0x00, /* sequence number */
|
0x3a,0x00, /* sequence number */
|
0x61,0x62,0x63,0x64,0x65,0x66,0x67,
|
0x61,0x62,0x63,0x64,0x65,0x66,0x67,
|
0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
|
0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
|
0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
|
0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
|
0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
|
0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
|
0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
|
0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
|
0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
|
0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
|
0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,
|
0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,
|
0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
|
0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
|
0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
|
0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
|
0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,
|
0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,
|
0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
|
0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
|
0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
|
0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
|
0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,
|
0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,
|
0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,
|
0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,
|
0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
|
0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
|
0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,
|
0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,
|
0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
|
0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
|
0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
|
0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
|
0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
|
0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
|
0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,
|
0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,
|
0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
|
0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
|
0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
|
0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
|
0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
|
0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
|
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
|
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
|
0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
|
0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
|
0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
|
0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
|
0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
|
0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
|
0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
|
0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
|
0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
|
0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
|
0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,
|
0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,
|
0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
|
0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
|
0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
|
0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
|
0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,
|
0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,
|
0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
|
0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
|
0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
|
0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
|
0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,
|
0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,
|
0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,
|
0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,
|
0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
|
0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
|
0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,
|
0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,
|
0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
|
0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
|
0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
|
0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
|
0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
|
0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
|
0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,
|
0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,
|
0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
|
0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
|
0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
|
0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
|
0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
|
0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
|
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
|
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
|
0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
|
0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
|
0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
|
0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
|
0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
|
0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
|
0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
|
0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
|
0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
|
0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
|
0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,
|
0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,
|
0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
|
0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
|
0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
|
0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
|
0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,
|
0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,
|
0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
|
0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
|
0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
|
0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
|
0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,
|
0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,
|
0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,
|
0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,
|
0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
|
0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
|
0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,
|
0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,
|
0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
|
0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
|
0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
|
0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
|
0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
|
0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
|
0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,
|
0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,
|
0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
|
0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
|
0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
|
0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
|
0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
|
0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
|
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
|
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
|
0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
|
0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
|
0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
|
0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
|
0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
|
0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
|
0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
|
0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
|
0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
|
0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
|
0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,
|
0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,
|
0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
|
0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
|
0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
|
0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
|
0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,
|
0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,
|
0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
|
0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
|
0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
|
0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
|
0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,
|
0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,
|
0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,
|
0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,
|
0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
|
0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
|
0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,
|
0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,
|
0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
|
0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
|
0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
|
0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
|
0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
|
0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
|
0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,
|
0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,
|
0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
|
0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
|
0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
|
0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
|
0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
|
0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
|
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
|
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
|
0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
|
0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
|
0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
|
0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
|
0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
|
0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
|
0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
|
0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
|
0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
|
0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
|
0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77};
|
0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77};
|
|
|
|
|
/* This should be 98 bytes big */
|
/* This should be 98 bytes big */
|
char ping_packet[] = {
|
char ping_packet[] = {
|
0x00, 0x24, 0xe8, 0x91, 0x7c, 0x0d, /*DST MAC*/
|
0x00, 0x24, 0xe8, 0x91, 0x7c, 0x0d, /*DST MAC*/
|
//0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /*DST MAC*/
|
//0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /*DST MAC*/
|
0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, /*SRC MAC*/
|
0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, /*SRC MAC*/
|
0x08, 0x00, /*TYPE*/
|
0x08, 0x00, /*TYPE*/
|
/* IP */
|
/* IP */
|
0x45, /* Version, header length*/
|
0x45, /* Version, header length*/
|
0x00, /* Differentiated services field */
|
0x00, /* Differentiated services field */
|
0x00, 0x54, /* Total length */
|
0x00, 0x54, /* Total length */
|
0x00, 0x00, /* Identification */
|
0x00, 0x00, /* Identification */
|
0x40, /* Flags */
|
0x40, /* Flags */
|
0x00, /* Fragment offset */
|
0x00, /* Fragment offset */
|
0x40, /* Time to live */
|
0x40, /* Time to live */
|
0x01, /* Protocol (0x01 = ICMP */
|
0x01, /* Protocol (0x01 = ICMP */
|
0xf0, 0x53, /* Header checksum */
|
0xf0, 0x53, /* Header checksum */
|
//0xc0, 0xa8, 0x64, 0xDE, /* Source IP */
|
//0xc0, 0xa8, 0x64, 0xDE, /* Source IP */
|
OUR_IP_BYTES, /* Source IP */
|
OUR_IP_BYTES, /* Source IP */
|
DEST_IP_BYTES, /* Dest. IP */
|
DEST_IP_BYTES, /* Dest. IP */
|
/* ICMP Message body */
|
/* ICMP Message body */
|
0x08, 0x00, 0x9a, 0xd4, 0xc8, 0x18, 0x00, 0x01, 0xd9, 0x8c, 0x54,
|
0x08, 0x00, 0x9a, 0xd4, 0xc8, 0x18, 0x00, 0x01, 0xd9, 0x8c, 0x54,
|
0x4a, 0x7b, 0x37, 0x01, 0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
|
0x4a, 0x7b, 0x37, 0x01, 0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
|
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
|
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
|
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
|
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
|
0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
|
0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
|
};
|
};
|
|
|
void send_test_packet()
|
void send_test_packet()
|
{
|
{
|
|
|
/*Send packet */
|
/*Send packet */
|
//tx_packet((void*) ping_packet, 102);
|
//tx_packet((void*) ping_packet, 102);
|
tx_packet((void*) broadcast_ping_packet, 102);
|
tx_packet((void*) broadcast_ping_packet, 102);
|
|
|
}
|
}
|
|
|
|
|
/* The interrupt handler.
|
/* The interrupt handler.
|
*/
|
*/
|
void
|
void
|
oeth_interrupt(void)
|
oeth_interrupt(void)
|
{
|
{
|
|
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
uint int_events;
|
uint int_events;
|
int serviced;
|
int serviced;
|
|
|
serviced = 0;
|
serviced = 0;
|
|
|
/* Get the interrupt events that caused us to be here.
|
/* Get the interrupt events that caused us to be here.
|
*/
|
*/
|
int_events = regs->int_src;
|
int_events = regs->int_src;
|
regs->int_src = int_events;
|
regs->int_src = int_events;
|
|
|
|
|
/* Indicate busy */
|
/* Indicate busy */
|
if (int_events & OETH_INT_BUSY)
|
if (int_events & OETH_INT_BUSY)
|
{
|
{
|
printf("\tBusy flag\n");
|
printf("\tBusy flag\n");
|
/*
|
/*
|
printf("\n=tx_ | %x | %x | %x | %x | %x | %x | %x | %x\n",
|
printf("\n=tx_ | %x | %x | %x | %x | %x | %x | %x | %x\n",
|
((oeth_bd *)(OETH_BD_BASE))->len_status,
|
((oeth_bd *)(OETH_BD_BASE))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+8))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+8))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+16))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+16))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+24))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+24))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+32))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+32))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+40))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+40))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+48))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+48))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+56))->len_status);
|
((oeth_bd *)(OETH_BD_BASE+56))->len_status);
|
*/
|
*/
|
printf("=rx_ | %x | %x | %x | %x | %x | %x | %x | %x\n",
|
printf("=rx_ | %x | %x | %x | %x | %x | %x | %x | %x\n",
|
((oeth_bd *)(OETH_BD_BASE+64))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+8))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+8))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+16))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+16))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+24))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+24))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+32))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+32))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+40))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+40))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+48))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+48))->len_status,
|
((oeth_bd *)(OETH_BD_BASE+64+56))->len_status);
|
((oeth_bd *)(OETH_BD_BASE+64+56))->len_status);
|
|
|
printf("=int | rxc %d | txc %d | txb %d | txe %d | rxb %d | rxe %d | busy %d\n",
|
printf("=int | rxc %d | txc %d | txb %d | txe %d | rxb %d | rxe %d | busy %d\n",
|
(int_events & OETH_INT_RXC) > 0,
|
(int_events & OETH_INT_RXC) > 0,
|
(int_events & OETH_INT_TXC) > 0,
|
(int_events & OETH_INT_TXC) > 0,
|
(int_events & OETH_INT_TXB) > 0,
|
(int_events & OETH_INT_TXB) > 0,
|
(int_events & OETH_INT_TXE) > 0,
|
(int_events & OETH_INT_TXE) > 0,
|
(int_events & OETH_INT_RXF) > 0,
|
(int_events & OETH_INT_RXF) > 0,
|
(int_events & OETH_INT_RXE) > 0,
|
(int_events & OETH_INT_RXE) > 0,
|
(int_events & OETH_INT_BUSY) > 0);
|
(int_events & OETH_INT_BUSY) > 0);
|
}/*
|
}/*
|
else
|
else
|
printf("=int | rxc %d | txc %d | txb %d | txe %d | rxb %d | rxe %d | busy %d\n",
|
printf("=int | rxc %d | txc %d | txb %d | txe %d | rxb %d | rxe %d | busy %d\n",
|
(int_events & OETH_INT_RXC) > 0,
|
(int_events & OETH_INT_RXC) > 0,
|
(int_events & OETH_INT_TXC) > 0,
|
(int_events & OETH_INT_TXC) > 0,
|
(int_events & OETH_INT_TXB) > 0,
|
(int_events & OETH_INT_TXB) > 0,
|
(int_events & OETH_INT_TXE) > 0,
|
(int_events & OETH_INT_TXE) > 0,
|
(int_events & OETH_INT_RXF) > 0,
|
(int_events & OETH_INT_RXF) > 0,
|
(int_events & OETH_INT_RXE) > 0,
|
(int_events & OETH_INT_RXE) > 0,
|
(int_events & OETH_INT_BUSY) > 0);
|
(int_events & OETH_INT_BUSY) > 0);
|
*/
|
*/
|
/* Handle receive event in its own function.
|
/* Handle receive event in its own function.
|
*/
|
*/
|
if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) {
|
if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) {
|
serviced |= 0x1;
|
serviced |= 0x1;
|
if (print_ethmac_debug_reg)
|
if (print_ethmac_debug_reg)
|
oeth_print_wbdebug();
|
oeth_print_wbdebug();
|
oeth_rx();
|
oeth_rx();
|
if (print_ethmac_debug_reg)
|
if (print_ethmac_debug_reg)
|
oeth_print_wbdebug();
|
oeth_print_wbdebug();
|
}
|
}
|
|
|
/* Handle transmit event in its own function.
|
/* Handle transmit event in its own function.
|
*/
|
*/
|
if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) {
|
if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) {
|
if (print_ethmac_debug_reg)
|
if (print_ethmac_debug_reg)
|
oeth_print_wbdebug();
|
oeth_print_wbdebug();
|
serviced |= 0x2;
|
serviced |= 0x2;
|
oeth_tx();
|
oeth_tx();
|
serviced |= 0x2;
|
serviced |= 0x2;
|
if (print_ethmac_debug_reg)
|
if (print_ethmac_debug_reg)
|
oeth_print_wbdebug();
|
oeth_print_wbdebug();
|
|
|
}
|
}
|
|
|
return;
|
return;
|
}
|
}
|
|
|
// ARP stuff
|
// ARP stuff
|
|
|
typedef unsigned long IPaddr_t;
|
typedef unsigned long IPaddr_t;
|
|
|
/*
|
/*
|
* Ethernet header
|
* Ethernet header
|
*/
|
*/
|
typedef struct {
|
typedef struct {
|
unsigned char et_dest[6]; /* Destination node */
|
unsigned char et_dest[6]; /* Destination node */
|
unsigned char et_src[6]; /* Source node */
|
unsigned char et_src[6]; /* Source node */
|
unsigned short et_protlen; /* Protocol or length */
|
unsigned short et_protlen; /* Protocol or length */
|
unsigned char et_dsap; /* 802 DSAP */
|
unsigned char et_dsap; /* 802 DSAP */
|
unsigned char et_ssap; /* 802 SSAP */
|
unsigned char et_ssap; /* 802 SSAP */
|
unsigned char et_ctl; /* 802 control */
|
unsigned char et_ctl; /* 802 control */
|
unsigned char et_snap1; /* SNAP */
|
unsigned char et_snap1; /* SNAP */
|
unsigned char et_snap2;
|
unsigned char et_snap2;
|
unsigned char et_snap3;
|
unsigned char et_snap3;
|
unsigned short et_prot; /* 802 protocol */
|
unsigned short et_prot; /* 802 protocol */
|
} Ethernet_t;
|
} Ethernet_t;
|
|
|
#define ETHER_HDR_SIZE 14 /* Ethernet header size */
|
#define ETHER_HDR_SIZE 14 /* Ethernet header size */
|
#define E802_HDR_SIZE 22 /* 802 ethernet header size */
|
#define E802_HDR_SIZE 22 /* 802 ethernet header size */
|
#define PROT_IP 0x0800 /* IP protocol */
|
#define PROT_IP 0x0800 /* IP protocol */
|
#define PROT_ARP 0x0806 /* IP ARP protocol */
|
#define PROT_ARP 0x0806 /* IP ARP protocol */
|
#define PROT_RARP 0x8035 /* IP ARP protocol */
|
#define PROT_RARP 0x8035 /* IP ARP protocol */
|
|
|
|
|
/*
|
/*
|
* Internet Protocol (IP) header.
|
* Internet Protocol (IP) header.
|
*/
|
*/
|
typedef struct {
|
typedef struct {
|
unsigned char ip_hl_v; /* header length and version*/
|
unsigned char ip_hl_v; /* header length and version*/
|
unsigned char ip_tos; /* type of service */
|
unsigned char ip_tos; /* type of service */
|
unsigned short ip_len; /* total length */
|
unsigned short ip_len; /* total length */
|
unsigned short ip_id; /* identification */
|
unsigned short ip_id; /* identification */
|
unsigned short ip_off; /* fragment offset field */
|
unsigned short ip_off; /* fragment offset field */
|
unsigned char ip_ttl; /* time to live */
|
unsigned char ip_ttl; /* time to live */
|
unsigned char ip_p; /* protocol */
|
unsigned char ip_p; /* protocol */
|
unsigned short ip_sum; /* checksum */
|
unsigned short ip_sum; /* checksum */
|
IPaddr_t ip_src; /* Source IP address */
|
IPaddr_t ip_src; /* Source IP address */
|
IPaddr_t ip_dst; /* Destination IP address */
|
IPaddr_t ip_dst; /* Destination IP address */
|
unsigned short udp_src; /* UDP source port */
|
unsigned short udp_src; /* UDP source port */
|
unsigned short udp_dst; /* UDP destination port */
|
unsigned short udp_dst; /* UDP destination port */
|
unsigned short udp_len; /* Length of UDP packet */
|
unsigned short udp_len; /* Length of UDP packet */
|
unsigned short udp_xsum; /* Checksum */
|
unsigned short udp_xsum; /* Checksum */
|
} IP_t;
|
} IP_t;
|
|
|
#define IP_HDR_SIZE_NO_UDP (sizeof (IP_t) - 8)
|
#define IP_HDR_SIZE_NO_UDP (sizeof (IP_t) - 8)
|
#define IP_HDR_SIZE (sizeof (IP_t))
|
#define IP_HDR_SIZE (sizeof (IP_t))
|
|
|
#define IPPROTO_ICMP 1 /* Internet Control Message Protocol */
|
#define IPPROTO_ICMP 1 /* Internet Control Message Protocol */
|
#define IPPROTO_UDP 17 /* User Datagram Protocol */
|
#define IPPROTO_UDP 17 /* User Datagram Protocol */
|
|
|
|
|
/*
|
/*
|
* ICMP stuff (just enough to handle (host) redirect messages)
|
* ICMP stuff (just enough to handle (host) redirect messages)
|
*/
|
*/
|
#define ICMP_REDIRECT 5 /* Redirect (change route) */
|
#define ICMP_REDIRECT 5 /* Redirect (change route) */
|
|
|
/* Codes for REDIRECT. */
|
/* Codes for REDIRECT. */
|
#define ICMP_REDIR_NET 0 /* Redirect Net */
|
#define ICMP_REDIR_NET 0 /* Redirect Net */
|
#define ICMP_REDIR_HOST 1 /* Redirect Host */
|
#define ICMP_REDIR_HOST 1 /* Redirect Host */
|
|
|
#define ICMP_TYPE_ECHO_REPLY 0x00
|
#define ICMP_TYPE_ECHO_REPLY 0x00
|
#define ICMP_TYPE_ECHO_REQ 0x08
|
#define ICMP_TYPE_ECHO_REQ 0x08
|
|
|
unsigned char ip_reply_packet[0x600] __attribute__ ((aligned (4))); // Save space for a full ICMP reply packet
|
unsigned char ip_reply_packet[0x600] __attribute__ ((aligned (4))); // Save space for a full ICMP reply packet
|
|
|
typedef struct {
|
typedef struct {
|
unsigned char type;
|
unsigned char type;
|
unsigned char code;
|
unsigned char code;
|
unsigned short checksum;
|
unsigned short checksum;
|
union {
|
union {
|
struct {
|
struct {
|
unsigned short id;
|
unsigned short id;
|
unsigned short sequence;
|
unsigned short sequence;
|
} echo;
|
} echo;
|
unsigned long gateway;
|
unsigned long gateway;
|
struct {
|
struct {
|
unsigned short __unused;
|
unsigned short __unused;
|
unsigned short mtu;
|
unsigned short mtu;
|
} frag;
|
} frag;
|
} un;
|
} un;
|
} ICMP_t;
|
} ICMP_t;
|
|
|
// From http://lkml.indiana.edu/hypermail/linux/kernel/9612.3/0060.html
|
// From http://lkml.indiana.edu/hypermail/linux/kernel/9612.3/0060.html
|
unsigned short calculate_checksum(char* dats, unsigned int len)
|
unsigned short calculate_checksum(char* dats, unsigned int len)
|
{
|
{
|
unsigned int itr;
|
unsigned int itr;
|
unsigned long accum = 0;
|
unsigned long accum = 0;
|
unsigned long longsum;
|
unsigned long longsum;
|
|
|
// Sum all pairs of data
|
// Sum all pairs of data
|
for(itr=0;itr<(len & ~0x1);itr+=2)
|
for(itr=0;itr<(len & ~0x1);itr+=2)
|
accum += (unsigned long)(((dats[itr]<<8)&0xff00)|(dats[itr+1]&0x00ff));
|
accum += (unsigned long)(((dats[itr]<<8)&0xff00)|(dats[itr+1]&0x00ff));
|
|
|
if (len & 0x1) // Do leftover
|
if (len & 0x1) // Do leftover
|
accum += (unsigned long) ((dats[itr-1]<<8)&0xff00);
|
accum += (unsigned long) ((dats[itr-1]<<8)&0xff00);
|
|
|
longsum = (unsigned long) (accum & 0xffff);
|
longsum = (unsigned long) (accum & 0xffff);
|
longsum += (unsigned long) (accum >> 16); // Sum the carries
|
longsum += (unsigned long) (accum >> 16); // Sum the carries
|
longsum += (longsum >> 16);
|
longsum += (longsum >> 16);
|
return (unsigned short)((longsum ^ 0xffff) & 0xffff);
|
return (unsigned short)((longsum ^ 0xffff) & 0xffff);
|
|
|
}
|
}
|
|
|
void
|
void
|
packet_check_icmp_header(void * pkt)
|
packet_check_icmp_header(void * pkt)
|
{
|
{
|
Ethernet_t * eth_pkt;
|
Ethernet_t * eth_pkt;
|
IP_t * ip;
|
IP_t * ip;
|
ICMP_t * icmp;
|
ICMP_t * icmp;
|
|
|
unsigned int zero = 0;
|
unsigned int zero = 0;
|
|
|
eth_pkt = (Ethernet_t *) pkt;
|
eth_pkt = (Ethernet_t *) pkt;
|
|
|
// Check it's for our MAC
|
// Check it's for our MAC
|
char* eth_pkt_dst_mac = (char*) eth_pkt;
|
char* eth_pkt_dst_mac = (char*) eth_pkt;
|
if (!(
|
if (!(
|
((eth_pkt_dst_mac[0] == (char) ETH_MACADDR0) && // Either our MAC
|
((eth_pkt_dst_mac[0] == (char) ETH_MACADDR0) && // Either our MAC
|
(eth_pkt_dst_mac[1] == (char) ETH_MACADDR1) &&
|
(eth_pkt_dst_mac[1] == (char) ETH_MACADDR1) &&
|
(eth_pkt_dst_mac[2] == (char) ETH_MACADDR2) &&
|
(eth_pkt_dst_mac[2] == (char) ETH_MACADDR2) &&
|
(eth_pkt_dst_mac[3] == (char) ETH_MACADDR3) &&
|
(eth_pkt_dst_mac[3] == (char) ETH_MACADDR3) &&
|
(eth_pkt_dst_mac[4] == (char) ETH_MACADDR4) &&
|
(eth_pkt_dst_mac[4] == (char) ETH_MACADDR4) &&
|
(eth_pkt_dst_mac[5] == (char) ETH_MACADDR5)) ||
|
(eth_pkt_dst_mac[5] == (char) ETH_MACADDR5)) ||
|
((eth_pkt_dst_mac[0] == (char) 0xff) && // or broadcast MAC
|
((eth_pkt_dst_mac[0] == (char) 0xff) && // or broadcast MAC
|
(eth_pkt_dst_mac[1] == (char) 0xff) &&
|
(eth_pkt_dst_mac[1] == (char) 0xff) &&
|
(eth_pkt_dst_mac[2] == (char) 0xff) &&
|
(eth_pkt_dst_mac[2] == (char) 0xff) &&
|
(eth_pkt_dst_mac[3] == (char) 0xff) &&
|
(eth_pkt_dst_mac[3] == (char) 0xff) &&
|
(eth_pkt_dst_mac[4] == (char) 0xff) &&
|
(eth_pkt_dst_mac[4] == (char) 0xff) &&
|
(eth_pkt_dst_mac[5] == (char) 0xff))
|
(eth_pkt_dst_mac[5] == (char) 0xff))
|
)
|
)
|
)
|
)
|
|
|
return ;
|
return ;
|
|
|
// Check it's an IP packet
|
// Check it's an IP packet
|
if (!(eth_pkt->et_protlen == PROT_IP))
|
if (!(eth_pkt->et_protlen == PROT_IP))
|
return ;
|
return ;
|
|
|
pkt += ETHER_HDR_SIZE; // Skip eth header stuff
|
pkt += ETHER_HDR_SIZE; // Skip eth header stuff
|
|
|
ip = (IP_t*) pkt;
|
ip = (IP_t*) pkt;
|
|
|
// Check if this is an ICMP packet
|
// Check if this is an ICMP packet
|
if (!(ip->ip_p == IPPROTO_ICMP))
|
if (!(ip->ip_p == IPPROTO_ICMP))
|
return ;
|
return ;
|
|
|
// Check if this is for our IP, get pointer to the DST IP part of IP header
|
// Check if this is for our IP, get pointer to the DST IP part of IP header
|
// which is end of IP section - 4 bytes
|
// which is end of IP section - 4 bytes
|
char * internet_protocol_adr = ((unsigned char*)ip + (IP_HDR_SIZE_NO_UDP-4));
|
char * internet_protocol_adr = ((unsigned char*)ip + (IP_HDR_SIZE_NO_UDP-4));
|
|
|
if (!((internet_protocol_adr[0] == our_ip[0]) &&
|
if (!((internet_protocol_adr[0] == our_ip[0]) &&
|
(internet_protocol_adr[1] == our_ip[1]) &&
|
(internet_protocol_adr[1] == our_ip[1]) &&
|
(internet_protocol_adr[2] == our_ip[2]) &&
|
(internet_protocol_adr[2] == our_ip[2]) &&
|
(internet_protocol_adr[3] == our_ip[3])))
|
(internet_protocol_adr[3] == our_ip[3])))
|
return ;
|
return ;
|
|
|
pkt += IP_HDR_SIZE_NO_UDP;
|
pkt += IP_HDR_SIZE_NO_UDP;
|
|
|
icmp = (ICMP_t*) pkt;
|
icmp = (ICMP_t*) pkt;
|
|
|
// Currently we only support replying to echo (ping) requests
|
// Currently we only support replying to echo (ping) requests
|
|
|
// Check for ICMP echo request type
|
// Check for ICMP echo request type
|
if (!(icmp->type == ICMP_TYPE_ECHO_REQ))
|
if (!(icmp->type == ICMP_TYPE_ECHO_REQ))
|
return;
|
return;
|
|
|
// Skip forward to the target I.P address
|
// Skip forward to the target I.P address
|
if (packet_inspect_debug)
|
if (packet_inspect_debug)
|
printf("Ping packet\n");
|
printf("Ping packet\n");
|
|
|
// Go ahead and construct a response packet
|
// Go ahead and construct a response packet
|
// Setup pointers
|
// Setup pointers
|
Ethernet_t * reply_pkt = (Ethernet_t *) &ip_reply_packet[0];
|
Ethernet_t * reply_pkt = (Ethernet_t *) &ip_reply_packet[0];
|
IP_t * reply_IP = (IP_t*) &ip_reply_packet[ETHER_HDR_SIZE];
|
IP_t * reply_IP = (IP_t*) &ip_reply_packet[ETHER_HDR_SIZE];
|
ICMP_t * reply_ICMP = (ICMP_t*) &ip_reply_packet[ETHER_HDR_SIZE+
|
ICMP_t * reply_ICMP = (ICMP_t*) &ip_reply_packet[ETHER_HDR_SIZE+
|
IP_HDR_SIZE_NO_UDP];
|
IP_HDR_SIZE_NO_UDP];
|
// Setup Ethernet header
|
// Setup Ethernet header
|
// Copy source MAC to destination MAC
|
// Copy source MAC to destination MAC
|
memcpy( (void*)&reply_pkt->et_dest , (void*)ð_pkt->et_src , 6);
|
memcpy( (void*)&reply_pkt->et_dest , (void*)ð_pkt->et_src , 6);
|
reply_pkt->et_src[0] = ETH_MACADDR0;
|
reply_pkt->et_src[0] = ETH_MACADDR0;
|
reply_pkt->et_src[1] = ETH_MACADDR1;
|
reply_pkt->et_src[1] = ETH_MACADDR1;
|
reply_pkt->et_src[2] = ETH_MACADDR2;
|
reply_pkt->et_src[2] = ETH_MACADDR2;
|
reply_pkt->et_src[3] = ETH_MACADDR3;
|
reply_pkt->et_src[3] = ETH_MACADDR3;
|
reply_pkt->et_src[4] = ETH_MACADDR4;
|
reply_pkt->et_src[4] = ETH_MACADDR4;
|
reply_pkt->et_src[5] = ETH_MACADDR5;
|
reply_pkt->et_src[5] = ETH_MACADDR5;
|
reply_pkt->et_protlen = PROT_IP;
|
reply_pkt->et_protlen = PROT_IP;
|
|
|
// IP header
|
// IP header
|
reply_IP->ip_hl_v = 0x45; // version 4, 20 byte long header, not 100% on this!
|
reply_IP->ip_hl_v = 0x45; // version 4, 20 byte long header, not 100% on this!
|
reply_IP->ip_tos = 0x00 ; // ToS (DSCP) - usually used for QoS, set to 0
|
reply_IP->ip_tos = 0x00 ; // ToS (DSCP) - usually used for QoS, set to 0
|
unsigned short ip_indicated_length;
|
unsigned short ip_indicated_length;
|
// First copy total length indicated in received IP header to a variable, we
|
// First copy total length indicated in received IP header to a variable, we
|
// need it again later...
|
// need it again later...
|
memcpy ((void*)&ip_indicated_length, (void*)&ip->ip_len, 2);
|
memcpy ((void*)&ip_indicated_length, (void*)&ip->ip_len, 2);
|
// Now copy into reply IP packet
|
// Now copy into reply IP packet
|
memcpy ((void*)&reply_IP->ip_len, (void*)&ip_indicated_length, 2);
|
memcpy ((void*)&reply_IP->ip_len, (void*)&ip_indicated_length, 2);
|
memcpy ((void*)&reply_IP->ip_id, (void*)&ip->ip_id, 2); // Copy ID
|
memcpy ((void*)&reply_IP->ip_id, (void*)&ip->ip_id, 2); // Copy ID
|
reply_IP->ip_ttl = 0x40; // Packet TTL - 64, typical value
|
reply_IP->ip_ttl = 0x40; // Packet TTL - 64, typical value
|
reply_IP->ip_p = IPPROTO_ICMP; // Duh, this is an ICMP echo reply
|
reply_IP->ip_p = IPPROTO_ICMP; // Duh, this is an ICMP echo reply
|
// Clear header checksum for now
|
// Clear header checksum for now
|
|
|
memcpy ((void*)&reply_IP->ip_sum, (void*)&zero, 2);
|
memcpy ((void*)&reply_IP->ip_sum, (void*)&zero, 2);
|
memcpy ((void*)&reply_IP->ip_src, (void*)&our_ip[0], 4); // Copy in our IP
|
memcpy ((void*)&reply_IP->ip_src, (void*)&our_ip[0], 4); // Copy in our IP
|
// "...return to sender... budupbadah address ....KNOWN ..."
|
// "...return to sender... budupbadah address ....KNOWN ..."
|
// WTF this memcpy() fails with alignment error...(?!?!)
|
// WTF this memcpy() fails with alignment error...(?!?!)
|
//memcpy (&reply_IP->ip_dst, &ip->ip_src, sizeof(IPaddr_t));
|
//memcpy (&reply_IP->ip_dst, &ip->ip_src, sizeof(IPaddr_t));
|
//...OK then, do it manually.....
|
//...OK then, do it manually.....
|
unsigned char *ptr1, *ptr2;
|
unsigned char *ptr1, *ptr2;
|
ptr1 = &reply_IP->ip_dst; ptr2 = &ip->ip_src;
|
ptr1 = &reply_IP->ip_dst; ptr2 = &ip->ip_src;
|
ptr1[0] = ptr2[0];
|
ptr1[0] = ptr2[0];
|
ptr1[1] = ptr2[1];
|
ptr1[1] = ptr2[1];
|
ptr1[2] = ptr2[2];
|
ptr1[2] = ptr2[2];
|
ptr1[3] = ptr2[3];
|
ptr1[3] = ptr2[3];
|
|
|
// Now calculate the CRC, probably move this to a fuction....
|
// Now calculate the CRC, probably move this to a fuction....
|
unsigned short ip_sum = 0; // Initialise checksum value to 0
|
unsigned short ip_sum = 0; // Initialise checksum value to 0
|
int itr;
|
int itr;
|
char* sum_data_ptr = (char*)reply_IP;
|
char* sum_data_ptr = (char*)reply_IP;
|
ip_sum = calculate_checksum(sum_data_ptr,IP_HDR_SIZE_NO_UDP);
|
ip_sum = calculate_checksum(sum_data_ptr,IP_HDR_SIZE_NO_UDP);
|
/*
|
/*
|
for(itr=0;itr<IP_HDR_SIZE_NO_UDP;itr+=2)
|
for(itr=0;itr<IP_HDR_SIZE_NO_UDP;itr+=2)
|
ip_sum += (((sum_data_ptr[itr]<<8)&0xff00)|(sum_data_ptr[itr+1]&0x00ff));
|
ip_sum += (((sum_data_ptr[itr]<<8)&0xff00)|(sum_data_ptr[itr+1]&0x00ff));
|
while (ip_sum>>16)
|
while (ip_sum>>16)
|
ip_sum = (ip_sum & 0xffff) + (ip_sum>>16);
|
ip_sum = (ip_sum & 0xffff) + (ip_sum>>16);
|
ip_sum = ~ip_sum;
|
ip_sum = ~ip_sum;
|
*/
|
*/
|
|
|
memcpy ((void*)&reply_IP->ip_sum, (void*)&ip_sum, 2);
|
memcpy ((void*)&reply_IP->ip_sum, (void*)&ip_sum, 2);
|
|
|
//
|
//
|
// Now construct ICMP part of packet
|
// Now construct ICMP part of packet
|
//
|
//
|
reply_ICMP->type = ICMP_TYPE_ECHO_REPLY; // ping response type
|
reply_ICMP->type = ICMP_TYPE_ECHO_REPLY; // ping response type
|
reply_ICMP->code = icmp->code; // ICMP code same as sender (is this right?)
|
reply_ICMP->code = icmp->code; // ICMP code same as sender (is this right?)
|
|
|
// Clear ICMP checksum for now
|
// Clear ICMP checksum for now
|
memcpy ((void*)&reply_ICMP->checksum, (void*)&zero, 2);
|
memcpy ((void*)&reply_ICMP->checksum, (void*)&zero, 2);
|
|
|
//
|
//
|
// Simply copy in the data from the received packet
|
// Simply copy in the data from the received packet
|
// Figure out how much there is after the checksum
|
// Figure out how much there is after the checksum
|
// It should be :
|
// It should be :
|
// length_from_received_IP_header - IP_header_length - initial_ICMP_packet_dat
|
// length_from_received_IP_header - IP_header_length - initial_ICMP_packet_dat
|
//
|
//
|
unsigned long icmp_data_length = ip_indicated_length - IP_HDR_SIZE_NO_UDP - 4;
|
unsigned long icmp_data_length = ip_indicated_length - IP_HDR_SIZE_NO_UDP - 4;
|
memcpy ((void*)&reply_ICMP->un,(void*)&icmp->un, icmp_data_length);
|
memcpy ((void*)&reply_ICMP->un,(void*)&icmp->un, icmp_data_length);
|
|
|
// Now calculate checksum for ICMP data
|
// Now calculate checksum for ICMP data
|
unsigned short icmp_sum = 0;
|
unsigned short icmp_sum = 0;
|
sum_data_ptr = (char*)reply_ICMP;
|
sum_data_ptr = (char*)reply_ICMP;
|
icmp_sum = calculate_checksum(sum_data_ptr,icmp_data_length+4);
|
icmp_sum = calculate_checksum(sum_data_ptr,icmp_data_length+4);
|
|
|
memcpy ((void*)&reply_ICMP->checksum, (void*)&icmp_sum, 2);
|
memcpy ((void*)&reply_ICMP->checksum, (void*)&icmp_sum, 2);
|
|
|
// All done!
|
// All done!
|
|
|
tx_packet((void*)ip_reply_packet,ETHER_HDR_SIZE+ip_indicated_length);
|
tx_packet((void*)ip_reply_packet,ETHER_HDR_SIZE+ip_indicated_length);
|
|
|
}
|
}
|
|
|
|
|
|
|
/*
|
/*
|
* Address Resolution Protocol (ARP) header.
|
* Address Resolution Protocol (ARP) header.
|
*/
|
*/
|
typedef struct
|
typedef struct
|
{
|
{
|
unsigned short ar_hrd; /* Format of hardware address */
|
unsigned short ar_hrd; /* Format of hardware address */
|
# define ARP_ETHER 1 /* Ethernet hardware address */
|
# define ARP_ETHER 1 /* Ethernet hardware address */
|
unsigned short ar_pro; /* Format of protocol address */
|
unsigned short ar_pro; /* Format of protocol address */
|
unsigned char ar_hln; /* Length of hardware address */
|
unsigned char ar_hln; /* Length of hardware address */
|
unsigned char ar_pln; /* Length of protocol address */
|
unsigned char ar_pln; /* Length of protocol address */
|
unsigned short ar_op; /* Operation */
|
unsigned short ar_op; /* Operation */
|
# define ARPOP_REQUEST 1 /* Request to resolve address */
|
# define ARPOP_REQUEST 1 /* Request to resolve address */
|
# define ARPOP_REPLY 2 /* Response to previous request */
|
# define ARPOP_REPLY 2 /* Response to previous request */
|
|
|
# define RARPOP_REQUEST 3 /* Request to resolve address */
|
# define RARPOP_REQUEST 3 /* Request to resolve address */
|
# define RARPOP_REPLY 4 /* Response to previous request */
|
# define RARPOP_REPLY 4 /* Response to previous request */
|
|
|
/*
|
/*
|
* The remaining fields are variable in size, according to
|
* The remaining fields are variable in size, according to
|
* the sizes above, and are defined as appropriate for
|
* the sizes above, and are defined as appropriate for
|
* specific hardware/protocol combinations.
|
* specific hardware/protocol combinations.
|
*/
|
*/
|
unsigned char ar_data[0];
|
unsigned char ar_data[0];
|
#if 0
|
#if 0
|
unsigned char ar_sha[]; /* Sender hardware address */
|
unsigned char ar_sha[]; /* Sender hardware address */
|
unsigned char ar_spa[]; /* Sender protocol address */
|
unsigned char ar_spa[]; /* Sender protocol address */
|
unsigned char ar_tha[]; /* Target hardware address */
|
unsigned char ar_tha[]; /* Target hardware address */
|
unsigned char ar_tpa[]; /* Target protocol address */
|
unsigned char ar_tpa[]; /* Target protocol address */
|
#endif /* 0 */
|
#endif /* 0 */
|
} ARP_t;
|
} ARP_t;
|
|
|
#define ARP_HDR_SIZE (8+20) /* Size assuming ethernet */
|
#define ARP_HDR_SIZE (8+20) /* Size assuming ethernet */
|
|
|
char arp_reply_packet[(ETHER_HDR_SIZE + ARP_HDR_SIZE)];
|
char arp_reply_packet[(ETHER_HDR_SIZE + ARP_HDR_SIZE)];
|
|
|
void
|
void
|
packet_check_arp_header(void * pkt)
|
packet_check_arp_header(void * pkt)
|
{
|
{
|
Ethernet_t * eth_pkt;
|
Ethernet_t * eth_pkt;
|
|
|
ARP_t * arp;
|
ARP_t * arp;
|
|
|
//printf("packet_check_arp_header: pkt data at 0x%.8x\n",(unsigned long) pkt);
|
//printf("packet_check_arp_header: pkt data at 0x%.8x\n",(unsigned long) pkt);
|
eth_pkt = (Ethernet_t *) pkt;
|
eth_pkt = (Ethernet_t *) pkt;
|
|
|
if (eth_pkt->et_protlen == 0x0806)
|
if (eth_pkt->et_protlen == 0x0806)
|
{
|
{
|
// Is an ARP request
|
// Is an ARP request
|
// Check the IP
|
// Check the IP
|
pkt += ETHER_HDR_SIZE; // Skip eth header stuff
|
pkt += ETHER_HDR_SIZE; // Skip eth header stuff
|
//printf("Is ARP protocol\npkt header now at 0x%.8x\n",pkt);
|
//printf("Is ARP protocol\npkt header now at 0x%.8x\n",pkt);
|
|
|
arp = (ARP_t*) pkt;
|
arp = (ARP_t*) pkt;
|
|
|
if (arp->ar_hrd == ARP_ETHER && arp->ar_op == ARPOP_REQUEST)
|
if (arp->ar_hrd == ARP_ETHER && arp->ar_op == ARPOP_REQUEST)
|
{
|
{
|
// Skip forward to the target I.P address
|
// Skip forward to the target I.P address
|
if (packet_inspect_debug)
|
if (packet_inspect_debug)
|
printf("ARP packet\n");
|
printf("ARP packet\n");
|
|
|
char * internet_protocol_adr = (((unsigned long)&arp->ar_data[0]) +
|
char * internet_protocol_adr = (((unsigned long)&arp->ar_data[0]) +
|
(arp->ar_hln * 2) + (arp->ar_pln));
|
(arp->ar_hln * 2) + (arp->ar_pln));
|
|
|
//printf("Is ARP ethernet request\ncheck adr at 0x%.8x\n",
|
//printf("Is ARP ethernet request\ncheck adr at 0x%.8x\n",
|
// internet_protocol_adr);
|
// internet_protocol_adr);
|
if ((internet_protocol_adr[0] == our_ip[0]) &&
|
if ((internet_protocol_adr[0] == our_ip[0]) &&
|
(internet_protocol_adr[1] == our_ip[1]) &&
|
(internet_protocol_adr[1] == our_ip[1]) &&
|
(internet_protocol_adr[2] == our_ip[2]) &&
|
(internet_protocol_adr[2] == our_ip[2]) &&
|
(internet_protocol_adr[3] == our_ip[3]))
|
(internet_protocol_adr[3] == our_ip[3]))
|
{
|
{
|
//printf("Got valid ARP request\n");
|
//printf("Got valid ARP request\n");
|
// Send ARP reply
|
// Send ARP reply
|
|
|
Ethernet_t * reply_pkt = (Ethernet_t *)&arp_reply_packet[0];
|
Ethernet_t * reply_pkt = (Ethernet_t *)&arp_reply_packet[0];
|
ARP_t * reply_arp = (ARP_t*)&arp_reply_packet[ETHER_HDR_SIZE];
|
ARP_t * reply_arp = (ARP_t*)&arp_reply_packet[ETHER_HDR_SIZE];
|
memcpy( (void*)&reply_pkt->et_dest , (void*)ð_pkt->et_src , 6);
|
memcpy( (void*)&reply_pkt->et_dest , (void*)ð_pkt->et_src , 6);
|
reply_pkt->et_src[0] = ETH_MACADDR0;
|
reply_pkt->et_src[0] = ETH_MACADDR0;
|
reply_pkt->et_src[1] = ETH_MACADDR1;
|
reply_pkt->et_src[1] = ETH_MACADDR1;
|
reply_pkt->et_src[2] = ETH_MACADDR2;
|
reply_pkt->et_src[2] = ETH_MACADDR2;
|
reply_pkt->et_src[3] = ETH_MACADDR3;
|
reply_pkt->et_src[3] = ETH_MACADDR3;
|
reply_pkt->et_src[4] = ETH_MACADDR4;
|
reply_pkt->et_src[4] = ETH_MACADDR4;
|
reply_pkt->et_src[5] = ETH_MACADDR5;
|
reply_pkt->et_src[5] = ETH_MACADDR5;
|
reply_pkt->et_protlen = 0x0806;
|
reply_pkt->et_protlen = 0x0806;
|
// ARP part of packet
|
// ARP part of packet
|
reply_arp->ar_hrd = ARP_ETHER;
|
reply_arp->ar_hrd = ARP_ETHER;
|
reply_arp->ar_pro = 0x0800; // IP Protocol
|
reply_arp->ar_pro = 0x0800; // IP Protocol
|
reply_arp->ar_hln = 0x06;
|
reply_arp->ar_hln = 0x06;
|
reply_arp->ar_pln = 0x04;
|
reply_arp->ar_pln = 0x04;
|
reply_arp->ar_op = ARPOP_REPLY;
|
reply_arp->ar_op = ARPOP_REPLY;
|
// My MAC
|
// My MAC
|
memcpy( (void*)&reply_arp->ar_data[0] ,
|
memcpy( (void*)&reply_arp->ar_data[0] ,
|
(void*)&reply_pkt->et_src , 6);
|
(void*)&reply_pkt->et_src , 6);
|
// My IP
|
// My IP
|
memcpy( (void*)&reply_arp->ar_data[6] , (void*)&our_ip , 4);
|
memcpy( (void*)&reply_arp->ar_data[6] , (void*)&our_ip , 4);
|
// Their MAC
|
// Their MAC
|
memcpy( (void*)&reply_arp->ar_data[10] ,
|
memcpy( (void*)&reply_arp->ar_data[10] ,
|
(void*)ð_pkt->et_src , 6);
|
(void*)ð_pkt->et_src , 6);
|
// Their IP
|
// Their IP
|
char * their_internet_protocol_adr =
|
char * their_internet_protocol_adr =
|
(((unsigned long)&arp->ar_data[0]) + arp->ar_hln );
|
(((unsigned long)&arp->ar_data[0]) + arp->ar_hln );
|
memcpy( (void*)&reply_arp->ar_data[16] ,
|
memcpy( (void*)&reply_arp->ar_data[16] ,
|
(void*)&their_internet_protocol_adr[0] , 4);
|
(void*)&their_internet_protocol_adr[0] , 4);
|
|
|
tx_packet((void*)arp_reply_packet,(ETHER_HDR_SIZE+ARP_HDR_SIZE) );
|
tx_packet((void*)arp_reply_packet,(ETHER_HDR_SIZE+ARP_HDR_SIZE) );
|
|
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
|
|
|
|
static void
|
static void
|
oeth_rx(void)
|
oeth_rx(void)
|
{
|
{
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
volatile oeth_bd *rx_bdp;
|
volatile oeth_bd *rx_bdp;
|
int pkt_len, i;
|
int pkt_len, i;
|
int bad = 0;
|
int bad = 0;
|
|
|
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
|
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
|
|
|
if (print_packet_contents)
|
if (print_packet_contents)
|
printf("rx ");
|
printf("rx ");
|
|
|
/* Find RX buffers marked as having received data */
|
/* Find RX buffers marked as having received data */
|
for(i = 0; i < OETH_RXBD_NUM; i++)
|
for(i = 0; i < OETH_RXBD_NUM; i++)
|
{
|
{
|
/* Looking for NOT empty buffers desc. */
|
/* Looking for NOT empty buffers desc. */
|
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){
|
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){
|
/* Check status for errors.
|
/* Check status for errors.
|
*/
|
*/
|
if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG |
|
if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG |
|
OETH_RX_BD_SHORT)) {
|
OETH_RX_BD_SHORT)) {
|
bad = 1;
|
bad = 1;
|
}
|
}
|
if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) {
|
if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) {
|
bad = 1;
|
bad = 1;
|
}
|
}
|
if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) {
|
if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) {
|
bad = 1;
|
bad = 1;
|
}
|
}
|
if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) {
|
if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) {
|
bad = 1;
|
bad = 1;
|
}
|
}
|
if (rx_bdp[i].len_status & OETH_RX_BD_MISS) {
|
if (rx_bdp[i].len_status & OETH_RX_BD_MISS) {
|
|
|
}
|
}
|
if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) {
|
if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) {
|
bad = 1;
|
bad = 1;
|
}
|
}
|
|
|
if (bad) {
|
if (bad) {
|
printf("RXE: 0x%x\n",rx_bdp[i].len_status &
|
printf("RXE: 0x%x\n",rx_bdp[i].len_status &
|
OETH_RX_BD_STATS);
|
OETH_RX_BD_STATS);
|
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
|
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
|
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
|
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
|
|
|
|
if (print_packet_contents)
|
|
{
|
|
oeth_print_packet(i, rx_bdp[i].addr,
|
|
rx_bdp[i].len_status
|
|
>> 16);
|
|
printf("\t end of packet\n\n");
|
|
}
|
|
|
bad = 0;
|
bad = 0;
|
continue;
|
continue;
|
}
|
}
|
else {
|
else {
|
|
|
/* Process the incoming frame.
|
/* Process the incoming frame.
|
*/
|
*/
|
pkt_len = rx_bdp[i].len_status >> 16;
|
pkt_len = rx_bdp[i].len_status >> 16;
|
|
|
/* Do something here with the data - copy it
|
/* Do something here with the data - copy it
|
into userspace, perhaps. */
|
into userspace, perhaps. */
|
// See if it's an ARP packet
|
// See if it's an ARP packet
|
packet_check_arp_header((void*)rx_bdp[i].addr);
|
packet_check_arp_header((void*)rx_bdp[i].addr);
|
// See if it's an ICMP echo request
|
// See if it's an ICMP echo request
|
packet_check_icmp_header((void*)rx_bdp[i].addr);
|
packet_check_icmp_header((void*)rx_bdp[i].addr);
|
if (print_packet_contents)
|
if (print_packet_contents)
|
{
|
{
|
oeth_print_packet(i, rx_bdp[i].addr,
|
oeth_print_packet(i, rx_bdp[i].addr,
|
rx_bdp[i].len_status
|
rx_bdp[i].len_status
|
>> 16);
|
>> 16);
|
printf("\t end of packet\n\n");
|
printf("\t end of packet\n\n");
|
}
|
}
|
/* finish up */
|
/* finish up */
|
/* Clear stats */
|
/* Clear stats */
|
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
|
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
|
/* Mark RX BD as empty */
|
/* Mark RX BD as empty */
|
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
|
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
|
|
|
oeth_transmit_pause(); //try this!
|
oeth_transmit_pause(); //try this!
|
|
|
|
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
|
|
|
|
static void
|
static void
|
oeth_tx(void)
|
oeth_tx(void)
|
{
|
{
|
volatile oeth_bd *tx_bd;
|
volatile oeth_bd *tx_bd;
|
int i;
|
int i;
|
if (print_packet_contents)
|
if (print_packet_contents)
|
printf("tx");
|
printf("tx");
|
|
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
|
|
|
/* Go through the TX buffs, search for one that was just sent */
|
/* Go through the TX buffs, search for one that was just sent */
|
for(i = 0; i < OETH_TXBD_NUM; i++)
|
for(i = 0; i < OETH_TXBD_NUM; i++)
|
{
|
{
|
/* Looking for buffer NOT ready for transmit. and IRQ enabled */
|
/* Looking for buffer NOT ready for transmit. and IRQ enabled */
|
if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) &&
|
if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) &&
|
(tx_bd[i].len_status & (OETH_TX_BD_IRQ)) )
|
(tx_bd[i].len_status & (OETH_TX_BD_IRQ)) )
|
{
|
{
|
/* Single threaded so no chance we have detected a
|
/* Single threaded so no chance we have detected a
|
buffer that has had its IRQ bit set but not its
|
buffer that has had its IRQ bit set but not its
|
BD_READ flag. Maybe this won't work in linux */
|
BD_READ flag. Maybe this won't work in linux */
|
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ;
|
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ;
|
|
|
/* Probably good to check for TX errors here */
|
/* Probably good to check for TX errors here */
|
// Check if either carrier sense lost or colission
|
// Check if either carrier sense lost or colission
|
// indicated
|
// indicated
|
if (tx_bd[i].len_status & OETH_TX_BD_STATS)
|
if (tx_bd[i].len_status & OETH_TX_BD_STATS)
|
printf("TXER: 0x%x\n",
|
printf("TXER: 0x%x\n",
|
(tx_bd[i].len_status &OETH_TX_BD_STATS));
|
(tx_bd[i].len_status &OETH_TX_BD_STATS));
|
|
|
if (print_packet_contents)
|
if (print_packet_contents)
|
printf("T%d",i);
|
printf("T%d\n",i);
|
}
|
}
|
}
|
}
|
return;
|
return;
|
}
|
}
|
|
|
|
|
int main ()
|
int main ()
|
{
|
{
|
|
|
print_packet_contents = 0; // Default to not printing packet contents.
|
print_packet_contents = 0; // Default to not printing packet contents.
|
packet_inspect_debug = 0;
|
packet_inspect_debug = 0;
|
print_ethmac_debug_reg = 0;
|
print_ethmac_debug_reg = 0;
|
|
|
/* Initialise vector handler */
|
/* Initialise vector handler */
|
int_init();
|
int_init();
|
|
|
/* Install ethernet interrupt handler, it is enabled here too */
|
/* Install ethernet interrupt handler, it is enabled here too */
|
int_add(ETH0_IRQ, oeth_interrupt, 0);
|
int_add(ETH0_IRQ, oeth_interrupt, 0);
|
|
|
/* Enable interrupts */
|
/* Enable interrupts */
|
cpu_enable_user_interrupts();
|
cpu_enable_user_interrupts();
|
|
|
last_char=0; /* Variable init for spin_cursor() */
|
last_char=0; /* Variable init for spin_cursor() */
|
next_tx_buf_num = 4; /* init for tx buffer counter */
|
next_tx_buf_num = 4; /* init for tx buffer counter */
|
|
|
uart_init(DEFAULT_UART); // init the UART before we can printf
|
uart_init(DEFAULT_UART); // init the UART before we can printf
|
printf("\n\teth ping program\n\n");
|
printf("\n\teth ping program\n\n");
|
printf("\n\tboard IP: %d.%d.%d.%d\n",our_ip[0]&0xff,our_ip[1]&0xff,
|
printf("\n\tboard IP: %d.%d.%d.%d\n",our_ip[0]&0xff,our_ip[1]&0xff,
|
our_ip[2]&0xff,our_ip[3]&0xff);
|
our_ip[2]&0xff,our_ip[3]&0xff);
|
|
|
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in
|
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in
|
MODER */
|
MODER */
|
|
|
//scan_ethphys(); /* Scan MIIM bus for PHYs */
|
//scan_ethphys(); /* Scan MIIM bus for PHYs */
|
//ethphy_init(); /* Attempt reset and configuration of PHY via MIIM */
|
//ethphy_init(); /* Attempt reset and configuration of PHY via MIIM */
|
//ethmac_scanstatus(); /* Enable scanning of status register via MIIM */
|
//ethmac_scanstatus(); /* Enable scanning of status register via MIIM */
|
|
|
/* Loop, monitoring user input from TTY */
|
/* Loop, monitoring user input from TTY */
|
while(1)
|
while(1)
|
{
|
{
|
char c;
|
char c;
|
|
|
while(!uart_check_for_char(DEFAULT_UART))
|
while(!uart_check_for_char(DEFAULT_UART))
|
{
|
{
|
|
|
spin_cursor();
|
spin_cursor();
|
|
|
if (print_ethmac_debug_reg)
|
if (print_ethmac_debug_reg)
|
oeth_print_wbdebug();
|
oeth_print_wbdebug();
|
}
|
}
|
|
|
c = uart_getc(DEFAULT_UART);
|
c = uart_getc(DEFAULT_UART);
|
|
|
if (c == 's')
|
if (c == 's')
|
tx_packet((void*) ping_packet, 98);
|
tx_packet((void*) ping_packet, 98);
|
else if (c == 'S')
|
else if (c == 'S')
|
tx_packet((void*)big_ping_packet, 1514);
|
tx_packet((void*)big_ping_packet, 1514);
|
else if (c == 'h')
|
else if (c == 'h')
|
scan_ethphys();
|
scan_ethphys();
|
else if (c == 'i')
|
else if (c == 'i')
|
ethphy_init();
|
ethphy_init();
|
else if (c == 'c')
|
else if (c == 'c')
|
oeth_ctrlmode_switch();
|
oeth_ctrlmode_switch();
|
else if (c == 'P')
|
else if (c == 'P')
|
{
|
{
|
print_packet_contents = print_packet_contents ? 0 : 1;
|
print_packet_contents = print_packet_contents ? 0 : 1;
|
if (print_packet_contents)
|
if (print_packet_contents)
|
printf("Enabling packet dumping\n");
|
printf("Enabling packet dumping\n");
|
else
|
else
|
printf("Packet dumping disabled\n");
|
printf("Packet dumping disabled\n");
|
}
|
}
|
else if (c == 'p')
|
else if (c == 'p')
|
oeth_printregs();
|
oeth_printregs();
|
else if (c == '0')
|
else if (c == 'a')
|
scan_ethphy(0);
|
ethphy_print_status(ethphy_found);
|
else if (c == '1')
|
else if (c >= '0' && c <= '9')
|
scan_ethphy(1);
|
scan_ethphy(c - 0x30);
|
else if (c == '7')
|
|
{
|
|
//scan_ethphy(7);
|
|
//ethphy_print_status(7);
|
|
printf("ext_sr 0x%x\n",eth_mii_read(0x7, 0x1b));
|
|
}
|
|
else if (c == 'r')
|
else if (c == 'r')
|
{
|
{
|
ethphy_reset(7);
|
ethphy_reset(ethphy_found);
|
printf("PHY reset\n");
|
printf("PHY reset\n");
|
}
|
}
|
else if (c == 'R')
|
else if (c == 'R')
|
{
|
{
|
//oeth_reset_tx_bd_pointer();
|
//oeth_reset_tx_bd_pointer();
|
ethmac_setup();
|
ethmac_setup();
|
printf("MAC reset\n");
|
printf("MAC reset\n");
|
}
|
}
|
else if (c == 'n')
|
else if (c == 'n')
|
ethphy_reneg(7);
|
ethphy_reneg(ethphy_found);
|
else if (c == 'N')
|
else if (c == 'N')
|
ethphy_set_autoneg(7);
|
ethphy_toggle_autoneg(ethphy_found);
|
else if (c == 'm')
|
else if (c == 'm')
|
ethmac_togglehugen();
|
ethmac_togglehugen();
|
else if (c == 't')
|
else if (c == 't')
|
ethphy_set_10mbit(0);
|
ethphy_set_10mbit(ethphy_found);
|
else if (c == 'w')
|
else if (c == 'H')
|
{
|
ethphy_set_100mbit(ethphy_found);
|
// Play with HWCFG mode of Alaska 88e1111 Phy
|
|
c = uart_getc(DEFAULT_UART);
|
|
short newvalue;
|
|
// c is an ascii char, let's convert it to actual hex
|
|
// value
|
|
if (c >= 'A' && c <= 'F')
|
|
newvalue = c - (65 - 10);
|
|
else if (c >= 'a' && c <= 'f')
|
|
newvalue = c - (99 - 10);
|
|
else if (c >= '0' && c <= '9')
|
|
newvalue = c - 48;
|
|
|
|
// Take this value and or it into the bottom bit
|
|
// (supposedly ext_sr)
|
|
#define MII_M1111_PHY_EXT_SR 0x1b
|
|
short ext_sr;
|
|
ext_sr = eth_mii_read(0x7, MII_M1111_PHY_EXT_SR);
|
|
#define MII_M1111_HWCFG_MODE_MASK 0xf
|
|
ext_sr &= ~MII_M1111_HWCFG_MODE_MASK;
|
|
ext_sr |= (short) newvalue;
|
|
eth_mii_write(0x7, MII_M1111_PHY_EXT_SR, ext_sr);
|
|
printf("ext_sr updated to - 0x%x\n",
|
|
eth_mii_read(0x7, MII_M1111_PHY_EXT_SR));
|
|
}
|
|
else if ( c == 'b' )
|
else if ( c == 'b' )
|
{
|
{
|
printf("\n\t---\n");
|
printf("\n\t---\n");
|
oeth_dump_bds();
|
oeth_dump_bds();
|
printf("\t---\n");
|
printf("\t---\n");
|
}
|
}
|
|
|
else if ( c == 'B' )
|
else if ( c == 'B' )
|
{
|
{
|
tx_packet((void*) broadcast_ping_packet, 298);
|
tx_packet((void*) broadcast_ping_packet, 298);
|
}
|
}
|
else if (c == 'u' )
|
else if (c == 'u' )
|
oeth_transmit_pause();
|
oeth_transmit_pause();
|
else if (c == 'd' )
|
else if (c == 'd' )
|
{
|
{
|
oeth_print_wbdebug();
|
oeth_print_wbdebug();
|
print_ethmac_debug_reg = !print_ethmac_debug_reg;
|
print_ethmac_debug_reg = !print_ethmac_debug_reg;
|
}
|
}
|
|
else if (c == 'D')
|
|
{
|
|
marvell_phy_toggle_delay();
|
|
}
|
else if (c == 'v' )
|
else if (c == 'v' )
|
{
|
{
|
if (packet_inspect_debug)
|
if (packet_inspect_debug)
|
printf("Disabling ");
|
printf("Disabling ");
|
else
|
else
|
printf("Enabling ");
|
printf("Enabling ");
|
|
|
printf("packet type announcments\n");
|
printf("packet type announcments\n");
|
|
|
packet_inspect_debug = !packet_inspect_debug;
|
packet_inspect_debug = !packet_inspect_debug;
|
}
|
}
|
else if ( c == 'o' )
|
else if ( c == 'o' )
|
oeth_toggle_promiscuous();
|
oeth_toggle_promiscuous();
|
|
else if (c == 'L')
|
|
ethphy_toggle_loopback();
|
|
else if (c == 'g')
|
|
ethphy_toggle_gigadvertise();
|
|
|
}
|
}
|
|
|
}
|
}
|
|
|