Files

230 lines
5.6 KiB
C

/*
* rtl8150.c- Sigmastar
*
* Copyright (C) 2018 Sigmastar Technology Corp.
*
* Author: jiang.ann <jiang.ann@sigmastar.com.tw>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <common.h>
#include <net.h>
#include "usb.h"
#include "usb_lan.h"
#define IDR 0x0120
#define MAR 0x0126
#define CR 0x012e
#define TCR 0x012f
#define RCR 0x0130
#define TSR 0x0132
#define RSR 0x0133
#define CON0 0x0135
#define CON1 0x0136
#define MSR 0x0137
#define PHYADD 0x0138
#define PHYDAT 0x0139
#define PHYCNT 0x013b
#define GPPC 0x013d
#define BMCR 0x0140
#define BMSR 0x0142
#define ANAR 0x0144
#define ANLP 0x0146
#define AER 0x0148
#define CSCR 0x014C /* This one has the link status */
#define CSCR_LINK_STATUS (1 << 3)
#define USB_LAN_REQT_READ 0xc0
#define USB_LAN_REQT_WRITE 0x40
#define USB_LAN_REQ_GET_REGS 0x05
#define USB_LAN_REQ_SET_REGS 0x05
/* Receive status register errors */
#define RSR_ROK (1)
#define RSR_CRC (1<<2)
#define RSR_FAE (1<<1)
#define RSR_ERRORS (RSR_CRC | RSR_FAE)
#define RTL8150_MTU 1700
static unsigned char netbuf[RTL8150_MTU] __attribute__ ((aligned (8)));
extern void __inline__ wait_ms(unsigned long ms);
extern int usb_bulk_transfer_in(struct usb_device *dev,
void *data, int len,int *transdata);
extern int usb_bulk_transfer_out(struct usb_device *dev,
void *data, int len);
/* NIC specific static variables go here */
static char packet[2096];
/**************************************************************************
RTL 8150 Operations
***************************************************************************/
static int get_registers(struct eth_device *nic, u16 indx, u16 size, void *data)
{
return usb_control_msg(nic->udev, usb_rcvctrlpipe(nic->udev, 0),
USB_LAN_REQ_GET_REGS, USB_LAN_REQT_READ,
indx, 0, data, size, 500);
}
static int set_registers(struct eth_device *nic, u16 indx, u16 size, void *data)
{
return usb_control_msg(nic->udev, usb_sndctrlpipe(nic->udev, 0),
USB_LAN_REQ_SET_REGS, USB_LAN_REQT_WRITE,
indx, 0, data, size, 500);
}
static void disable_net_traffic(struct eth_device *nic)
{
u8 cr;
get_registers(nic, CR, 1, &cr);
cr &= 0xf3;
set_registers(nic, CR, 1, &cr);
}
static void rtl8150_disable(struct eth_device *nic)
{
netif_stop_queue(nic);
disable_net_traffic(nic);
}
static int rtl8150_reset(struct eth_device *nic)
{
u8 data = 0x10;
unsigned long i = HZ;
set_registers(nic, CR, 1, &data);
do {
get_registers(nic, CR, 1, &data);
} while ((data & 0x10) && --i);
//wait_ms(3000);
//printf("data:%x\n",data);
return (i > 0) ? 1 : 0;
}
static int enable_net_traffic(struct eth_device *nic)
{
u8 cr, tcr, rcr, msr;
DEBUGFUNC();
/* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */
rcr = 0x9e;
tcr = 0xd8; //windows RTL driver set to 0x18
cr = 0x0c;
//if (!(rcr & 0x80))
// set_bit(USB_LAN_HW_CRC, &nic->flags);
set_registers(nic, RCR, 1, &rcr);
set_registers(nic, TCR, 1, &tcr);
set_registers(nic, CR, 1, &cr);
get_registers(nic, MSR, 1, &msr);
return 0;
}
static void set_ethernet_addr(struct eth_device *nic)
{
u8 node_id[6];
DEBUGFUNC();
memset(node_id, 0, sizeof(node_id));
get_registers(nic, IDR, sizeof(node_id), node_id);
memcpy(nic->enetaddr, node_id, sizeof(node_id));
USB_LAN_DBG("net addr:%x-%x-%x-%x-%x-%x\n",nic->enetaddr[0],nic->enetaddr[1],nic->enetaddr[2],nic->enetaddr[3],nic->enetaddr[4],nic->enetaddr[5]);
}
/**************************************************************************
POLL - Wait for a frame
***************************************************************************/
static int
rtl8150_rx(struct eth_device *nic)
{
void *usb_buffer; //20080602 Nick Add
int datalen;
usb_buffer=(void*)&netbuf[0];
if (usb_bulk_transfer_in((nic->udev),usb_buffer, RTL8150_MTU,&datalen) < 0)
return -1;
memcpy((uchar *)packet,(usb_buffer),datalen);
#ifndef CONFIG_USE_UBOOT2017
NetReceive((uchar *)packet, datalen);
#else
net_process_received_packet((uchar *)packet, datalen);
#endif
return 1;
}
/**************************************************************************
TRANSMIT - Transmit a frame
***************************************************************************/
static int
rtl8150_tx(struct eth_device *nic, volatile void *packet, int length)
{
void *usb_buffer; //20080602 Nick Add
usb_buffer=(void*)&netbuf[0];
memcpy(usb_buffer,(void *)packet,length);
while (length < 60) //padding to 60 bytes
{
*((u8*)packet+length)=0;
length++;
}
if (usb_bulk_transfer_out( nic->udev,usb_buffer, length) < 0)
return -1;
return 1;
}
static int
rtl8150_open(struct eth_device *nic, bd_t * bis)
{
DEBUGFUNC();
set_registers(nic, IDR, 6, nic->enetaddr);
rtl8150_reset(nic);
enable_net_traffic(nic);
return 1;
}
/**************************************************************************
INIT - set up ethernet interface(s)
***************************************************************************/
int rtl8150_init(struct eth_device *nic)
{
DEBUGFUNC();
nic->init = rtl8150_open;
nic->recv = rtl8150_rx;
nic->send = rtl8150_tx;
nic->halt = rtl8150_disable;
if (!rtl8150_reset(nic)) {
printf("rtl8150 - device reset failed \n");
}
set_ethernet_addr(nic);
strcpy(nic->name, "rtl8150");
return 1;
}