3198 lines
88 KiB
C
Executable File
3198 lines
88 KiB
C
Executable File
/*
|
|
** $Id: //BBN_Linux/Branch/Branch_for_Rel_CMCC_7526_20161014/tclinux_phoenix/modules/private/tc3162l2hp2h/mac_tc3162l2.c#1 $
|
|
*/
|
|
/************************************************************************
|
|
*
|
|
* Copyright (C) 2006 Trendchip Technologies, Corp.
|
|
* All Rights Reserved.
|
|
*
|
|
* Trendchip Confidential; Need to Know only.
|
|
* Protected as an unpublished work.
|
|
*
|
|
* The computer program listings, specifications and documentation
|
|
* herein are the property of Trendchip Technologies, Co. and shall
|
|
* not be reproduced, copied, disclosed, or used in whole or in part
|
|
* for any reason without the prior express written permission of
|
|
* Trendchip Technologeis, Co.
|
|
*
|
|
*************************************************************************/
|
|
/*
|
|
** $Log: mac_tc3162l2.c,v $
|
|
** Revision 1.21 2011/07/24 12:00:14 xyzhu_nj
|
|
** #11006: Merge China telecom branch to Main trunk.
|
|
**
|
|
** Revision 1.20 2011/07/14 02:51:59 shnwind
|
|
** fix bug : mac polling timer will die when status is RESET or POWERDOWN
|
|
**
|
|
** Revision 1.19 2011/07/07 07:46:13 shnwind
|
|
** RT63260 & RT63260 auto_bench support
|
|
**
|
|
** Revision 1.18 2011/06/23 02:43:59 shnwind
|
|
** fix bug : rt5392 throughput (1 wifi to 1 lan) problem
|
|
**
|
|
** Revision 1.17 2011/06/03 09:14:45 shnwind
|
|
** change netif_receive_skb to replace netif_skb when use NAPI in mac driver
|
|
**
|
|
** Revision 1.16 2011/05/27 05:52:23 yuantian_sz
|
|
** #10397: can not find eth0 port when upgrade single port version.
|
|
**
|
|
** Revision 1.15 2011/05/13 08:02:03 tzzhang_nj
|
|
** [Enhancement]#9542:
|
|
** 1. Use special tag to vlan tag under pvc uplink to make sure lan2lan throughput to 80M-120M;
|
|
** 2. Use switch vlan under ethernet uplink.
|
|
** 3. Enable PVC WAN:
|
|
** ethcmd eth0 vlanpt disable
|
|
** echo 1 > /proc/tc3162/stag_to_vtag
|
|
** ethcmd eth0 vlanpt enable
|
|
** Enable ethernet WAN:
|
|
** ethcmd eth0 vlanpt disable
|
|
** echo 0 > /proc/tc3162/stag_to_vtag
|
|
** ethcmd eth0 vlanpt enable
|
|
**
|
|
** Revision 1.14 2011/03/31 14:16:04 shnwind
|
|
** solve tc3182 throughput issue
|
|
**
|
|
** Revision 1.13 2011/03/23 12:04:23 shnwind
|
|
** solve a lot of out-of-order packet
|
|
**
|
|
** Revision 1.12 2011/03/17 11:44:01 shnwind
|
|
** Add a switch to vlanpt disable and NAPI moce
|
|
**
|
|
** Revision 1.11 2011/01/26 11:43:48 shnwind
|
|
** merge #8655 #8656
|
|
**
|
|
** Revision 1.10 2011/01/25 13:33:08 shnwind
|
|
** merge #8655
|
|
**
|
|
** Revision 1.9 2011/01/18 11:42:19 xyzhu_nj
|
|
** 8119
|
|
**
|
|
** Revision 1.8 2011/01/04 08:25:25 yuantian_sz
|
|
** merge #2018 TCSUPPORT_DYNAMIC_VLAN to maintrunk
|
|
**
|
|
** Revision 1.7 2010/12/24 12:42:23 xyzhu_nj
|
|
** #8119:Add support port reverse function.
|
|
**
|
|
** Revision 1.6 2010/12/22 01:55:08 xyzhu_nj
|
|
** #8119:Add support port reverse function.
|
|
**
|
|
** Revision 1.5 2010/12/02 06:24:34 shnwind
|
|
** fix some warning
|
|
**
|
|
** Revision 1.4 2010/11/09 11:31:32 shnwind
|
|
** fix bug : vlan packet send error when bridge mode
|
|
**
|
|
** Revision 1.3 2010/10/21 09:51:58 shnwind
|
|
** Use special tag to replace vlan function in switch
|
|
**
|
|
** Revision 1.2 2010/10/20 09:27:56 xmdai_nj
|
|
** #7191:crash happened when wan2lan&IGMP are enabled
|
|
**
|
|
** Revision 1.1.1.1 2010/09/30 21:14:54 josephxu
|
|
** modules/public, private
|
|
**
|
|
** Revision 1.10 2010/09/25 15:04:33 here
|
|
** [Ehancement]TCConsole to support capture the console log message and set command into cpe.
|
|
**
|
|
** Revision 1.9 2010/09/03 16:39:12 here
|
|
** [Ehance] TC3182 GMAC Driver is support TC-Console & WAN2LAN function.
|
|
**
|
|
** Revision 1.8 2010/09/03 13:47:23 xyyou
|
|
** add new version control
|
|
**
|
|
** Revision 1.7 2010/09/02 07:26:00 here
|
|
** [Ehance] Support TC3162U/TC3182 Auto-Bench
|
|
**
|
|
** Revision 1.6 2010/08/25 16:02:56 here
|
|
** [Bug fix] The tc-console can't be work and disabled TC2206 CPU PORT turbo mii mode with L2P2/L3P3/L4P4 CPU.
|
|
**
|
|
** Revision 1.5 2010/07/22 05:19:10 jlliu_nj
|
|
** Bug#6345:Support Version control mechanism in mldsnooping module,mac driver,sar driver:add line break in version
|
|
**
|
|
** Revision 1.4 2010/07/22 02:48:55 jlliu_nj
|
|
** Bug#6345:Support Version control mechanism in mldsnooping module,mac driver,sar driver
|
|
**
|
|
** Revision 1.3 2010/06/21 12:40:26 jlliu_nj
|
|
** update TC2205F/6F patch version to F8.0
|
|
**
|
|
** Revision 1.2 2010/05/20 07:32:26 here
|
|
** [Ehancemenet] Support the TC2206 swithc ic with TC3262 platform and sprate the switch ic into tcswitch.c files
|
|
**
|
|
** Revision 1.1.1.1 2010/04/09 09:35:28 feiyan
|
|
** New TC Linux Make Flow Trunk
|
|
**
|
|
** Revision 1.12 2010/03/29 15:20:18 ian
|
|
** Dynamic IMEM Utilization
|
|
**
|
|
** Revision 1.11 2010/03/29 12:37:06 yzwang_nj
|
|
** Fix compile error
|
|
** (Some statements about wan2lan were not limited by "ifndef TC2031_SUPPORT")
|
|
**
|
|
** Revision 1.10 2010/03/26 05:14:34 here
|
|
** [Bug fix] TCCONSOLE can't be work when user actived the virtual port function(Fix one port compiler error problem).
|
|
**
|
|
** Revision 1.9 2010/03/25 17:00:31 here
|
|
** [Bug fix] TCCONSOLE can't be work when user actived the virtual port function.
|
|
**
|
|
** Revision 1.8 2010/03/23 05:40:38 here
|
|
** [Bug fix] TC3162U with TC2206 Switch IC ESD Software Patch.
|
|
**
|
|
** Revision 1.7 2010/02/03 02:42:40 here
|
|
** [Ehancement]Remove the check mechanism for wifi driver that is released by trendchip crop.
|
|
**
|
|
** Revision 1.6 2010/02/02 12:13:13 here
|
|
** [Ehancement]1.RT3092 Chip is support polling mode when the adsl at init state.
|
|
** 2. Support the check mechanism for wifi driver that is released by trendchip crop.
|
|
**
|
|
** Revision 1.5 2010/01/28 13:21:49 here
|
|
** [Ehance]The mac driver is supported TC2206F switch ic.
|
|
**
|
|
** Revision 1.4 2010/01/15 17:26:22 pork
|
|
** wan2lan porting
|
|
**
|
|
** Revision 1.3 2010/01/10 15:26:32 here
|
|
** [Ehancement]TC3162U MAC EEE is operated at 100M-FD, SAR interface is accroding the SAR_CLK to calculate atm rate.
|
|
**
|
|
** Revision 1.2 2009/12/30 07:05:58 jlliu_nj
|
|
** Bug#3779:IPv6 ready logo Phase-2
|
|
**
|
|
** Revision 1.1.1.1 2009/12/17 01:48:05 josephxu
|
|
** 20091217, from Hinchu ,with VoIP
|
|
**
|
|
** Revision 1.2 2006/07/06 06:05:59 lino
|
|
** update to version 1.2
|
|
**
|
|
** Revision 1.1 2006/07/06 05:04:47 lino
|
|
** add kernel module support
|
|
**
|
|
** Revision 1.6 2006/02/27 05:12:31 lino
|
|
** do lan reset first then search phy addr
|
|
**
|
|
** Revision 1.5 2006/02/17 04:59:27 lino
|
|
** when disable adsl, let compilation correct
|
|
**
|
|
** Revision 1.4 2005/12/12 07:50:58 lino
|
|
** merge macTxSend and tc3162_tx_send functions
|
|
**
|
|
** Revision 1.3 2005/11/16 08:00:19 lino
|
|
** fix "ifconfig eth0 down" then "ifconfig eth0 up" will cause do_ade error
|
|
** fix "ifconfig eth0 hw ether" cannot change ethernet mac address
|
|
**
|
|
** Revision 1.2 2005/11/02 08:27:26 lino
|
|
** remove ahb_err handler
|
|
**
|
|
** Revision 1.1.1.1 2005/11/02 05:45:19 lino
|
|
** no message
|
|
**
|
|
*/
|
|
#define TC3162_MAC_NAPI
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/netdevice.h>
|
|
#include <linux/etherdevice.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/signal.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/init.h>
|
|
#include <linux/timer.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <asm/io.h>
|
|
#include <asm/tc3162/tc3162.h>
|
|
#include <asm/tc3162/ledcetrl.h>
|
|
#include <asm/tc3162/TCIfSetQuery_os.h>
|
|
#include "../../../version/tcversion.h"
|
|
#ifdef CONFIG_TC3162_ADSL
|
|
#include <linux/if_vlan.h>
|
|
#include <linux/skbuff.h>
|
|
#endif
|
|
#ifdef TCSUPPORT_AUTOBENCH
|
|
#include "../auto_bench/autobench.h"
|
|
#endif
|
|
|
|
#include "../tcphy/tcconsole.h"
|
|
|
|
#ifdef MII_INTERFACE
|
|
#include <linux/mii.h>
|
|
#endif
|
|
#include "tc3162l2mac.h"
|
|
|
|
|
|
#ifdef TCPHY_SUPPORT
|
|
#include <asm/tc3162/cmdparse.h>
|
|
#include "../tcphy/tcetherphy.h"
|
|
#include "../tcphy/tcswitch.h"
|
|
|
|
#ifdef TCPHY_DEBUG
|
|
#include "tcethercmd.h"
|
|
#endif
|
|
#endif
|
|
#ifdef EEE_SUPPORT
|
|
#include "psm_verify.h"
|
|
#endif
|
|
|
|
#define RX_BUF_LEN (2048 - 16 - 64 - (sizeof(struct skb_shared_info)))
|
|
#define RX_MAX_PKT_LEN 1536
|
|
//#define RX_BUF_LEN 1776
|
|
|
|
|
|
/************************************************************************
|
|
* C O N S T A N T S
|
|
*************************************************************************
|
|
*/
|
|
#define DYNAMIC_ALLOC_DMA_BUF 1
|
|
|
|
#define LAN_ST_100MB 0x01
|
|
#define LAN_ST_FULL_DUPLEX 0x02
|
|
#define LAN_ST_LINK_UP 0x04
|
|
|
|
|
|
/* ADMTEK6996M register */
|
|
#define ADM_PORT0_BASIC 0x01
|
|
#define ADM_PORT1_BASIC 0x03
|
|
#define ADM_PORT2_BASIC 0x05
|
|
#define ADM_PORT3_BASIC 0x07
|
|
#define ADM_PORT4_BASIC 0x08
|
|
#define ADM_PORT5_BASIC 0x09
|
|
|
|
#define ADM_CHIP_ID0 0xa0
|
|
#define ADM_CHIP_ID1 0xa1
|
|
|
|
|
|
|
|
/************************************************************************
|
|
* D A T A T Y P E S
|
|
*************************************************************************
|
|
*/
|
|
|
|
#if defined(TCSUPPORT_ETHER_ALL_LED)
|
|
extern uint8 ether_lan_speed;
|
|
int ether_speed[4] = {200,150,100,50};
|
|
#endif
|
|
/************************************************************************
|
|
* F U N C T I O N D E C L A R A T I O N S
|
|
*************************************************************************
|
|
*/
|
|
PRIVATE void tcAdmMiiStationWrite(uint32 admReg, uint32 miiData);
|
|
PRIVATE uint32 tcAdmMiiStationRead(uint32 admReg);
|
|
#ifdef MII_INTERFACE
|
|
static int mdio_read(struct net_device *dev, int phy_id, int reg_num);
|
|
static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val);
|
|
#endif
|
|
#ifdef TCPHY_SUPPORT
|
|
extern int cmd_unregister(char *name);
|
|
#define LAN_ST_CONNECTED 0x40 /* if lan cable is connected */
|
|
extern uint8 tcPhyExtResetNeeded(void);
|
|
extern uint8 getTcPhyFlag(void);
|
|
extern int tcPhyInit(macAdapter_t * mac_p);
|
|
extern uint8 phyMbpChk(struct sk_buff* oldMbp);
|
|
extern uint8 phy_recv_err_check(struct sk_buff** oldMbp, volatile macRxDescr_t *rxDescrp, uint32 *frameSize);
|
|
extern int tcPhyVerLookUp(macAdapter_t *mac_p);
|
|
extern uint8 getTcPhyForceLinkFlag(void);
|
|
extern uint32 getTcPhyStatusReg(macAdapter_t * mac_p);
|
|
extern uint8 getTcPhyLookbackFlag(void);
|
|
extern void tcephydbgcmd(void);
|
|
#endif
|
|
static irqreturn_t tc3162_mac_isr(int irq, void *dev_id);
|
|
int tc3162_mac_tx(struct sk_buff *skb, struct net_device *dev);
|
|
#ifdef SWITCH_3052
|
|
int macRt3052STagEnable(ChanID);
|
|
#endif
|
|
|
|
#if !defined(TCSUPPORT_CT)
|
|
extern int tcPhySwPatch(void);
|
|
#ifdef TC_CONSOLE_ENABLE
|
|
void delete_tcconsole_proc(void);
|
|
#endif
|
|
#endif
|
|
#ifdef TCPHY_4PORT
|
|
extern char esd_has_reset;
|
|
extern void phy_reset_esd(void);
|
|
extern int eth_esd_read_proc(char *buf, char **start, off_t off, int count,
|
|
int *eof, void *data);
|
|
|
|
extern int eth_esd_write_proc(struct file *file, const char *buffer,
|
|
unsigned long count, void *data);
|
|
#if !defined(TCSUPPORT_CT)
|
|
#if 1//def VPORT
|
|
extern int vport_enable_read_proc(char *buf, char **start, off_t off, int count,
|
|
int *eof, void *data);
|
|
|
|
extern int vport_enable_write_proc(struct file *file, const char *buffer,
|
|
unsigned long count, void *data);
|
|
|
|
#endif
|
|
#endif
|
|
#ifdef TCPHY_SUPPORT
|
|
extern int eth_port_stat_read_proc(char *buf, char **start, off_t off, int count,
|
|
int *eof, void *data);
|
|
#endif
|
|
#endif
|
|
#if defined(TCSUPPORT_ETHER_ALL_LED)
|
|
int ether_states_handler(void); //ethernet led support
|
|
#endif
|
|
/************************************************************************
|
|
* P U B L I C D A T A
|
|
*************************************************************************
|
|
*/
|
|
|
|
int DbgSettings = DBG_TIME |
|
|
//DBG_HW |
|
|
//DBG_DBG |
|
|
//DBG_STAT |
|
|
//DBG_REG |
|
|
//DBG_FUNCTION |
|
|
//DBG_BUF |
|
|
//DBG_DES |
|
|
//DBG_MSG |
|
|
//DBG_ERROR |
|
|
//DBG_WARN |
|
|
//DBG_BUFS |
|
|
//DBG_OUT |
|
|
0;
|
|
|
|
|
|
/************************************************************************
|
|
* E X T E R N A L D A T A
|
|
*************************************************************************
|
|
*/
|
|
|
|
#ifdef EEE_SUPPORT
|
|
extern void chkLinkStatus(void);
|
|
#ifdef EEE_DEBUG
|
|
extern uint16 macLoopback;
|
|
extern uint32 macRxLoopback;
|
|
extern uint8 dbgLevel;
|
|
#endif
|
|
#endif
|
|
#ifdef WAN2LAN
|
|
extern int masko;
|
|
#endif
|
|
//#ifdef VPORT
|
|
//int vportMasko=0;
|
|
//#endif
|
|
|
|
/************************************************************************
|
|
* P R I V A T E D A T A
|
|
*************************************************************************
|
|
*/
|
|
|
|
|
|
/* Device data */
|
|
struct net_device *tc3162_mac_dev;
|
|
/* Timer */
|
|
static struct timer_list eth_timer;
|
|
static struct timer_list eth_poll_timer;
|
|
|
|
macAdapter_t *mac_p = NULL;
|
|
static macPhyLinkProfile_t enetPhyLinkProfile;
|
|
#ifdef DYNAMIC_ALLOC_DMA_BUF
|
|
static macMemPool_t *enetMemPool;
|
|
#else
|
|
static macMemPool_t enetMemPool __attribute__ ((__aligned__(16)));
|
|
#endif
|
|
|
|
static phyDeviceList_t phyDeviceList[] = {
|
|
{ 0x0013, "LXT972" },
|
|
{ 0x0022, "AC101L" },
|
|
{ 0x0243, "IP101" },
|
|
{ 0x8201, "RTL8201" },
|
|
{ 0x03a2, "TC2031" }
|
|
};
|
|
|
|
static uint8 macInitialized = 0; /* wdl */
|
|
|
|
uint8 def_mac_addr[] = {0x00, 0x00, 0xaa, 0xbb, 0xcc, 0xff};
|
|
|
|
uint8 swicVendor = 0;
|
|
#if defined(WAN2LAN) || defined(CONFIG_TC3162_ADSL)
|
|
#ifndef TC2031_SUPPORT
|
|
/* ------ xyzhu_091105:special tag relation data start ---------- */
|
|
extern uint8 macVlanFlag;
|
|
extern uint8 macRxPortFlag;
|
|
#if defined(TCSUPPORT_CT)
|
|
extern uint8 macSTagFlag;
|
|
#else
|
|
//extern uint8 macSTagFlag;
|
|
#endif
|
|
/* ------ xyzhu_091105:special tag relation data end ----------- */
|
|
#endif
|
|
#endif
|
|
#if !defined(TCSUPPORT_CT)
|
|
#if 1//defined(WAN2LAN) || defined(VPORT)
|
|
#ifndef TC2031_SUPPORT
|
|
extern uint8 macSTagFlag;
|
|
#endif
|
|
#endif
|
|
//#if 1//def TCSUPPORT_PORT_REVERSE
|
|
//int g_port_reverse = 0;
|
|
//extern int g_port_reverse;
|
|
//#endif
|
|
#endif
|
|
#ifndef TC2031_SUPPORT
|
|
/* for port reverse */
|
|
extern int port_reverse_read_proc(char *buf, char **start, off_t off, int count, int *eof, void *data);
|
|
extern int port_reverse_write_proc(struct file *file, const char *buffer, unsigned long count, void *data);
|
|
#if !defined(TCSUPPORT_CT)
|
|
/* for special tag to vtag */
|
|
extern int stag_to_vtag_read_proc(char *buf, char **start, off_t off, int count, int *eof, void *data);
|
|
extern int stag_to_vtag_write_proc(struct file *file, const char *buffer, unsigned long count, void *data);
|
|
#endif
|
|
#endif
|
|
/************************************************************************
|
|
* F U N C T I O N D E F I N I T I O N S
|
|
*************************************************************************
|
|
*/
|
|
#define read_reg_word(reg) VPint(reg)
|
|
#define write_reg_word(reg, wdata) VPint(reg)=wdata
|
|
#define pause(x) mdelay(x)
|
|
|
|
|
|
#ifdef EEE_DEBUG
|
|
static void dump_skb(struct sk_buff *skb)
|
|
{
|
|
char tmp[80];
|
|
char *p = skb->data;
|
|
char *t = tmp;
|
|
int i, n = 0;
|
|
|
|
printk("ERR skb=%08lx data=%08lx len=%d\n", (uint32) skb, (uint32) skb->data, skb->len);
|
|
for (i = 0; i < skb->len + 4; i++) {
|
|
t += sprintf(t, "%02x ", *p++ & 0xff);
|
|
if ((i & 0x0f) == 0x0f) {
|
|
printk("%04x: %s\n", n, tmp);
|
|
n += 16;
|
|
t = tmp;
|
|
}
|
|
}
|
|
if (i & 0x0f)
|
|
printk("%04x: %s\n", n, tmp);
|
|
}
|
|
|
|
#endif
|
|
PRIVATE uint32
|
|
align16Byte
|
|
(
|
|
uint32 addr
|
|
)
|
|
{
|
|
return (addr+15)&0xFFFFFFF0;
|
|
}
|
|
|
|
PUBLIC void
|
|
miiStationWrite(
|
|
macAdapter_t *mac_p,
|
|
uint32 phyReg,
|
|
uint32 miiData
|
|
)
|
|
{
|
|
uint32 cnt=1000;
|
|
uint32 reg=0;
|
|
macPhyWDataReg_t macPHYWData;
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n---->miiStationWrite"));
|
|
// check argument
|
|
if(mac_p==NULL){
|
|
DEBUGMSG(DBG_ERROR,("\r\nERROR:miiStationWrite() mac_p is NULL pointer"));
|
|
}
|
|
if(phyReg>24){
|
|
DEBUGMSG(DBG_ERROR,("\r\nERROR:miiStationWrite() phyReg is out of range(16)"));
|
|
}
|
|
macPHYWData.bits.miiwdata = miiData & 0x0000ffff;
|
|
write_reg_word (CR_MAC_PHYWDATA, macPHYWData.value);
|
|
|
|
if(isTC3162U || isRT63260){
|
|
/*New format to access mii register*/
|
|
reg=((phyReg & 0x1f)<<NEW_PHYOR_REG_SHIFT) |((mac_p->enetPhyAddr & 0x1f)<<NEW_PHYOR_ADDR_SHIFT)\
|
|
|(NEW_PHYOR_OP_WR<<NEW_PHYOR_OP_SHIFT) |(NEW_PHYOR_ST_IEEE_OLD <<NEW_PHYOR_ST_SHIFT);
|
|
write_reg_word (CR_MAC_PHYCR, reg);
|
|
do{
|
|
reg=read_reg_word (CR_MAC_PHYCR);
|
|
cnt--;
|
|
}while ((reg&NEW_PHYOR_BUSY)&&cnt>0);
|
|
}
|
|
else{
|
|
/*Old format to accress mii register*/
|
|
reg=((phyReg & 0x1f)<<PHYOR_REG_SHIFT)|((mac_p->enetPhyAddr & 0x1f)<<PHYOR_ADDR_SHIFT) \
|
|
|PHYOR_WRITE;
|
|
write_reg_word (CR_MAC_PHYCR, reg);
|
|
do{
|
|
reg=read_reg_word (CR_MAC_PHYCR);
|
|
cnt--;
|
|
}while ((reg & PHYOR_WRITE)&&cnt>0);
|
|
}
|
|
|
|
if(cnt==0){
|
|
DEBUGMSG(DBG_MSG,("\r\nError:miiStationWrite Timeout!"));
|
|
}
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n<----miiStationWrite"));
|
|
}
|
|
|
|
PUBLIC uint32
|
|
miiStationRead(
|
|
macAdapter_t *mac_p,
|
|
uint32 phyReg
|
|
)
|
|
{
|
|
uint32 reg=0;
|
|
uint32 cnt=1000;
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n---->tcMiiStationRead"));
|
|
|
|
if(mac_p==NULL){
|
|
DEBUGMSG(DBG_ERROR,("\r\nERROR:miiStationWrite() mac_p is NULL pointer"));
|
|
}
|
|
|
|
if(phyReg>24){
|
|
DEBUGMSG(DBG_ERROR,("\r\nERROR:miiStationWrite() phyReg is out of range(16)"));
|
|
}
|
|
|
|
if(isTC3162U || isRT63260){
|
|
/*New format to access mii register*/
|
|
reg=((phyReg & 0x1f)<<NEW_PHYOR_REG_SHIFT) |((mac_p->enetPhyAddr & 0x1f) <<NEW_PHYOR_ADDR_SHIFT)\
|
|
|(NEW_PHYOR_OP_RD<<NEW_PHYOR_OP_SHIFT) |(NEW_PHYOR_ST_IEEE_OLD <<NEW_PHYOR_ST_SHIFT);
|
|
write_reg_word (CR_MAC_PHYCR, reg);
|
|
do{
|
|
reg=read_reg_word (CR_MAC_PHYCR);
|
|
cnt--;
|
|
}while ((reg&NEW_PHYOR_BUSY)&&cnt>0);
|
|
}
|
|
else{
|
|
/*Old format to accress mii register*/
|
|
reg=((phyReg & 0x1f)<<PHYOR_REG_SHIFT) |((mac_p->enetPhyAddr & 0x1f) <<PHYOR_ADDR_SHIFT) \
|
|
|PHYOR_READ;
|
|
write_reg_word (CR_MAC_PHYCR, reg);
|
|
do{
|
|
reg=read_reg_word (CR_MAC_PHYCR);
|
|
cnt--;
|
|
}while ((reg&PHYOR_READ)&&cnt>0);
|
|
}
|
|
|
|
if(cnt==0){
|
|
DEBUGMSG(DBG_ERROR,("\r\nError:miiStationRead Timeout!"));
|
|
}
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n<----miiStationRead"));
|
|
return (reg & 0xffff);
|
|
}
|
|
|
|
void
|
|
tcMiiStationWrite
|
|
(
|
|
uint32 enetPhyAddr,
|
|
uint32 phyReg,
|
|
uint32 miiData
|
|
)
|
|
{
|
|
uint32 cnt=1000;
|
|
uint32 reg=0;
|
|
macPhyWDataReg_t macPHYWData;
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n---->miiStationWrite"));
|
|
if(phyReg>24){
|
|
DEBUGMSG(DBG_ERROR,("\r\nERROR:miiStationWrite() phyReg is out of range(16)"));
|
|
}
|
|
|
|
macPHYWData.bits.miiwdata = miiData & 0x0000ffff;
|
|
write_reg_word (CR_MAC_PHYWDATA, macPHYWData.value);
|
|
|
|
if(isTC3162U || isRT63260){
|
|
/*New format to access mii register*/
|
|
reg=((phyReg & 0x1f)<<NEW_PHYOR_REG_SHIFT) |((enetPhyAddr & 0x1f) <<NEW_PHYOR_ADDR_SHIFT)\
|
|
|(NEW_PHYOR_OP_WR<<NEW_PHYOR_OP_SHIFT) |(NEW_PHYOR_ST_IEEE_OLD <<NEW_PHYOR_ST_SHIFT);
|
|
write_reg_word (CR_MAC_PHYCR, reg);
|
|
do{
|
|
reg=read_reg_word (CR_MAC_PHYCR);
|
|
cnt--;
|
|
}while ((reg&NEW_PHYOR_BUSY)&&cnt>0);
|
|
}
|
|
else{
|
|
/*Old format to accress mii register*/
|
|
reg=((phyReg & 0x1f)<<PHYOR_REG_SHIFT) |((enetPhyAddr & 0x1f) <<PHYOR_ADDR_SHIFT) \
|
|
|PHYOR_WRITE;
|
|
write_reg_word (CR_MAC_PHYCR, reg);
|
|
do{
|
|
reg=read_reg_word (CR_MAC_PHYCR);
|
|
cnt--;
|
|
}while ((reg & PHYOR_WRITE)&&cnt>0);
|
|
}
|
|
|
|
if(cnt==0){
|
|
DEBUGMSG(DBG_MSG,("\r\nError:miiStationWrite Timeout!"));
|
|
}
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n<----miiStationWrite"));
|
|
#ifdef TCPHY_4PORT
|
|
/*TC2206 switch IC can't be direct to do PHY reset, we must
|
|
* avoid ESD software patch be trigger.
|
|
*/
|
|
refillPhyDefVal(enetPhyAddr, phyReg, miiData);
|
|
#endif
|
|
}
|
|
|
|
uint32
|
|
tcMiiStationRead(
|
|
uint32 enetPhyAddr,
|
|
uint32 phyReg
|
|
)
|
|
{
|
|
uint32 reg=0;
|
|
uint32 cnt=1000;
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n---->tcMiiStationRead"));
|
|
|
|
if(phyReg>24){
|
|
DEBUGMSG(DBG_ERROR,("\r\nERROR:miiStationWrite() phyReg is out of range(16)"));
|
|
}
|
|
|
|
if(isTC3162U || isRT63260){
|
|
/*New format to access mii register*/
|
|
reg=((phyReg & 0x1f)<<NEW_PHYOR_REG_SHIFT) |((enetPhyAddr & 0x1f) <<NEW_PHYOR_ADDR_SHIFT)\
|
|
|(NEW_PHYOR_OP_RD<<NEW_PHYOR_OP_SHIFT) |(NEW_PHYOR_ST_IEEE_OLD <<NEW_PHYOR_ST_SHIFT);
|
|
write_reg_word (CR_MAC_PHYCR, reg);
|
|
do{
|
|
reg=read_reg_word (CR_MAC_PHYCR);
|
|
cnt--;
|
|
}while ((reg&NEW_PHYOR_BUSY)&&cnt>0);
|
|
}
|
|
else{
|
|
/*Old format to accress mii register*/
|
|
reg=((phyReg & 0x1f)<<PHYOR_REG_SHIFT) |((enetPhyAddr & 0x1f) <<PHYOR_ADDR_SHIFT) \
|
|
|PHYOR_READ;
|
|
write_reg_word (CR_MAC_PHYCR, reg);
|
|
do{
|
|
reg=read_reg_word (CR_MAC_PHYCR);
|
|
cnt--;
|
|
}while ((reg&PHYOR_READ)&&cnt>0);
|
|
}
|
|
|
|
if(cnt==0){
|
|
DEBUGMSG(DBG_ERROR,("\r\nError:miiStationRead Timeout!"));
|
|
}
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n<----miiStationRead"));
|
|
return (reg & 0xffff);
|
|
}
|
|
|
|
PRIVATE void
|
|
tcAdmMiiStationWrite(
|
|
uint32 admReg,
|
|
uint32 miiData
|
|
)
|
|
{
|
|
uint32 phyaddr;
|
|
uint32 reg;
|
|
|
|
phyaddr = admReg >> 5;
|
|
reg = admReg & 0x1f;
|
|
|
|
tcMiiStationWrite(phyaddr, reg, miiData);
|
|
}
|
|
|
|
PRIVATE uint32
|
|
tcAdmMiiStationRead(
|
|
uint32 admReg
|
|
)
|
|
{
|
|
uint32 phyaddr;
|
|
uint32 reg;
|
|
|
|
phyaddr = admReg >> 5;
|
|
reg = admReg & 0x1f;
|
|
|
|
return tcMiiStationRead(phyaddr, reg);
|
|
}
|
|
#ifdef MII_INTERFACE
|
|
static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
|
|
{
|
|
return tcMiiStationRead(phy_id, reg_num);
|
|
}
|
|
|
|
static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val)
|
|
{
|
|
tcMiiStationWrite(phy_id, reg_num, val);
|
|
}
|
|
#endif
|
|
|
|
PRIVATE void macIMRMask(void)
|
|
{
|
|
macIntrMaskReg_t macIntrMask;
|
|
macIntrMask.value = 0;
|
|
macIntrMask.bits.rpkt_finish = 1;
|
|
#ifdef TC3162_MAC_NAPI
|
|
macIntrMask.bits.norxbuf = 1;
|
|
macIntrMask.bits.rpkt_lost = 1;
|
|
#endif
|
|
#if 0
|
|
macIntrMask.bits.rpkt_ok_by_thrhold = 0;
|
|
macIntrMask.bits.rpkt_ok_by_timeout = 0;
|
|
macIntrMask.bits.xpkt_ok_by_thrhold = 0;
|
|
macIntrMask.bits.xpkt_ok_by_timeout = 0;
|
|
macIntrMask.bits.norxbuf = 1;
|
|
macIntrMask.bits.notxbuf = 1;
|
|
macIntrMask.bits.xpkt_finish = 1;
|
|
macIntrMask.bits.xpkt_lost = 1;
|
|
macIntrMask.bits.rpkt_lost = 1;
|
|
macIntrMask.bits.xpkt_save = 1;
|
|
macIntrMask.bits.rpkt_save = 1;
|
|
macIntrMask.bits.ahb_err = 1;
|
|
macIntrMask.bits.physts_chg = 1;
|
|
#endif
|
|
write_reg_word(CR_MAC_IMR, macIntrMask.value);
|
|
}
|
|
|
|
PRIVATE void macResetSwMAC(void)
|
|
{
|
|
macCtrlReg_t macCtrl;
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n---->macResetSwMAC"));
|
|
// Disable DMA Enable
|
|
macCtrl.value = 0;
|
|
write_reg_word (CR_MAC_MACCR, macCtrl.value);
|
|
pause(2);
|
|
|
|
// Reset Mac
|
|
// macCtrl.value = 0;
|
|
macCtrl.bits.sw_rst = 1;
|
|
write_reg_word (CR_MAC_MACCR, macCtrl.value);
|
|
pause(2);
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n<----macResetSwMAC"));
|
|
}
|
|
|
|
PRIVATE void macSetIntTimer(void)
|
|
{
|
|
mac_intr_timer_ctrl_reg_t macIntrTimerCtrl;
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n---->macSetIntTimer"));
|
|
macIntrTimerCtrl.value = 0;
|
|
write_reg_word (CR_MAC_ITC, macIntrTimerCtrl.value);
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n<----macSetIntTimer"));
|
|
}
|
|
|
|
// Assign Tx Rx Descriptor Control Registers
|
|
PRIVATE void macSetDMADescrCtrlReg(macAdapter_t *mac_p)
|
|
{
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n---->macSetDMADescrCtrlReg"));
|
|
write_reg_word(CR_MAC_TXR_BADR, K1_TO_PHY( mac_p->txDescrRingBaseVAddr));
|
|
write_reg_word(CR_MAC_RXR_BADR, K1_TO_PHY( mac_p->rxDescrRingBaseVAddr));
|
|
|
|
VPint(CR_MAC_TXR_SIZE) = mac_p->txRingSize;
|
|
VPint(CR_MAC_RXR_SIZE) = mac_p->rxRingSize;
|
|
VPint(CR_MAC_TXDESP_SIZE) = mac_p->txDescrSize;
|
|
VPint(CR_MAC_RXDESP_SIZE) = mac_p->rxDescrSize;
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n<----macSetDMADescrCtrlReg"));
|
|
}
|
|
|
|
PRIVATE void macSetMACCR
|
|
(
|
|
macAdapter_t *map_p
|
|
)
|
|
{
|
|
macCtrlReg_t macCtrl;
|
|
|
|
DEBUGMSG(DBG_FUNCTION, ("\r\n---->macSetMACCR"));
|
|
// clear reg
|
|
//macCtrl.value = 0x3df23;
|
|
macCtrl.value = 0x0;
|
|
//Enable RX flow control. shnwind 20110622
|
|
macCtrl.bits.rx_flow_ctrl = 1;
|
|
|
|
// set flag
|
|
macCtrl.bits.rx_broadpkt = 1;
|
|
macCtrl.bits.rx_multipkt = 1;
|
|
|
|
macCtrl.bits.fulltx = 1;
|
|
macCtrl.bits.crc_apd = 1;
|
|
macCtrl.bits.mdc_sel = 0;
|
|
macCtrl.bits.rcv_all = 1;
|
|
|
|
macCtrl.bits.rx_ftl = 1;
|
|
macCtrl.bits.rx_runt = 1;
|
|
macCtrl.bits.ht_multi_en = 1;
|
|
macCtrl.bits.rcv_en = 0;
|
|
|
|
macCtrl.bits.l2_mode = 1;
|
|
macCtrl.bits.enrx_in_halftx = 0;
|
|
macCtrl.bits.xmt_en = 0;
|
|
macCtrl.bits.crc_dis = 0;
|
|
|
|
macCtrl.bits.loop_en = 0;
|
|
macCtrl.bits.sw_rst = 0;
|
|
macCtrl.bits.rdma_en = 0;
|
|
macCtrl.bits.xdma_en = 0;
|
|
|
|
macCtrl.bits.txfifo_thr = 0x0e;
|
|
macCtrl.bits.rx_untag = 0;
|
|
macCtrl.bits.drop_local = 0;
|
|
|
|
write_reg_word (CR_MAC_MACCR, macCtrl.value);
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n<----macSetMACCR"));
|
|
}
|
|
|
|
PRIVATE void macSetMacReg
|
|
(
|
|
macAdapter_t *mac_p
|
|
)
|
|
{
|
|
write_reg_word(CR_MAC_MADR,mac_p->macAddr[0]<<8 | mac_p->macAddr[1]<<0);
|
|
write_reg_word(CR_MAC_LADR,mac_p->macAddr[2]<<24 | mac_p->macAddr[3]<<16 | \
|
|
mac_p->macAddr[4]<<8 | mac_p->macAddr[5]<<0);
|
|
}
|
|
|
|
PRIVATE macTxDescr_t*
|
|
macTxRingProc
|
|
(
|
|
macAdapter_t *mac_p
|
|
)
|
|
{
|
|
volatile macTxDescr_t *pTxDescp;
|
|
unsigned long flags;
|
|
|
|
spin_lock_irqsave(&mac_p->lock, flags);
|
|
pTxDescp = ((macTxDescr_t*)mac_p->txDescrRingBaseVAddr) + mac_p->txUnReleasedDescp;
|
|
|
|
while ( mac_p->txUnReleasedBufCnt != 0 )
|
|
{
|
|
if ( (pTxDescp->tdes0.word)&(1<<31) )
|
|
{
|
|
spin_unlock_irqrestore(&mac_p->lock, flags);
|
|
return 0; // owned by MAC engine, something wrong here!
|
|
}
|
|
if ( mac_p->statisticOn )
|
|
{
|
|
if ( (pTxDescp->tdes0.word)&(1<<1) )
|
|
{
|
|
mac_p->macStat.inSilicon.txExCollisionCnt++;
|
|
mac_p->macStat.inSilicon.txCollisionCnt++;
|
|
mac_p->macStat.MIB_II.outErrors++;
|
|
}
|
|
|
|
if ( (pTxDescp->tdes0.word)&(1<<3|1<<2) )
|
|
{
|
|
mac_p->macStat.inSilicon.txUnderRunCnt++;
|
|
}
|
|
|
|
if ( (pTxDescp->tdes0.word)&(1<<0) )
|
|
{
|
|
mac_p->macStat.inSilicon.txLateCollisionCnt++;
|
|
mac_p->macStat.inSilicon.txCollisionCnt++;
|
|
mac_p->macStat.MIB_II.outErrors++;
|
|
}
|
|
} // mac_p->statisticOn
|
|
|
|
if (pTxDescp->tdes2.buf_p == 0x0)
|
|
printk("buf_p is null\n");
|
|
dev_kfree_skb_any(pTxDescp->skb);
|
|
|
|
pTxDescp->tdes2.buf_p = 0;
|
|
pTxDescp->skb = NULL;
|
|
|
|
if ( mac_p->txUnReleasedDescp == ( mac_p->txRingSize - 1) )
|
|
{
|
|
mac_p->txUnReleasedDescp = 0;
|
|
}
|
|
else
|
|
{
|
|
mac_p->txUnReleasedDescp++;
|
|
}
|
|
mac_p->txUnReleasedBufCnt--;
|
|
|
|
pTxDescp = ((macTxDescr_t*)mac_p->txDescrRingBaseVAddr) + mac_p->txUnReleasedDescp;
|
|
|
|
mac_p->macStat.inSilicon.txDeQueueNum++;
|
|
|
|
} // while
|
|
spin_unlock_irqrestore(&mac_p->lock, flags);
|
|
|
|
return (macTxDescr_t*)pTxDescp;
|
|
}
|
|
|
|
__IMEM int tc3162_mac_tx(struct sk_buff *skb, struct net_device *dev)
|
|
{
|
|
volatile macTxDescr_t *currDescrp = NULL;
|
|
uint32 length;
|
|
uint8 *bufAddrp = skb->data;
|
|
unsigned long flags;
|
|
#if !defined(TCSUPPORT_CT)
|
|
uint8 vlanid;
|
|
|
|
#endif
|
|
length = ((ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN);
|
|
|
|
|
|
#ifdef EEE_DEBUG
|
|
if(dbgLevel & DUMP_TX_PKT){
|
|
dump_skb(skb);
|
|
}
|
|
#endif
|
|
#ifdef CONFIG_TC3162_ADSL
|
|
#ifndef TC2031_SUPPORT
|
|
if(isTCConsolePkt(skb)){
|
|
if(swicVendor == SWIC_TC2206){
|
|
macTC2206STagInsert(skb);
|
|
}
|
|
else if(swicVendor ==SWIC_IP175C){
|
|
macIpSTagInsert(skb);
|
|
}
|
|
length = ((ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN);
|
|
}
|
|
#endif
|
|
#endif
|
|
#if !defined(TCSUPPORT_CT)
|
|
#if 1//def VPORT
|
|
#ifndef TC2031_SUPPORT
|
|
else if(!(skb->mark & SKBUF_COPYTOLAN) && macSTagFlag){
|
|
//prevent modify clone skbuff data.
|
|
skb = skb_unshare(skb ,GFP_ATOMIC);
|
|
if (skb == NULL){
|
|
mac_p->macStat.MIB_II.outDiscards++;
|
|
return 0;
|
|
}
|
|
/*Normal packet is inclued the vlan header, and also the
|
|
wan2lan packet is not inclued the vlan header.*/
|
|
#if 0
|
|
if (g_port_reverse) {
|
|
#ifdef TCSUPPORT_CT_2PWIFI
|
|
vlanid = 2 - ((uint8)skb->data[15]);
|
|
#else
|
|
vlanid = 4 - ((uint8)skb->data[15]);
|
|
#endif
|
|
vportMasko = (1<<vlanid);
|
|
}
|
|
else {
|
|
vportMasko = (1<<(uint8)skb->data[15]-BASE_VID_IDX);
|
|
}
|
|
#endif
|
|
|
|
/*Remove the vlan tag*/
|
|
//memmove(skb->data+VLAN_HLEN, skb->data, 12);
|
|
//skb_pull(skb, VLAN_HLEN);
|
|
skb->mark|=SKBUF_VLAN;
|
|
}
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(TCSUPPORT_CT)
|
|
#ifdef WAN2LAN
|
|
#ifndef TC2031_SUPPORT
|
|
if ((swicVendor == SWIC_IP175C) && macSTagFlag && !(skb->mark & SKBUF_TCCONSOLE))
|
|
{
|
|
macIpSTagInsert(skb);
|
|
length = ((ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN);
|
|
}
|
|
|
|
//#ifdef TC2206_SUPPORT
|
|
if((swicVendor==SWIC_TC2206)&&macSTagFlag && !(skb->mark & SKBUF_TCCONSOLE)){
|
|
macTC2206STagInsert(skb);
|
|
length = ((ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN);
|
|
}
|
|
//#endif /*TC2206_SUPPORT*/
|
|
#endif /*TC2031_SUPPORT*/
|
|
#endif
|
|
#else
|
|
#if 1//defined(WAN2LAN) || defined(VPORT)
|
|
#ifndef TC2031_SUPPORT
|
|
if ((swicVendor == SWIC_IP175C) && macSTagFlag && !(skb->mark & SKBUF_TCCONSOLE))
|
|
{
|
|
macIpSTagInsert(skb);
|
|
length = ((ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN);
|
|
}
|
|
|
|
//#ifdef TC2206_SUPPORT
|
|
if((swicVendor==SWIC_TC2206)&&macSTagFlag && !(skb->mark & SKBUF_TCCONSOLE)){
|
|
macTC2206STagInsert(skb);
|
|
length = ((ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN);
|
|
}
|
|
//#endif /*TC2206_SUPPORT*/
|
|
#endif /*TC2031_SUPPORT*/
|
|
#endif
|
|
#endif
|
|
if (mac_p->txUnReleasedBufCnt >= TX_BUF_RELEASE_THRESHOLD)
|
|
{
|
|
macTxRingProc(mac_p);
|
|
}
|
|
|
|
if ( mac_p->txUnReleasedBufCnt == mac_p->txRingSize )
|
|
{
|
|
mac_p->macStat.MIB_II.outDiscards++;
|
|
dev_kfree_skb_any(skb);
|
|
|
|
/*Must return 0 here. If the return value is not equal zero, kernel will put the skb to link list.
|
|
This skb has been free here so it cause kernel double free this skb. shnwind 20090821.*/
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
spin_lock_irqsave(&mac_p->lock, flags);
|
|
/* ----- Get the transmit descriptor ----- */
|
|
currDescrp = ((macTxDescr_t*)mac_p->txDescrRingBaseVAddr) + mac_p->txCurrentDescp;
|
|
|
|
if( (currDescrp->tdes0.word)&(1<<31) )
|
|
{
|
|
mac_p->macStat.MIB_II.outDiscards++;
|
|
dev_kfree_skb_any(skb);
|
|
#if !defined(TCSUPPORT_CT)
|
|
spin_unlock_irqrestore(&mac_p->lock, flags);
|
|
#endif
|
|
/*Must return 0 here. If the return value is not equal zero, kernel will put the skb to link list.
|
|
This skb has been free here so it cause kernel double free this skb. shnwind 20090821.*/
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* ----- Count the MIB-II ----- */
|
|
mac_p->macStat.MIB_II.outOctets += length;
|
|
|
|
if ( *bufAddrp & 0x01 )
|
|
{
|
|
mac_p->macStat.MIB_II.outMulticastPkts++;
|
|
}
|
|
else
|
|
{
|
|
mac_p->macStat.MIB_II.outUnicastPkts++;
|
|
}
|
|
#if !defined(TCSUPPORT_ETHER_ALL_LED)
|
|
ledTurnOn(LED_ETHER_ACT_STATUS);
|
|
if (mac_p->macPhyLinkProfile_p->enetMode & LAN_ST_100MB)
|
|
ledTurnOn(LED_ETHER_100M_ACT_STATUS);
|
|
else
|
|
ledTurnOn(LED_ETHER_10M_ACT_STATUS);
|
|
#endif
|
|
//spin_lock_irqsave(&mac_p->lock, flags);
|
|
dma_cache_wback_inv((unsigned long)(skb->data), skb->len);
|
|
// tx buffer size
|
|
currDescrp->tdes0.word = 0;
|
|
/* clear all except edotr, fts, lts */
|
|
currDescrp->tdes1.word &= (1<<31|1<<28|1<<27);
|
|
currDescrp->tdes1.word |= (length&0x000007ff);
|
|
|
|
currDescrp->tdes2.buf_p = K1_TO_PHY(skb->data);
|
|
currDescrp->skb = skb;
|
|
|
|
currDescrp->tdes0.word |= (1<<31);
|
|
|
|
if( mac_p->txCurrentDescp == ( mac_p->txRingSize - 1 ))
|
|
{
|
|
mac_p->txCurrentDescp = 0;
|
|
}
|
|
else
|
|
{
|
|
mac_p->txCurrentDescp ++;
|
|
}
|
|
|
|
mac_p->txUnReleasedBufCnt++;
|
|
|
|
mac_p->macStat.inSilicon.txEnQueueNum++;
|
|
spin_unlock_irqrestore(&mac_p->lock, flags);
|
|
|
|
MAC_TX_POLL_DEMAND_(1);
|
|
return 0;
|
|
}
|
|
|
|
PUBLIC void
|
|
macDefaultParaSet
|
|
(
|
|
macAdapter_t *mac_p
|
|
)
|
|
{
|
|
mac_p->rxDescrSize = MAC_RXDESCP_SIZE;
|
|
mac_p->txDescrSize = MAC_TXDESCP_SIZE;
|
|
mac_p->rxRingSize = MAC_RXDESCP_NO;
|
|
mac_p->txRingSize = MAC_TXDESCP_NO;
|
|
|
|
mac_p->macStat.inSilicon.rxEnQueueNum = 0;
|
|
mac_p->macStat.inSilicon.rxDeQueueNum = 0;
|
|
mac_p->macStat.inSilicon.txEnQueueNum = 0;
|
|
mac_p->macStat.inSilicon.txDeQueueNum = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
PUBLIC int
|
|
macDrvRegInit
|
|
(
|
|
macAdapter_t *mac_p
|
|
)
|
|
{
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n---->macDrvRegInit"));
|
|
|
|
// ----- setup interrupt mask ---
|
|
// ---- Setup HASH table------------------------------------------
|
|
// -----Setup Interrupt Timer-------------------------------------
|
|
// -----Setup AUTO polling timer----------------------------------
|
|
// ---- Setup DMA burst and arbitration---------------------------
|
|
// -----Setup DMA Descriptor Base Address Assign------------------
|
|
// -----Setup MACCR-----------------------------------------------
|
|
|
|
macResetSwMAC();
|
|
|
|
macIMRMask();
|
|
|
|
macSetIntTimer();
|
|
|
|
// macSetAutoPollTmr();
|
|
|
|
// macSetupDMABurstArbitration();
|
|
|
|
macSetDMADescrCtrlReg(mac_p);
|
|
|
|
macSetMACCR(mac_p);
|
|
|
|
// --- setup MAC address ---
|
|
macSetMacReg(mac_p);
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n<----macDrvRegInit"));
|
|
return 0;
|
|
}
|
|
|
|
PRIVATE void
|
|
macDrvDescripReset
|
|
(
|
|
macAdapter_t *mac_p
|
|
)
|
|
{
|
|
int i;
|
|
|
|
macRxDescr_t * pRxDescp;
|
|
macTxDescr_t * pTxDescp;
|
|
struct sk_buff *skb;
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n---->macDrvDescripReset"));
|
|
|
|
pTxDescp = (macTxDescr_t*) mac_p->txDescrRingBaseVAddr;
|
|
pRxDescp = (macRxDescr_t*) mac_p->rxDescrRingBaseVAddr;
|
|
|
|
// free all un-released tx mbuf
|
|
for (i = 0 ; i < mac_p->txRingSize ; i++)
|
|
{
|
|
skb = pTxDescp->skb;
|
|
if( skb != NULL )
|
|
{
|
|
dev_kfree_skb_any(skb);
|
|
}
|
|
pTxDescp->tdes0.word = DESCP_OWNED_BY_CPU_WORD;
|
|
pTxDescp->tdes2.buf_p = 0;
|
|
pTxDescp->skb = NULL;
|
|
pTxDescp++;
|
|
}
|
|
|
|
for (i = 0; i < mac_p->rxRingSize; i++)
|
|
{
|
|
pRxDescp->rdes0.word = DESCP_OWNED_BY_DMA_WORD;
|
|
pRxDescp++;
|
|
}
|
|
|
|
mac_p->txCurrentDescp = 0;
|
|
mac_p->txUnReleasedDescp = 0;
|
|
mac_p->txUnReleasedBufCnt = 0;
|
|
mac_p->rxCurrentDescp = 0;
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n<----macDrvDescripReset"));
|
|
}
|
|
|
|
PRIVATE uint8
|
|
macDrvDescripInit
|
|
(
|
|
macAdapter_t *mac_p
|
|
)
|
|
{
|
|
macRxDescr_t *pRxDescp;
|
|
macTxDescr_t *pTxDescp;
|
|
uint32 i;
|
|
struct sk_buff *skb;
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n---->macDrvDescripInit"));
|
|
mac_p->txDescrRingBaseVAddr = K0_TO_K1(align16Byte((uint32)&mac_p->macMemPool_p->descrPool[0]));
|
|
|
|
mac_p->rxDescrRingBaseVAddr = mac_p->txDescrRingBaseVAddr + (mac_p->txDescrSize * mac_p->txRingSize);
|
|
|
|
// add function here to free all mbuf after Mac is soft-reset */
|
|
if( macInitialized )
|
|
{
|
|
macDrvDescripReset( mac_p );
|
|
}
|
|
|
|
/* init. tx descriptor, don't allocate memory */
|
|
pTxDescp = (macTxDescr_t*) mac_p->txDescrRingBaseVAddr;
|
|
mac_p->txCurrDescp = pTxDescp;
|
|
|
|
for ( i = 0 ; i < mac_p->txRingSize ; i++, pTxDescp++ )
|
|
{
|
|
// Init descriptor
|
|
pTxDescp->tdes0.word = 0;
|
|
pTxDescp->tdes1.word = 0;
|
|
pTxDescp->tdes2.word = 0;
|
|
|
|
// Assign flag
|
|
pTxDescp->tdes0.bits.ownerDma = 0; /* owned by CPU */
|
|
pTxDescp->tdes1.bits.sw_txtag_en = 0; /* SW Tag */
|
|
pTxDescp->tdes1.bits.ipcs_en = 0; /* IP Chksum */
|
|
pTxDescp->tdes1.bits.vtag_en = 0; /* VLAN Tag */
|
|
pTxDescp->skb = NULL;
|
|
}
|
|
|
|
/* init. Rx descriptor, allocate memory for each descriptor */
|
|
pRxDescp = (macRxDescr_t*) mac_p->rxDescrRingBaseVAddr;
|
|
|
|
for( i = 0 ; i< mac_p->rxRingSize ; i++, pRxDescp++)
|
|
{
|
|
// Init Descriptor
|
|
pRxDescp->rdes0.word = 0;
|
|
pRxDescp->rdes1.word = 0;
|
|
pRxDescp->rdes2.word = 0;
|
|
|
|
// Assign flag
|
|
pRxDescp->rdes0.bits.ownerDma = 1; /* owned by DMA */
|
|
pRxDescp->rdes1.bits.rxBufSize = 1776;
|
|
|
|
skb = skbmgr_dev_alloc_skb2k();
|
|
if( skb == NULL )
|
|
{
|
|
printk("tc3162_mac_descinit init fail.\n");
|
|
return 1;
|
|
}
|
|
/*To invaild the cache memroy*/
|
|
dma_cache_inv((unsigned long)(skb->data), RX_MAX_PKT_LEN);
|
|
|
|
skb_reserve(skb, 2);
|
|
//skb_reserve(skb, 8);
|
|
|
|
pRxDescp->rdes2.buf_p = K1_TO_PHY(skb->data);
|
|
pRxDescp->skb = skb;
|
|
}
|
|
|
|
mac_p->txCurrentDescp = 0;
|
|
mac_p->txUnReleasedDescp = 0;
|
|
mac_p->txUnReleasedBufCnt = 0;
|
|
mac_p->rxCurrentDescp = 0;
|
|
|
|
DEBUGMSG(DBG_FUNCTION,("\r\n<----macDrvDescripInit"));
|
|
return 0;
|
|
}
|
|
|
|
PUBLIC void
|
|
macDrvStart
|
|
(
|
|
void
|
|
)
|
|
{
|
|
macCtrlReg_t macCtrl;
|
|
|
|
macCtrl.value = VPint(CR_MAC_MACCR);
|
|
/* enable DMA tx& rx */
|
|
macCtrl.bits.rdma_en = 1;
|
|
macCtrl.bits.xdma_en = 1;
|
|
/* enable mac tx& rx */
|
|
macCtrl.bits.rcv_en = 1;
|
|
macCtrl.bits.xmt_en = 1;
|
|
VPint(CR_MAC_MACCR) = macCtrl.value;
|
|
}
|
|
|
|
void
|
|
macPhyReset
|
|
(
|
|
void
|
|
)
|
|
{
|
|
local_irq_disable();
|
|
|
|
#ifdef TCPHY_SUPPORT
|
|
if(getTcPhyFlag()){
|
|
tcPhyInit(mac_p);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
miiStationWrite( mac_p, PHY_CONTROL_REG, PHY_RESET );
|
|
miiStationWrite( mac_p, PHY_CONTROL_REG, MIIDR_AUTO_NEGOTIATE );
|
|
}
|
|
|
|
local_irq_enable();
|
|
}
|
|
|
|
#ifdef TCSUPPORT_AUTOBENCH
|
|
extern int autobench_mac_lpbk_flag;
|
|
extern int autobench_mac_lpbk_cnt;
|
|
extern int autobench_mac_lpbk1_flag;
|
|
extern unsigned char LoopbackData[];
|
|
#endif
|
|
|
|
__IMEM
|
|
#ifdef TC3162_MAC_NAPI
|
|
int macRxRingProc(struct net_device *dev, int quota)
|
|
#else
|
|
void macRxRingProc(struct net_device *dev)
|
|
#endif
|
|
{
|
|
volatile macRxDescr_t *rxDescrp;
|
|
uint32 frameSize;
|
|
struct sk_buff *newMbp, *oldMbp;
|
|
uint32 rdes0_error_check, rdes1_error_check;
|
|
#ifdef TC3162_MAC_NAPI
|
|
int npackets = 0;
|
|
#endif
|
|
#ifdef TCPHY_4PORT
|
|
uint16 maxPktSize=0;
|
|
#endif
|
|
|
|
rxDescrp = ((macRxDescr_t*)mac_p->rxDescrRingBaseVAddr) + mac_p->rxCurrentDescp;
|
|
/*Not check long packet error due to we enable the special tag the max packet size will be too long*/
|
|
rdes0_error_check = (1<<27|1<<22|1<<21|1<<19|1<<18);
|
|
rdes1_error_check = 0;
|
|
#ifdef TC3162_MAC_NAPI
|
|
while ((npackets <= quota) && ((rxDescrp->rdes0.word & (1<<31)) == 0)) // ownerDMA for TCMAC
|
|
#else
|
|
while ((rxDescrp->rdes0.word & (1<<31)) == 0) // ownerDMA for TCMAC
|
|
#endif
|
|
{
|
|
#ifdef TC3162_MAC_NAPI
|
|
npackets++;
|
|
#endif
|
|
// According to UNH document, the alignment error should be recorded and
|
|
// the packet may be discarded if CRC error happens.
|
|
if ( rxDescrp->rdes1.word&(1<<27) )
|
|
{
|
|
mac_p->macStat.inSilicon.rxAlignErr++;
|
|
mac_p->macStat.inSilicon.rxDribblingErr++;
|
|
}
|
|
|
|
if ( (rxDescrp->rdes0.word & rdes0_error_check) == 0 &&
|
|
(rxDescrp->rdes1.word & rdes1_error_check) == 0 )
|
|
{
|
|
// For removing Rx VLAN tag, we need to check if the remain length
|
|
// is not smaller than minimun packet length.
|
|
// rxDescrp->rdes0.bits.vlan_hit
|
|
if (rxDescrp->rdes0.word & (1<<30))
|
|
{
|
|
frameSize = rxDescrp->rdes0.bits.rfl;
|
|
frameSize = (frameSize > 60) ? frameSize : 60;
|
|
}
|
|
else
|
|
frameSize = rxDescrp->rdes0.bits.rfl;
|
|
if (rxDescrp->rdes1.word & (1<<28))
|
|
mac_p->macStat.inSilicon.rx802p3FrameLengthErr++;
|
|
|
|
#ifndef TCPHY_4PORT
|
|
/* lino: make VLAN friendly */
|
|
if ( (frameSize < 60) || (frameSize > 1522) )
|
|
#else
|
|
switch(swicVendor){
|
|
case SWIC_TC2206:
|
|
/*TC2206 Special Tag Length=8bytes, vlan header 4 bytes, max ethernet length=1518; 1518+8+4=1530*/
|
|
maxPktSize=1530;
|
|
break;
|
|
default:
|
|
maxPktSize=1522;
|
|
break;
|
|
}
|
|
if ( (frameSize < 60) || (frameSize > maxPktSize))
|
|
#endif
|
|
{
|
|
DEBUGMSG(DBG_ERROR,("\r\n frame size is out of range"));
|
|
mac_p->macStat.inSilicon.rxEtherFrameLengthErr++;
|
|
|
|
// Discard this packet & Repost this mbuf
|
|
(volatile struct sk_buff *)newMbp = (volatile struct sk_buff *)(rxDescrp->skb);
|
|
DEBUGMSG(DBG_ERROR,("\r\n the packet will be discarded"));
|
|
goto DISCARD;
|
|
}
|
|
|
|
// ----- Count the MIB-II -----
|
|
if ( mac_p->statisticOn )
|
|
{
|
|
mac_p->macStat.MIB_II.inOctets += frameSize;
|
|
|
|
if ( (rxDescrp->rdes0.word)&(1<<16) )
|
|
mac_p->macStat.MIB_II.inMulticastPkts++;
|
|
else
|
|
mac_p->macStat.MIB_II.inUnicastPkts++;
|
|
}
|
|
|
|
(volatile struct sk_buff *)oldMbp = (volatile struct sk_buff *)(rxDescrp->skb);
|
|
#ifdef TCPHY_DEBUG
|
|
if(getTcPhyFlag()){
|
|
if(phyMbpChk(oldMbp) == 1){
|
|
newMbp = oldMbp;
|
|
goto RECVOK;
|
|
}
|
|
}
|
|
#endif
|
|
newMbp = skbmgr_dev_alloc_skb2k();
|
|
if ( !newMbp ) /* faild to allocate more mbuf -> drop this pkt */
|
|
{
|
|
newMbp = oldMbp;
|
|
mac_p->macStat.MIB_II.inDiscards++;
|
|
goto RECVOK;
|
|
}
|
|
/*Invaild the cache memory*/
|
|
dma_cache_inv((unsigned long)(newMbp->data), RX_MAX_PKT_LEN);
|
|
skb_reserve(newMbp, 2);
|
|
skb_put(oldMbp, frameSize);
|
|
|
|
#if defined(TCSUPPORT_CT)
|
|
#if defined(WAN2LAN) || defined(CONFIG_TC3162_ADSL)
|
|
#ifndef TC2031_SUPPORT
|
|
/*add specail tag function by xyzhu*/
|
|
if (macSTagFlag)
|
|
{
|
|
switch (swicVendor)
|
|
{
|
|
case SWIC_ADM6996M:
|
|
//macAdmSTagRemove(oldMbp);
|
|
break;
|
|
case SWIC_IP175C:
|
|
macIpSTagRemove(oldMbp);
|
|
break;
|
|
case SWIC_TC2206:
|
|
macTC2206STagRemove(oldMbp);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
#else
|
|
#if 1//defined(WAN2LAN) || defined(CONFIG_TC3162_ADSL) || defined(VPORT)
|
|
#ifndef TC2031_SUPPORT
|
|
/*add specail tag function by xyzhu*/
|
|
if (macSTagFlag)
|
|
{
|
|
switch (swicVendor)
|
|
{
|
|
case SWIC_ADM6996M:
|
|
//macAdmSTagRemove(oldMbp);
|
|
break;
|
|
case SWIC_IP175C:
|
|
macIpSTagRemove(oldMbp);
|
|
break;
|
|
case SWIC_TC2206:
|
|
macTC2206STagRemove(oldMbp);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#ifdef TCSUPPORT_AUTOBENCH
|
|
if( autobench_mac_lpbk_flag ){
|
|
|
|
if( memcmp(oldMbp->data, LoopbackData, MAC_LPBK_DATA_LEN) == 0 )
|
|
autobench_mac_lpbk_cnt++;
|
|
else{
|
|
|
|
int i;
|
|
for( i=0; i<MAC_LPBK_DATA_LEN; i++){
|
|
printk("%02x ", (unsigned char)oldMbp->data[i]);
|
|
if( (i+1)%8 == 0 )
|
|
printk("\n");
|
|
}
|
|
}
|
|
dev_kfree_skb_any(oldMbp);
|
|
goto RECVOK;
|
|
}
|
|
if( autobench_mac_lpbk1_flag ){
|
|
autobench_mac_lpbk_cnt++;
|
|
dev_kfree_skb_any(oldMbp);
|
|
goto RECVOK;
|
|
}
|
|
#endif
|
|
#ifdef EEE_DEBUG
|
|
if(dbgLevel & DUMP_RX_PKT){
|
|
dump_skb(oldMbp);
|
|
}
|
|
if (LOOPBACK_MODE(macLoopback) == LOOPBACK_TX) {
|
|
/*Used received the packets to send it.*/
|
|
tc3162_mac_tx(oldMbp, tc3162_mac_dev);
|
|
goto RECVOK;
|
|
}else if (LOOPBACK_MODE(macLoopback) == LOOPBACK_RX_CHK) {
|
|
tc3162_mac_loopback_chk(oldMbp, tc3162_mac_dev);
|
|
goto RECVOK;
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_TC3162_ADSL
|
|
if(tcconsole_proc(oldMbp)==1){
|
|
;
|
|
} else {
|
|
#else
|
|
{
|
|
#endif
|
|
oldMbp->dev = dev;
|
|
oldMbp->ip_summed = CHECKSUM_NONE;
|
|
oldMbp->protocol = eth_type_trans(oldMbp, dev);
|
|
dev->last_rx = jiffies;
|
|
#ifdef TC3162_MAC_NAPI
|
|
netif_receive_skb(oldMbp);
|
|
#else
|
|
netif_rx(oldMbp);
|
|
#endif
|
|
}
|
|
DISCARD:
|
|
|
|
RECVOK:
|
|
|
|
rxDescrp->rdes2.buf_p = K1_TO_PHY(newMbp->data);
|
|
rxDescrp->skb = newMbp;
|
|
}
|
|
else /* Update Error Counter and Drop it */
|
|
{
|
|
if ( mac_p->statisticOn )
|
|
{
|
|
if ( rxDescrp->rdes1.word&(1<<28) )
|
|
{
|
|
mac_p->macStat.inSilicon.rx802p3FrameLengthErr++;
|
|
mac_p->macStat.MIB_II.inErrors++;
|
|
}
|
|
if ( rxDescrp->rdes0.word&(1<<27) )
|
|
{
|
|
mac_p->macStat.inSilicon.rxPktIPChkSumErr++;
|
|
mac_p->macStat.MIB_II.inErrors++;
|
|
}
|
|
if ( rxDescrp->rdes0.word&(1<<22) )
|
|
{
|
|
mac_p->macStat.inSilicon.rxCollisionErr++;
|
|
mac_p->macStat.MIB_II.inErrors++;
|
|
}
|
|
if ( rxDescrp->rdes0.word&(1<<21) )
|
|
{
|
|
mac_p->macStat.inSilicon.rxRuntErr++;
|
|
mac_p->macStat.MIB_II.inErrors++;
|
|
}
|
|
if ( rxDescrp->rdes0.word&(1<<20) )
|
|
{
|
|
mac_p->macStat.inSilicon.rxLongErr++;
|
|
mac_p->macStat.MIB_II.inErrors++;
|
|
}
|
|
if ( rxDescrp->rdes0.word&(1<<19) )
|
|
{
|
|
mac_p->macStat.inSilicon.rxCrcErr++;
|
|
mac_p->macStat.MIB_II.inErrors++;
|
|
#ifdef TCPHY_DEBUG
|
|
if(getTcPhyFlag())
|
|
phy_recv_err_check(&oldMbp, rxDescrp, &frameSize);
|
|
#endif
|
|
}
|
|
if ( rxDescrp->rdes0.word&(1<<18) )
|
|
{
|
|
mac_p->macStat.inSilicon.rxMiiErr++;
|
|
mac_p->macStat.MIB_II.inErrors++;
|
|
}
|
|
} /* if mac_p->statisticOn */
|
|
}
|
|
|
|
rxDescrp->rdes0.word |= (1<<31);
|
|
|
|
/* next descriptor*/
|
|
if ( mac_p->rxCurrentDescp == ( mac_p->rxRingSize - 1 ))
|
|
mac_p->rxCurrentDescp = 0;
|
|
else
|
|
mac_p->rxCurrentDescp++;
|
|
|
|
rxDescrp = ((macRxDescr_t*)mac_p->rxDescrRingBaseVAddr) + mac_p->rxCurrentDescp;
|
|
} /* while loop */
|
|
|
|
VPint(CR_MAC_RXR_SWIDX) = mac_p->rxCurrentDescp;
|
|
#ifdef TC3162_MAC_NAPI
|
|
return npackets;
|
|
#endif
|
|
}
|
|
|
|
PUBLIC void
|
|
macControllerStop(macAdapter_t *mac_p)
|
|
{
|
|
macCtrlReg_t macCtrl;
|
|
|
|
macCtrl.value = VPint(CR_MAC_MACCR);
|
|
/* disable DMA tx& rx */
|
|
macCtrl.bits.rdma_en = 0;
|
|
macCtrl.bits.xdma_en = 0;
|
|
/* disable mac tx& rx */
|
|
macCtrl.bits.rcv_en = 0;
|
|
macCtrl.bits.xmt_en = 0;
|
|
VPint(CR_MAC_MACCR) = macCtrl.value;
|
|
}
|
|
|
|
PUBLIC macAdapter_t *
|
|
macGetAdapterByChanID(void)
|
|
{
|
|
return mac_p;
|
|
}
|
|
|
|
PUBLIC void
|
|
macGetMacAddr
|
|
(
|
|
macAdapter_t *mac_p
|
|
)
|
|
{
|
|
uint32 i;
|
|
|
|
for ( i = 0; i < 6; i++ )
|
|
{
|
|
mac_p->macAddr[i] = def_mac_addr[i];
|
|
}
|
|
}
|
|
|
|
PRIVATE int32
|
|
macPhyLookUp(
|
|
macAdapter_t *mac_p,
|
|
uint32 companyId
|
|
)
|
|
{
|
|
uint32 i;
|
|
uint32 phyTypeSupport;
|
|
|
|
phyTypeSupport = sizeof(phyDeviceList) / sizeof(phyDeviceList_t);
|
|
for ( i = 0; i < phyTypeSupport; i++ ) {
|
|
if ( companyId == phyDeviceList[i].companyId ) {
|
|
mac_p->enetPhyId = i;
|
|
#ifdef TCPHY_SUPPORT
|
|
if( companyId == 0x03a2 ){
|
|
tcPhyVerLookUp(mac_p);
|
|
}
|
|
#endif
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
PRIVATE int32
|
|
macSearchPhyAddr(
|
|
macAdapter_t *mac_p
|
|
)
|
|
{
|
|
uint32 miiReg = 0;
|
|
|
|
mac_p->enetPhyAddr = 0;
|
|
for ( mac_p->enetPhyAddr = 0; mac_p->enetPhyAddr < 32; mac_p->enetPhyAddr++ ) {
|
|
miiReg = miiStationRead(mac_p, PHY_ID_REG1);
|
|
if (miiReg == 0)
|
|
miiReg = miiStationRead(mac_p, PHY_ID_REG2);
|
|
if ( macPhyLookUp(mac_p, miiReg) ) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
mac_p->enetPhyAddr = 0x00000000;
|
|
|
|
return -1;
|
|
}
|
|
|
|
void
|
|
macPhyDisableLoopback(
|
|
macAdapter_t *mac_p
|
|
)
|
|
{
|
|
uint32 data;
|
|
|
|
data = miiStationRead(mac_p,PHY_CONFIG_REG);
|
|
data |= PHY_TP_LOOPBACK;
|
|
miiStationWrite(mac_p, PHY_CONFIG_REG, data);
|
|
}
|
|
|
|
PUBLIC int
|
|
macSetUpPhy
|
|
(
|
|
macAdapter_t *mac_p
|
|
)
|
|
{
|
|
if (isTC3162U) {
|
|
VPint(CR_AHB_SSR) |= (1<<11)|(1<<10)|(1<<9)|(1<<8);
|
|
pause(10);
|
|
}
|
|
else if (isRT63260){
|
|
VPint(CR_AHB_SSR) |= (1<<24);
|
|
pause(10);
|
|
}
|
|
|
|
/* ----- Hardware reset Ehernet phy chip, this address is defined by h/w engineer ----- */
|
|
ledTurnOn(LED_LAN_RESET);
|
|
pause(100);
|
|
/* ----- Wait for hardware reset completed ----- */
|
|
ledTurnOff(LED_LAN_RESET);
|
|
pause(600);
|
|
|
|
|
|
macSearchPhyAddr(mac_p);
|
|
|
|
macPhyReset();
|
|
pause(100);
|
|
|
|
/* Detect 4-port switch or single port switch */
|
|
/* detect if ADM6996M */
|
|
if (((tcAdmMiiStationRead(ADM_CHIP_ID0) & 0xfff0) == 0x1020) &&
|
|
(tcAdmMiiStationRead(ADM_CHIP_ID1) == 0x7)) {
|
|
swicVendor = SWIC_ADM6996M;
|
|
/* enable crossover auto detect */
|
|
tcAdmMiiStationWrite(ADM_PORT0_BASIC, tcAdmMiiStationRead(ADM_PORT0_BASIC)|0x8000);
|
|
tcAdmMiiStationWrite(ADM_PORT1_BASIC, tcAdmMiiStationRead(ADM_PORT1_BASIC)|0x8000);
|
|
tcAdmMiiStationWrite(ADM_PORT2_BASIC, tcAdmMiiStationRead(ADM_PORT2_BASIC)|0x8000);
|
|
tcAdmMiiStationWrite(ADM_PORT3_BASIC, tcAdmMiiStationRead(ADM_PORT3_BASIC)|0x8000);
|
|
}
|
|
/* detect if IP175C */
|
|
if ((tcMiiStationRead(4, 2) == 0x243) && (tcMiiStationRead(4, 3) == 0xd80)) {
|
|
swicVendor = SWIC_IP175C;
|
|
}
|
|
|
|
/* detect if RTL8305 or RTL8036SD Switch IC*/
|
|
if ((tcMiiStationRead(4, 2) == 0x1c) && (tcMiiStationRead(4, 3) == 0xc852)) {
|
|
if ((tcMiiStationRead(6, 2) == 0x1c) && (tcMiiStationRead(6, 3) == 0xc852) ){
|
|
swicVendor = SWIC_RTL8306SD;
|
|
/*Let CPU Port Link up*/
|
|
tcMiiStationWrite(5, 22,tcMiiStationRead(5,22)|0x8000);
|
|
tcMiiStationWrite(6, 22,tcMiiStationRead(6,22)|0x8000);
|
|
}
|
|
else{
|
|
swicVendor = SWIC_RTL8305;
|
|
}
|
|
}
|
|
#ifdef TCPHY_4PORT
|
|
/*Switch Model Number Register (SMNR), Addr.: 16'h02FE*/
|
|
if (tcMiiStationRead(31, 31) == 0x2206){
|
|
swicVendor = SWIC_TC2206;
|
|
filedSwicDefVal();
|
|
printk("TC2206, ");
|
|
}
|
|
#endif
|
|
/* detect if MARVEL 88E6060 */
|
|
if (((tcMiiStationRead(4, 2) == 0x141) || (tcMiiStationRead(20, 2) == 0x141)) &&
|
|
((tcMiiStationRead(4, 3) == 0xc87) || (tcMiiStationRead(20, 3) == 0xc87)))
|
|
{
|
|
swicVendor = SWIC_MARVEL6060;
|
|
}
|
|
|
|
if( swicVendor )
|
|
{
|
|
}
|
|
|
|
/* ----- Set up Ethernet link speed, using auto negotiation ----- */
|
|
mac_p->macPhyLinkProfile_p->linkSpeed = MIIDR_AUTO_NEGOTIATE;
|
|
mac_p->macPhyLinkProfile_p->duplexMode = 0;
|
|
|
|
#ifdef TCPHY_SUPPORT
|
|
if(getTcPhyFlag() == 0)
|
|
{
|
|
#endif
|
|
if( !swicVendor )
|
|
{
|
|
if ( mac_p->macPhyLinkProfile_p->linkSpeed == MIIDR_AUTO_NEGOTIATE )
|
|
{
|
|
miiStationWrite(mac_p, PHY_CONTROL_REG, MIIDR_AUTO_NEGOTIATE );
|
|
pause(50); /* Timothy debug 1221, without this, negotiation is wrong... */
|
|
}
|
|
/* disable loopback mode */
|
|
macPhyDisableLoopback( mac_p );
|
|
}
|
|
#ifdef TCPHY_SUPPORT
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
PUBLIC uint8
|
|
macInit
|
|
(
|
|
void
|
|
)
|
|
{
|
|
if (macInitialized)
|
|
return 0;
|
|
|
|
macControllerStop(mac_p);
|
|
|
|
/* ----- Get Mac Adapter from dummy data or NDIS control block ----- */
|
|
mac_p = macGetAdapterByChanID();
|
|
#if defined(TCSUPPORT_CT)
|
|
memset(mac_p, 0x0, sizeof(macAdapter_t));
|
|
#else
|
|
/*reset this segment will clear lock state. shnwind 20101129.*/
|
|
//memset(mac_p, 0x0, sizeof(macAdapter_t));
|
|
|
|
#endif
|
|
/* ----- Assign reserved data pointer ----- */
|
|
mac_p->macPhyLinkProfile_p = &enetPhyLinkProfile;
|
|
#ifdef DYNAMIC_ALLOC_DMA_BUF
|
|
enetMemPool = kmalloc(sizeof(macMemPool_t), GFP_ATOMIC | GFP_DMA);
|
|
if (enetMemPool == NULL) {
|
|
printk("unable to kmalloc enetMemPool structure.\n");
|
|
return -1;
|
|
}
|
|
mac_p->macMemPool_p = enetMemPool;
|
|
#else
|
|
mac_p->macMemPool_p = &enetMemPool;
|
|
#endif
|
|
|
|
/* ----- Set up the paramters ----- */
|
|
macDefaultParaSet(mac_p);
|
|
|
|
/* ----- Get the Mac address ----- */
|
|
macGetMacAddr(mac_p);
|
|
|
|
/* ----- Initialize Tx/Rx descriptors ----- */
|
|
if( macInitialized == 0)
|
|
{
|
|
if ( macDrvDescripInit(mac_p) != 0 )
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
macDrvDescripReset( mac_p );
|
|
}
|
|
|
|
/* ----- Initialize the SEEQ 80225 phy chip(enet phy) ----- */
|
|
if ( macSetUpPhy(mac_p) )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
/* ----- Initialize Registers ----- */
|
|
macDrvRegInit(mac_p);
|
|
|
|
mac_p->statisticOn = MAC_STATISTIC_ON;
|
|
#if defined(WAN2LAN) || defined(CONFIG_TC3162_ADSL)
|
|
#ifndef TC2031_SUPPORT
|
|
/* ------ xyzhu_nj_091104:Enable special Tag default ----- */
|
|
macRxPortEnable(0);
|
|
#endif
|
|
#endif
|
|
|
|
macInitialized = 1;
|
|
macDrvStart();
|
|
|
|
return 0;
|
|
}
|
|
|
|
/************************************************************************
|
|
* A D S L R E L A T E D F U N C T I O N S
|
|
*************************************************************************
|
|
*/
|
|
|
|
struct sk_buff_head adsl_pkt_queue;
|
|
struct work_struct tq_adsl;
|
|
struct work_struct tq_mac;
|
|
|
|
void tc3162_emac_poll(void)
|
|
{
|
|
tc3162_mac_isr(tc3162_mac_dev->irq, tc3162_mac_dev);
|
|
}
|
|
|
|
static void tc3162_mac_poll(unsigned long data)
|
|
{
|
|
#ifdef CONFIG_TC3162_ADSL
|
|
uint8 modemst;
|
|
|
|
if (adsl_dev_ops == NULL)
|
|
goto down_proc;
|
|
|
|
adsl_dev_ops->query(ADSL_QUERY_STATUS, &modemst, NULL);
|
|
switch (modemst) {
|
|
case ADSL_MODEM_STATE_DOWN:
|
|
down_proc:
|
|
mod_timer(ð_poll_timer, jiffies + (HZ / 2));
|
|
break;
|
|
case ADSL_MODEM_STATE_WAIT_INIT:
|
|
/* polling ethernet */
|
|
if (!(VPint(CR_INTC_IMR) & (1 << MAC_INT)))
|
|
tc3162_emac_poll();
|
|
mod_timer(ð_poll_timer, jiffies + (HZ / 10));
|
|
break;
|
|
case ADSL_MODEM_STATE_INIT:
|
|
/* polling ethernet */
|
|
if (!(VPint(CR_INTC_IMR) & (1 << MAC_INT)))
|
|
schedule_work(&tq_mac);
|
|
mod_timer(ð_poll_timer, jiffies + (HZ / 10));
|
|
break;
|
|
case ADSL_MODEM_STATE_UP:
|
|
mod_timer(ð_poll_timer, jiffies + (HZ / 2));
|
|
break;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static void tc3162_mac_poll_rcv(struct work_struct *work)
|
|
{
|
|
/* polling ethernet */
|
|
if (!(VPint(CR_INTC_IMR) & (1 << MAC_INT)))
|
|
tc3162_emac_poll();
|
|
}
|
|
|
|
void TCConsole(uint8 mode)
|
|
{
|
|
}
|
|
EXPORT_SYMBOL(TCConsole);
|
|
|
|
void uartMacPutchar(int ch)
|
|
{
|
|
}
|
|
EXPORT_SYMBOL(uartMacPutchar);
|
|
|
|
|
|
static void macSendReal(struct work_struct *work)
|
|
{
|
|
for (;;) {
|
|
struct sk_buff *skb;
|
|
|
|
local_irq_disable();
|
|
skb = __skb_dequeue(&adsl_pkt_queue);
|
|
if (skb == NULL) {
|
|
local_irq_enable();
|
|
break;
|
|
}
|
|
tc3162_mac_tx(skb, tc3162_mac_dev);
|
|
local_irq_enable();
|
|
}
|
|
}
|
|
|
|
uint32 GetIpAddr(void)
|
|
{
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(GetIpAddr);
|
|
|
|
uint8 *GetMacAddr(void)
|
|
{
|
|
static uint8 macAddr[7];
|
|
|
|
memcpy(macAddr, def_mac_addr, 6);
|
|
macAddr[6] = 0x0;
|
|
return macAddr;
|
|
}
|
|
EXPORT_SYMBOL(GetMacAddr);
|
|
|
|
/************************************************************************
|
|
* E T H E R N E T D E V I C E P R O C D E F I N I T I O N S
|
|
*************************************************************************
|
|
*/
|
|
|
|
#define CHK_BUF() pos = begin + index; if (pos < off) { index = 0; begin = pos; }; if (pos > off + count) goto done;
|
|
|
|
static int getETHLinkSt(char *buf)
|
|
{
|
|
uint16 index = 0;
|
|
|
|
if ((mac_p == NULL) || (mac_p->macPhyLinkProfile_p == NULL)
|
|
|| (mac_p->macPhyLinkProfile_p->enetMode == 0)) {
|
|
index += sprintf(buf+index, "Down\n");
|
|
return index;
|
|
}
|
|
|
|
if (mac_p->macPhyLinkProfile_p->enetMode & LAN_ST_100MB)
|
|
index += sprintf(buf+index, "100M/");
|
|
else
|
|
index += sprintf(buf+index, "10M/");
|
|
if (mac_p->macPhyLinkProfile_p->enetMode & LAN_ST_FULL_DUPLEX)
|
|
index += sprintf(buf+index, "Full Duplex\n");
|
|
else
|
|
index += sprintf(buf+index, "Half Duplex\n");
|
|
return index;
|
|
}
|
|
|
|
static int eth_stats_read_proc(char *buf, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
int index = 0;
|
|
off_t pos = 0;
|
|
off_t begin = 0;
|
|
|
|
if (!macInitialized) {
|
|
*eof = 1;
|
|
return 0;
|
|
}
|
|
|
|
index += sprintf(buf+index, "inOctets = 0x%08lx, ", mac_p->macStat.MIB_II.inOctets);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "inUnicastPkts = 0x%08lx\n", mac_p->macStat.MIB_II.inUnicastPkts);
|
|
CHK_BUF();
|
|
|
|
index += sprintf(buf+index, "inMulticastPkts = 0x%08lx, ", mac_p->macStat.MIB_II.inMulticastPkts);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "inDiscards = 0x%08lx\n", mac_p->macStat.MIB_II.inDiscards);
|
|
CHK_BUF();
|
|
|
|
index += sprintf(buf+index, "inErrors = 0x%08lx, ", mac_p->macStat.MIB_II.inErrors);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "outOctets = 0x%08lx\n", mac_p->macStat.MIB_II.outOctets);
|
|
CHK_BUF();
|
|
|
|
index += sprintf(buf+index, "outUnicastPkts = 0x%08lx, ", mac_p->macStat.MIB_II.outUnicastPkts);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "outMulticastPkts = 0x%08lx\n", mac_p->macStat.MIB_II.outMulticastPkts);
|
|
CHK_BUF();
|
|
|
|
index += sprintf(buf+index, "outDiscards = 0x%08lx, ", mac_p->macStat.MIB_II.outDiscards);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "outErrors = 0x%08lx\n", mac_p->macStat.MIB_II.outErrors);
|
|
CHK_BUF();
|
|
|
|
index += sprintf(buf+index, "\n[ inSilicon Statistics Display ]\n");
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "txJabberTimeCnt = 0x%08lx ", mac_p->macStat.inSilicon.txJabberTimeCnt);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "txLossOfCarrierCnt = 0x%08lx\n", mac_p->macStat.inSilicon.txLossOfCarrierCnt);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "txNoCarrierCnt = 0x%08lx ", mac_p->macStat.inSilicon.txNoCarrierCnt);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "txLateCollisionCnt = 0x%08lx\n", mac_p->macStat.inSilicon.txLateCollisionCnt);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "txExCollisionCnt = 0x%08lx ", mac_p->macStat.inSilicon.txExCollisionCnt);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "txHeartbeatFailCnt = 0x%08lx\n", mac_p->macStat.inSilicon.txHeartbeatFailCnt);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "txCollisionCnt = 0x%08lx ", mac_p->macStat.inSilicon.txCollisionCnt);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "txExDeferralCnt = 0x%08lx\n", mac_p->macStat.inSilicon.txExDeferralCnt);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "txUnderRunCnt = 0x%08lx ", mac_p->macStat.inSilicon.txUnderRunCnt);
|
|
CHK_BUF();
|
|
|
|
index += sprintf(buf+index, "rxAlignErr = 0x%08lx\n", mac_p->macStat.inSilicon.rxAlignErr);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "rxDribblingErr = 0x%08lx ", mac_p->macStat.inSilicon.rxDribblingErr);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "rxSymbolErr = 0x%08lx\n", mac_p->macStat.inSilicon.rxSymbolErr);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "rxMiiErr = 0x%08lx ", mac_p->macStat.inSilicon.rxMiiErr);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "rxCollisionErr = 0x%08lx\n", mac_p->macStat.inSilicon.rxCollisionErr);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "rxCrcErr = 0x%08lx ", mac_p->macStat.inSilicon.rxCrcErr);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "rxEtherFrameLengthErr = 0x%08lx\n", mac_p->macStat.inSilicon.rxEtherFrameLengthErr);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "rx802p3FrameLengthErr = 0x%08lx ", mac_p->macStat.inSilicon.rx802p3FrameLengthErr);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "rxPktIPChkSumErr = 0x%08lx\n", mac_p->macStat.inSilicon.rxPktIPChkSumErr);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "rxRuntErr = 0x%08lx ", mac_p->macStat.inSilicon.rxRuntErr);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "rxLongErr = 0x%08lx\n", mac_p->macStat.inSilicon.rxLongErr);
|
|
CHK_BUF();
|
|
#if !defined(TCSUPPORT_CT)
|
|
index += sprintf(buf+index, "rxOverrunInt = 0x%08lx\n", mac_p->macStat.inSilicon.rxOverrunInt);
|
|
CHK_BUF();
|
|
|
|
#endif
|
|
index += sprintf(buf+index, "\n[ Extra information ]\n");
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "Rx Descriptor idx = 0x%08lx ", mac_p->rxCurrentDescp);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "Tx Descriptor idx = 0x%08lx\n", mac_p->txCurrentDescp);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "Rx Enqueued cnt = 0x%08lx ", mac_p->macStat.inSilicon.rxEnQueueNum);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "Tx Enqueued cnt = 0x%08lx\n", mac_p->macStat.inSilicon.txEnQueueNum);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "Rx Dequeued cnt = 0x%08lx ", mac_p->macStat.inSilicon.rxDeQueueNum);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "Tx Dequeued cnt = 0x%08lx\n", mac_p->macStat.inSilicon.txDeQueueNum);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "Tx Buf UnReleased cnt = 0x%08lx ", mac_p->txUnReleasedBufCnt);
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "Tx Buf UnReleased idx = 0x%08lx\n", mac_p->txUnReleasedDescp);
|
|
CHK_BUF();
|
|
|
|
*eof = 1;
|
|
|
|
done:
|
|
*start = buf + (off - begin);
|
|
index -= (off - begin);
|
|
if (index<0)
|
|
index = 0;
|
|
if (index>count)
|
|
index = count;
|
|
return index;
|
|
}
|
|
|
|
static int eth_stats_write_proc(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
char val_string[32];
|
|
|
|
if (count > sizeof(val_string) - 1)
|
|
return -EINVAL;
|
|
|
|
if (copy_from_user(val_string, buffer, count))
|
|
return -EFAULT;
|
|
|
|
val_string[count] = '\0';
|
|
|
|
if (!macInitialized) {
|
|
return 0;
|
|
}
|
|
|
|
memset(&mac_p->macStat.MIB_II, 0, sizeof(macMIB_II_t));
|
|
memset(&mac_p->macStat.inSilicon, 0, sizeof(inSiliconStat_t));
|
|
|
|
return count;
|
|
}
|
|
|
|
#if 0
|
|
/* support port reverse */
|
|
static int port_reverse_read_proc(char *buf, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
int index = 0;
|
|
off_t pos = 0;
|
|
off_t begin = 0;
|
|
|
|
index += sprintf(buf+index, "%d\n", g_port_reverse);
|
|
CHK_BUF();
|
|
|
|
*eof = 1;
|
|
|
|
done:
|
|
*start = buf + (off - begin);
|
|
index -= (off - begin);
|
|
if (index<0)
|
|
index = 0;
|
|
if (index>count)
|
|
index = count;
|
|
return index;
|
|
}
|
|
static int port_reverse_write_proc(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
int len;
|
|
char get_buf[32];
|
|
|
|
/* do a range checking, don't overflow buffers in kernel modules */
|
|
if(count > 32)
|
|
len = 32;
|
|
else
|
|
len = count;
|
|
|
|
if(copy_from_user(get_buf, buffer, len))
|
|
return -EFAULT;
|
|
|
|
get_buf[len]='\0';
|
|
|
|
//printk("get_buf is aa%s\n", get_buf);
|
|
|
|
g_port_reverse = atoi(get_buf);
|
|
|
|
/* debug */
|
|
//printk("g_port_reverse is %d\n", g_port_reverse);
|
|
|
|
return len;
|
|
}
|
|
#endif
|
|
|
|
int eth_link_st_proc(char *buf, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
int len = getETHLinkSt(buf);
|
|
if (len <= off+count)
|
|
*eof = 1;
|
|
*start = buf + off;
|
|
len -= off;
|
|
if (len>count)
|
|
len = count;
|
|
if (len<0)
|
|
len = 0;
|
|
return len;
|
|
}
|
|
|
|
int eth_reg_dump_proc(char *buf, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
int index = 0;
|
|
off_t pos = 0;
|
|
off_t begin = 0;
|
|
int i;
|
|
uint32 reg;
|
|
|
|
if (!macInitialized) {
|
|
*eof = 1;
|
|
return 0;
|
|
}
|
|
|
|
index += sprintf(buf+index, "CR_MAC_ISR (BFB50000) = 0x%08lx\n", VPint(CR_MAC_ISR)); // --- Interrupt Status Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_IMR (BFB50004) = 0x%08lx\n", VPint(CR_MAC_IMR)); // --- Interrupt Mask Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_MADR (BFB50008) = 0x%08lx\n", VPint(CR_MAC_MADR)); // --- MAC Address Register [47:32] ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_LADR (BFB5000c) = 0x%08lx\n", VPint(CR_MAC_LADR)); // --- MAC Address Register [31:0] ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_TXPD (BFB50018) = 0x%08lx\n", VPint(CR_MAC_TXPD)); // --- Transmit Poll Demand Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_RXPD (BFB5001c) = 0x%08lx\n", VPint(CR_MAC_RXPD)); // --- Receive Poll Demand Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_TXR_BADR (BFB50020) = 0x%08lx\n", VPint(CR_MAC_TXR_BADR)); // --- Transmit Ring Base Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_RXR_BADR (BFB50024) = 0x%08lx\n", VPint(CR_MAC_RXR_BADR)); // --- Receive Ring Base Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_ITC (BFB50028) = 0x%08lx\n", VPint(CR_MAC_ITC)); // --- Interrupt Timer Control Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_TXR_SIZE (BFB5002c) = 0x%08lx\n", VPint(CR_MAC_TXR_SIZE)); // --- Automatic Polling Timer Control Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_RXR_SIZE (BFB50030) = 0x%08lx\n", VPint(CR_MAC_RXR_SIZE)); // --- DMA Burst Length and Arbitration Control Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_RXR_SWIDX (BFB50034) = 0x%08lx\n", VPint(CR_MAC_RXR_SWIDX)); // --- DMA Burst Length and Arbitration Control Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_TXDESP_SIZE (BFB50038) = 0x%08lx\n", VPint(CR_MAC_TXDESP_SIZE)); // --- Transmit Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_RXDESP_SIZE (BFB5003c) = 0x%08lx\n", VPint(CR_MAC_RXDESP_SIZE)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_PRIORITY_CFG (BFB50050) = 0x%08lx\n", VPint(CR_MAC_PRIORITY_CFG)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_VLAN_CFG (BFB50054) = 0x%08lx\n", VPint(CR_MAC_VLAN_CFG)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_TOS0_CFG (BFB50058) = 0x%08lx\n", VPint(CR_MAC_TOS0_CFG)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_TOS1_CFG (BFB5005c) = 0x%08lx\n", VPint(CR_MAC_TOS1_CFG)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_TOS2_CFG (BFB50060) = 0x%08lx\n", VPint(CR_MAC_TOS2_CFG)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_TOS3_CFG (BFB50064) = 0x%08lx\n", VPint(CR_MAC_TOS3_CFG)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_TCP_CFG (BFB50068) = 0x%08lx\n", VPint(CR_MAC_TCP_CFG)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_SWTAG_CFG (BFB5006c) = 0x%08lx\n", VPint(CR_MAC_SWTAG_CFG)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_PMBL_CYC_NUM (BFB50070) = 0x%08lx\n", VPint(CR_MAC_PMBL_CYC_NUM)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_FCTL_CYC_NUM (BFB50074) = 0x%08lx\n", VPint(CR_MAC_FCTL_CYC_NUM)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_JAM_CYC_NUM (BFB50078) = 0x%08lx\n", VPint(CR_MAC_JAM_CYC_NUM)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_DEFER_VAL (BFB5007c) = 0x%08lx\n", VPint(CR_MAC_DEFER_VAL)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_RANDOM_POLY (BFB50080) = 0x%08lx\n", VPint(CR_MAC_RANDOM_POLY)); // --- Receive Address Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_MACCR (BFB50088) = 0x%08lx\n", VPint(CR_MAC_MACCR)); // --- MAC Control Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_MACSR (BFB5008c) = 0x%08lx\n", VPint(CR_MAC_MACSR)); // --- MAC Status Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_PHYCR (BFB50090) = 0x%08lx\n", VPint(CR_MAC_PHYCR)); // --- PHY Control Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_PHYWDATA (BFB50094) = 0x%08lx\n", VPint(CR_MAC_PHYWDATA)); // --- PHY Write Data Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_FCR (BFB50098) = 0x%08lx\n", VPint(CR_MAC_FCR)); // --- Flow Control Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_BPR (BFB5009c) = 0x%08lx\n", VPint(CR_MAC_BPR)); // --- Back Pressure Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_TM (BFB500cc) = 0x%08lx\n", VPint(CR_MAC_TM)); // --- Test Mode Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_XMPG_CNT (BFB500dc) = 0x%08lx\n", VPint(CR_MAC_XMPG_CNT)); // --- XM and PG Counter Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_RUNT_TLCC_CNT(BFB500e0) = 0x%08lx\n", VPint(CR_MAC_RUNT_TLCC_CNT)); // --- Runt and Late Collision Packet Counter Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_RCRC_RLONG_CNT(BFB500e4) = 0x%08lx\n", VPint(CR_MAC_RCRC_RLONG_CNT)); // --- CRC and Long Packet Counter Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_RLOSS_RCOL_CNT(BFB500e8) = 0x%08lx\n", VPint(CR_MAC_RLOSS_RCOL_CNT)); // --- Receive Packet Loss and Receive Collision Counter Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_BROADCAST_CNT(BFB500ec) = 0x%08lx\n", VPint(CR_MAC_BROADCAST_CNT)); // --- Receive Broadcast Counter Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_MULTICAST_CNT(BFB500f0) = 0x%08lx\n", VPint(CR_MAC_MULTICAST_CNT)); // --- Receive Multicast Counter Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_RX_CNT (BFB500f4) = 0x%08lx\n", VPint(CR_MAC_RX_CNT)); // --- Receive Good Packet Counter Register ---
|
|
CHK_BUF();
|
|
index += sprintf(buf+index, "CR_MAC_TX_CNT (BFB500f8) = 0x%08lx\n", VPint(CR_MAC_TX_CNT)); // --- Transmit Good Packet Counter Register ---
|
|
CHK_BUF();
|
|
|
|
index += sprintf(buf+index, "[PHY REG] PHYADDR=%d\n", mac_p->enetPhyId);
|
|
CHK_BUF();
|
|
for (i = 0; i <= 8; i++) {
|
|
reg = miiStationRead(mac_p, i);
|
|
index += sprintf(buf+index, "PHY reg%d=0x%08lx\n", i, reg);
|
|
CHK_BUF();
|
|
}
|
|
|
|
reg = miiStationRead(mac_p, 10);
|
|
index += sprintf(buf+index, "PHY reg%d=0x%08lx\n", 10, reg);
|
|
CHK_BUF();
|
|
|
|
for (i = 16; i <= 20; i++) {
|
|
reg = miiStationRead(mac_p, i);
|
|
index += sprintf(buf+index, "PHY reg%d=0x%08lx\n", i, reg);
|
|
CHK_BUF();
|
|
}
|
|
|
|
reg = miiStationRead(mac_p, 30);
|
|
index += sprintf(buf+index, "PHY reg%d=0x%08lx\n", 30, reg);
|
|
CHK_BUF();
|
|
|
|
*eof = 1;
|
|
|
|
done:
|
|
*start = buf + (off - begin);
|
|
index -= (off - begin);
|
|
if (index<0)
|
|
index = 0;
|
|
if (index>count)
|
|
index = count;
|
|
return index;
|
|
}
|
|
|
|
#ifdef TCPHY_SUPPORT
|
|
/*_____________________________________________________________________________
|
|
** function name: periodChk
|
|
** descriptions:
|
|
** The periodic check TC phy or switch register, and make sure
|
|
** the ethernet can be work.
|
|
**
|
|
** parameters:
|
|
** None
|
|
**
|
|
** global:
|
|
** None
|
|
**
|
|
** return:
|
|
** None
|
|
**
|
|
** call:
|
|
** getTcPhyFlag
|
|
** esdSwPatch
|
|
** updatingUpnpGid
|
|
** tcPhyChkVal
|
|
** tcPhyErrMonitor
|
|
**
|
|
** revision:
|
|
** 1. Here 2010/05/11
|
|
**____________________________________________________________________________
|
|
*/
|
|
void
|
|
periodChk(void){
|
|
if (getTcPhyFlag()){
|
|
tcPhySwPatch();
|
|
#ifdef TCPHY_4PORT
|
|
esdSwPatch();
|
|
/*Workaroud to fix hardware igmpsnoop function actived then
|
|
the upnp multicast packet will be drop.(239.255.255.250)*/
|
|
updatingUpnpGid();
|
|
#endif
|
|
#ifdef TCPHY_DEBUG
|
|
tcPhyChkVal();
|
|
tcPhyErrMonitor();
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
#if defined(TCSUPPORT_ETHER_ALL_LED)
|
|
/* if all of LAN ports is link down ,return 0;otherwise ,return 1*/
|
|
|
|
int ether_states_handler(void)
|
|
{
|
|
uint32 tx_pkt_num=0,rx_pkt_num=0,pkt_num=0;;
|
|
int i =0,port_num =0,ret = 0;
|
|
uint8 speed;
|
|
|
|
if(macSTagFlag){
|
|
#ifdef TCSUPPORT_2PORTS
|
|
port_num = 2;
|
|
#else
|
|
port_num = 4;
|
|
#endif
|
|
}else{
|
|
port_num = 1;
|
|
}
|
|
|
|
if(swicVendor == SWIC_TC2206){
|
|
for (i=0; i< port_num; i++){
|
|
pkt_num=tcMiiStationRead(i, MII_BMSR);
|
|
if(pkt_num&BMSR_LSTATUS){
|
|
ret ++; //test
|
|
tcMiiStationWrite(22,16,((i<<12)+0x0001));
|
|
rx_pkt_num += (tcMiiStationRead(22,17)<<16)+tcMiiStationRead(22,18);
|
|
tx_pkt_num += (tcMiiStationRead(22,25)<<16)+tcMiiStationRead(22,26);
|
|
}
|
|
}
|
|
if(ret){
|
|
pkt_num = rx_pkt_num + tx_pkt_num;
|
|
if(pkt_num > (ether_speed[0]?ether_speed[0]:200)){
|
|
speed = 1;
|
|
}else if(pkt_num > (ether_speed[1]?ether_speed[1]:150)){
|
|
speed = 2;
|
|
}else if(pkt_num > (ether_speed[2]?ether_speed[2]:100)){
|
|
speed = 4;
|
|
}else if(pkt_num > (ether_speed[3]?ether_speed[3]:50)){
|
|
speed = 8;
|
|
}else if(pkt_num > 0){
|
|
speed = 16;
|
|
}else speed = 0;
|
|
//printk("port,rx,tx,speed=%d,%x,%x,%d\n",ret,rx_pkt_num,tx_pkt_num,speed);
|
|
|
|
if(pkt_num > 0){
|
|
if(ether_lan_speed == 0){//ledturnon will change blink speed
|
|
//ledTurnOff(LED_ETHER_STATUS);
|
|
ledTurnOn(LED_ETHER_ACT_STATUS);
|
|
ledTurnOff(LED_ETHER_NOACT_STATUS);
|
|
}
|
|
}
|
|
else{
|
|
if(ether_lan_speed){
|
|
//ledTurnOn(LED_ETHER_STATUS);
|
|
ledTurnOff(LED_ETHER_ACT_STATUS);
|
|
ledTurnOn(LED_ETHER_NOACT_STATUS);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(ret == 0){ //no port conncect
|
|
speed = 0;
|
|
//ledTurnOff(LED_ETHER_STATUS);
|
|
ledTurnOff(LED_ETHER_ACT_STATUS);
|
|
ledTurnOff(LED_ETHER_NOACT_STATUS);
|
|
}
|
|
ether_lan_speed = speed;
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
/* Monitor the status of link, re-do link initialization if necessary. */
|
|
static void tc3162_mac_link_status(unsigned long data)
|
|
{
|
|
uint32 status = 0;
|
|
macCtrlReg_t macCtrl;
|
|
|
|
#if defined(TCSUPPORT_ETHER_ALL_LED)
|
|
static uint8 index = 0;
|
|
if(index++ >= 1){ //3 500ms 1 1s
|
|
index = 0;
|
|
#endif
|
|
#ifdef TCPHY_DEBUG
|
|
if (getTcPhyFlag()){
|
|
if( getTcPhyForceLinkFlag() == 1){
|
|
mac_p->macPhyLinkProfile_p->enetMode = LAN_ST_CONNECTED | LAN_ST_LINK_UP ;
|
|
goto leave;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef TCPHY_SUPPORT
|
|
periodChk();
|
|
#endif
|
|
|
|
#ifdef TC_CONSOLE_ENABLE
|
|
tcconsole_chk();
|
|
#endif
|
|
|
|
#ifdef EEE_SUPPORT
|
|
/*According the ethernet PHY link status to enable
|
|
or disable eee function, if link is down to disable
|
|
eee function,If the link is up, we need to wait 1
|
|
second then to enable psm function.*/
|
|
chkLinkStatus();
|
|
#endif
|
|
|
|
if (mac_p == NULL)
|
|
goto leave;
|
|
|
|
if( swicVendor ) {
|
|
mac_p->macPhyLinkProfile_p->enetMode = LAN_ST_100MB | LAN_ST_FULL_DUPLEX | LAN_ST_LINK_UP ;
|
|
} else {
|
|
mac_p->macPhyLinkProfile_p->enetMode = 0;
|
|
status = miiStationRead(mac_p, PHY_CONTROL_REG);
|
|
|
|
/* ----- Check reset bit & power down bit ----- */
|
|
if ( status & (PHY_RESET | PHY_POWER_DOWN) )
|
|
{
|
|
goto leave;
|
|
}
|
|
#ifdef TCPHY_SUPPORT
|
|
if (getTcPhyFlag())
|
|
status = getTcPhyStatusReg(mac_p);
|
|
else
|
|
#endif
|
|
status = miiStationRead(mac_p, PHY_STATUS_REG);
|
|
if ( status & PHY_AN_COMPLETE ) {
|
|
if ( mac_p->macPhyLinkProfile_p->ANCompFlag != 1 ) {
|
|
mac_p->macPhyLinkProfile_p->ANCompFlag = 1;
|
|
miiStationWrite(mac_p, PHY_CONTROL_REG, PHY_AN_ENABLE);
|
|
}
|
|
}
|
|
if ( status & PHY_LINK_STATUS ) {
|
|
mac_p->macPhyLinkProfile_p->enetMode |= LAN_ST_LINK_UP;
|
|
/* ----- Read remote capability register for link speed ----- */
|
|
#ifdef TCPHY_SUPPORT
|
|
if (getTcPhyFlag())
|
|
status = getTcPhyRMCAPReg(mac_p);
|
|
else
|
|
#endif
|
|
status = miiStationRead(mac_p, PHY_REMOTE_CAP_REG);
|
|
if ( status & PHY_100_BASE_TX_FD ) {
|
|
mac_p->macPhyLinkProfile_p->enetMode |= (LAN_ST_FULL_DUPLEX | LAN_ST_100MB);
|
|
} else if ( status & PHY_100_BASE_TX_HD ) {
|
|
mac_p->macPhyLinkProfile_p->enetMode |= (LAN_ST_100MB);
|
|
} else if ( status & PHY_10_BASE_T_FD ) {
|
|
mac_p->macPhyLinkProfile_p->enetMode |= (LAN_ST_FULL_DUPLEX);
|
|
} else if ( (status & PHY_10_BASE_T_HD) == 0 ) {
|
|
mac_p->macPhyLinkProfile_p->enetMode = 0;
|
|
}
|
|
} /* if status & PHY_LINK_STATUS */
|
|
}
|
|
#ifdef TCPHY_DEBUG
|
|
if(!getTcPhyLookbackFlag() && getTcPhyFlag()){
|
|
#endif
|
|
/* lino: according to enet phy link mode to adjust mac full duplex mode or not */
|
|
macCtrl.value = VPint(CR_MAC_MACCR);
|
|
macCtrl.bits.fulltx = (mac_p->macPhyLinkProfile_p->enetMode & LAN_ST_FULL_DUPLEX) ? 1 : 0;
|
|
VPint(CR_MAC_MACCR) = macCtrl.value;
|
|
#ifdef TCPHY_DEBUG
|
|
}
|
|
#endif
|
|
#if defined(TCSUPPORT_ETHER_ALL_LED)
|
|
}
|
|
ether_states_handler();
|
|
#endif
|
|
|
|
leave:
|
|
/* Schedule for the next time */
|
|
#ifdef TC2031_SUPPORT
|
|
eth_timer.expires = jiffies + (HZ / 2);
|
|
#else
|
|
#if defined(TCSUPPORT_ETHER_ALL_LED)
|
|
eth_timer.expires = jiffies + (HZ * 2);
|
|
#else
|
|
eth_timer.expires = jiffies + (HZ);//(HZ * 2); 500ms HZ/2 1s HZ 2s HZ*2
|
|
#endif
|
|
#endif
|
|
add_timer(ð_timer);
|
|
|
|
}
|
|
#ifdef TCPHY_DEBUG
|
|
/*_____________________________________________________________________________
|
|
** function name: macClearCnt
|
|
** descriptions:
|
|
** clear all mac counters
|
|
**
|
|
** parameters:
|
|
** none
|
|
** global:
|
|
** None
|
|
**
|
|
** return:
|
|
** none
|
|
**
|
|
** call:
|
|
**
|
|
** revision:
|
|
**
|
|
**____________________________________________________________________________
|
|
*/
|
|
void macClearCnt(void)
|
|
{
|
|
|
|
uint8 *erase_p;
|
|
|
|
erase_p = (uint8 *)(&mac_p->macStat.MIB_II);
|
|
|
|
memset(erase_p+4,0,sizeof(macMIB_II_t) - 4);
|
|
memset(&mac_p->macStat.inSilicon, 0, sizeof(inSiliconStat_t));
|
|
|
|
}
|
|
|
|
/*_____________________________________________________________________________
|
|
** function name: macDispCnt
|
|
** descriptions:
|
|
** display all mac counters
|
|
**
|
|
** parameters:
|
|
** none
|
|
** global:
|
|
** None
|
|
**
|
|
** return:
|
|
** none
|
|
**
|
|
** call:
|
|
**
|
|
** revision:
|
|
**
|
|
**____________________________________________________________________________
|
|
*/
|
|
void macDispCnt(void)
|
|
{
|
|
|
|
printk("inOctets = 0x%08lx, ", mac_p->macStat.MIB_II.inOctets);
|
|
printk("inUnicastPkts = 0x%08lx\n", mac_p->macStat.MIB_II.inUnicastPkts);
|
|
printk("inMulticastPkts = 0x%08lx, ", mac_p->macStat.MIB_II.inMulticastPkts);
|
|
printk("inDiscards = 0x%08lx\n", mac_p->macStat.MIB_II.inDiscards);
|
|
printk("inErrors = 0x%08lx, ", mac_p->macStat.MIB_II.inErrors);
|
|
printk("outOctets = 0x%08lx\n", mac_p->macStat.MIB_II.outOctets);
|
|
printk("outUnicastPkts = 0x%08lx, ", mac_p->macStat.MIB_II.outUnicastPkts);
|
|
printk("outMulticastPkts = 0x%08lx\n", mac_p->macStat.MIB_II.outMulticastPkts);
|
|
printk("outDiscards = 0x%08lx, ", mac_p->macStat.MIB_II.outDiscards);
|
|
printk("outErrors = 0x%08lx\n", mac_p->macStat.MIB_II.outErrors);
|
|
printk("softRstCnt = 0x00000000\n");//no counter in linux
|
|
printk("\n[ inSilicon Statistics Display ]\n");
|
|
printk("txJabberTimeCnt = 0x%08lx ", mac_p->macStat.inSilicon.txJabberTimeCnt);
|
|
printk("txLossOfCarrierCnt = 0x%08lx\n", mac_p->macStat.inSilicon.txLossOfCarrierCnt);
|
|
printk("txNoCarrierCnt = 0x%08lx ", mac_p->macStat.inSilicon.txNoCarrierCnt);
|
|
printk("txLateCollisionCnt = 0x%08lx\n", mac_p->macStat.inSilicon.txLateCollisionCnt);
|
|
printk("txExCollisionCnt = 0x%08lx ", mac_p->macStat.inSilicon.txExCollisionCnt);
|
|
printk("txHeartbeatFailCnt = 0x%08lx\n", mac_p->macStat.inSilicon.txHeartbeatFailCnt);
|
|
printk("txCollisionCnt = 0x%08lx ", mac_p->macStat.inSilicon.txCollisionCnt);
|
|
printk("txExDeferralCnt = 0x%08lx\n", mac_p->macStat.inSilicon.txExDeferralCnt);
|
|
printk("txUnderRunCnt = 0x%08lx ", mac_p->macStat.inSilicon.txUnderRunCnt);
|
|
printk("rxAlignErr = 0x%08lx\n", mac_p->macStat.inSilicon.rxAlignErr);
|
|
printk("rxDribblingErr = 0x%08lx ", mac_p->macStat.inSilicon.rxDribblingErr);
|
|
printk("rxSymbolErr = 0x%08lx\n", mac_p->macStat.inSilicon.rxSymbolErr);
|
|
printk("rxMiiErr = 0x%08lx ", mac_p->macStat.inSilicon.rxMiiErr);
|
|
printk("rxCollisionErr = 0x%08lx\n", mac_p->macStat.inSilicon.rxCollisionErr);
|
|
printk("rxCrcErr = 0x%08lx ", mac_p->macStat.inSilicon.rxCrcErr);
|
|
printk("rxEtherFrameLengthErr = 0x%08lx\n", mac_p->macStat.inSilicon.rxEtherFrameLengthErr);
|
|
printk("rx802p3FrameLengthErr = 0x%08lx ", mac_p->macStat.inSilicon.rx802p3FrameLengthErr);
|
|
printk("rxPktIPChkSumErr = 0x%08lx\n", mac_p->macStat.inSilicon.rxPktIPChkSumErr);
|
|
printk("rxRuntErr = 0x%08lx ", mac_p->macStat.inSilicon.rxRuntErr);
|
|
printk("rxLongErr = 0x%08lx\n", mac_p->macStat.inSilicon.rxLongErr);
|
|
printk("\n[ Extra information ]\n");
|
|
printk("Rx Descriptor idx = 0x%08lx ", mac_p->rxCurrentDescp);
|
|
printk("Tx Descriptor idx = 0x%08lx\n", mac_p->txCurrentDescp);
|
|
printk("Rx Enqueued cnt = 0x%08lx ", mac_p->macStat.inSilicon.rxEnQueueNum);
|
|
printk("Tx Enqueued cnt = 0x%08lx\n", mac_p->macStat.inSilicon.txEnQueueNum);
|
|
printk("Rx Dequeued cnt = 0x%08lx ", mac_p->macStat.inSilicon.rxDeQueueNum);
|
|
printk("Tx Dequeued cnt = 0x%08lx\n", mac_p->macStat.inSilicon.txDeQueueNum);
|
|
printk("Tx Buf UnReleased cnt = 0x%08lx ", mac_p->txUnReleasedBufCnt);
|
|
printk("Tx Buf UnReleased idx = 0x%08lx\n", mac_p->txUnReleasedDescp);
|
|
|
|
}
|
|
#endif
|
|
/* Starting up the ethernet device */
|
|
static int tc3162_mac_open(struct net_device *dev)
|
|
{
|
|
int err;
|
|
|
|
printk(KERN_INFO "%s: starting interface.\n", dev->name);
|
|
|
|
err = request_irq(dev->irq, tc3162_mac_isr, 0, dev->name, dev);
|
|
if (err)
|
|
return err;
|
|
|
|
macInit();
|
|
|
|
#ifdef MII_INTERFACE
|
|
/* MII setup */
|
|
mac_p->mii_if.phy_id = mac_p->enetPhyAddr;
|
|
mac_p->mii_if.full_duplex = 1;
|
|
mac_p->mii_if.phy_id_mask = 0x1f;
|
|
mac_p->mii_if.reg_num_mask = 0x1f;
|
|
mac_p->mii_if.dev = dev;
|
|
mac_p->mii_if.mdio_read = mdio_read;
|
|
mac_p->mii_if.mdio_write = mdio_write;
|
|
#endif
|
|
|
|
/* Schedule timer for monitoring link status */
|
|
init_timer(ð_timer);
|
|
#ifdef TC2031_SUPPORT
|
|
eth_timer.expires = jiffies + (HZ/2);
|
|
#else
|
|
eth_timer.expires = jiffies + (HZ * 2);
|
|
#endif
|
|
eth_timer.function = tc3162_mac_link_status;
|
|
eth_timer.data = (unsigned long)dev;
|
|
add_timer(ð_timer);
|
|
|
|
/* Schedule timer for monitoring link status */
|
|
init_timer(ð_poll_timer);
|
|
eth_poll_timer.expires = jiffies + (HZ * 2);
|
|
eth_poll_timer.function = tc3162_mac_poll;
|
|
eth_poll_timer.data = (unsigned long)dev;
|
|
add_timer(ð_poll_timer);
|
|
|
|
INIT_WORK(&tq_mac, tc3162_mac_poll_rcv);
|
|
|
|
netif_start_queue(dev);
|
|
|
|
/*Wait 3 seconds,ipv6 can send initial packet,Added by jlliu_20091230*/
|
|
pause(3000);
|
|
return 0;
|
|
}
|
|
|
|
/* Stopping the ethernet device */
|
|
static int tc3162_mac_close(struct net_device *dev)
|
|
{
|
|
printk(KERN_INFO "tc3162_mac_close\n");
|
|
|
|
netif_stop_queue(dev);
|
|
|
|
free_irq(dev->irq, dev);
|
|
|
|
/* Kill timer */
|
|
del_timer_sync(ð_timer);
|
|
del_timer_sync(ð_poll_timer);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Setup multicast list */
|
|
static void tc3162_mac_set_multicast_list(struct net_device *dev)
|
|
{
|
|
return; /* Do nothing */
|
|
}
|
|
|
|
/* Setting customized mac address */
|
|
static int tc3162_mac_set_macaddr(struct net_device *dev, void *p)
|
|
{
|
|
struct sockaddr *addr = p;
|
|
|
|
/* Check if given address is valid ethernet MAC address */
|
|
if (!is_valid_ether_addr(addr->sa_data))
|
|
return(-EIO);
|
|
|
|
/* Save the customize mac address */
|
|
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
|
|
memcpy(def_mac_addr, addr->sa_data, dev->addr_len);
|
|
|
|
macGetMacAddr(mac_p);
|
|
macSetMacReg(mac_p);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Get the stats information */
|
|
static struct net_device_stats *tc3162_mac_stats(struct net_device *dev)
|
|
{
|
|
struct net_device_stats *stats;
|
|
|
|
stats = &mac_p->stats;
|
|
|
|
stats->rx_packets = mac_p->macStat.MIB_II.inUnicastPkts +
|
|
mac_p->macStat.MIB_II.inMulticastPkts;
|
|
stats->tx_packets = mac_p->macStat.MIB_II.outUnicastPkts +
|
|
mac_p->macStat.MIB_II.outMulticastPkts;
|
|
stats->rx_bytes = mac_p->macStat.MIB_II.inOctets;
|
|
stats->tx_bytes = mac_p->macStat.MIB_II.outOctets;
|
|
stats->rx_dropped = mac_p->macStat.MIB_II.inDiscards;
|
|
stats->tx_dropped = mac_p->macStat.MIB_II.outDiscards;
|
|
stats->multicast = mac_p->macStat.MIB_II.inMulticastPkts;
|
|
stats->rx_errors = mac_p->macStat.MIB_II.inErrors;
|
|
stats->tx_errors = mac_p->macStat.MIB_II.outErrors;
|
|
stats->collisions = mac_p->macStat.inSilicon.txExCollisionCnt +
|
|
mac_p->macStat.inSilicon.txCollisionCnt +
|
|
mac_p->macStat.inSilicon.rxCollisionErr;
|
|
|
|
return stats;
|
|
}
|
|
|
|
/* Handling ioctl call */
|
|
static int tc3162_mac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|
{
|
|
#ifdef MII_INTERFACE
|
|
/*Add the mii read/write ioctl interface*/
|
|
int rc;
|
|
if (!netif_running(dev))
|
|
return -EINVAL;
|
|
|
|
spin_lock_irq(&mac_p->lock);
|
|
rc = generic_mii_ioctl(&mac_p->mii_if, if_mii(ifr), cmd, NULL);
|
|
spin_unlock_irq(&mac_p ->lock);
|
|
return rc;
|
|
#else
|
|
/* Not implemented yet */
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
#if 0
|
|
//remove unuse function. chih_huang 20101129.
|
|
uint8 int_eth;
|
|
|
|
#endif
|
|
__IMEM irqreturn_t tc3162_mac_isr(int irq, void *dev_id)
|
|
{
|
|
macIntrStatusReg_t isr;
|
|
#ifdef TC3162_MAC_NAPI
|
|
macIntrMaskReg_t macIntrMask;
|
|
#endif
|
|
struct net_device *dev = (struct net_device *) dev_id;
|
|
|
|
#if 0
|
|
//remove unuse function. chih_huang 20101129.
|
|
int_eth = (VPint(CR_INTC_IMR) & (1 << MAC_INT));
|
|
if (int_eth)
|
|
VPint(CR_INTC_IMR) &= ~(1<<MAC_INT);
|
|
|
|
#endif
|
|
// -------Read MACCR--------------------------------
|
|
isr.value = VPint(CR_MAC_ISR);
|
|
|
|
#ifdef EEE_DEBUG
|
|
dumpIRQEvent(isr.value);
|
|
#endif
|
|
#if 0
|
|
//if (DbgSettings & DBG_HW)
|
|
if (1)
|
|
{
|
|
if (isr.bits.physts_chg ) printk("\r\n--->PHYSTS_CHG ");
|
|
if (isr.bits.ahb_err ) printk("\r\n--->AHB_ERR ");
|
|
if (isr.bits.rpkt_lost ) printk("\r\n--->RPKT_LOST ");
|
|
//if (isr.bits.rpkt_save ) printk("\r\n--->RPKT_SAVE ");
|
|
if (isr.bits.xpkt_lost ) printk("\r\n--->XPKT_LOST ");
|
|
//if (isr.bits.xpkt_finish) printk("\r\n--->XPKT_FINISH ");
|
|
//if (isr.bits.notxbuf ) printk("\r\n--->NOTXBUF ");
|
|
//if (isr.bits.xpkt_save ) printk("\r\n--->XPKT_SAVE ");
|
|
if (isr.bits.norxbuf ) printk("\r\n--->NORXBUF ");
|
|
//if (isr.bits.rpkt_finish) printk("\r\n--->RPKT_FINISH ");
|
|
}
|
|
#endif
|
|
|
|
// ----------Packet Received----------------------
|
|
|
|
#ifdef TC3162_MAC_NAPI
|
|
if (isr.bits.rpkt_finish || isr.bits.norxbuf || isr.bits.rpkt_lost)
|
|
#else
|
|
if (isr.bits.rpkt_finish)
|
|
#endif
|
|
{
|
|
#if !defined(TCSUPPORT_ETHER_ALL_LED)
|
|
ledTurnOn(LED_ETHER_ACT_STATUS);
|
|
if (mac_p->macPhyLinkProfile_p->enetMode & LAN_ST_100MB)
|
|
ledTurnOn(LED_ETHER_100M_ACT_STATUS);
|
|
else
|
|
ledTurnOn(LED_ETHER_10M_ACT_STATUS);
|
|
#endif
|
|
#ifdef TC3162_MAC_NAPI
|
|
spin_lock(&mac_p->lock);
|
|
if (netif_rx_schedule_prep(dev)) {
|
|
macIntrMask.value = read_reg_word(CR_MAC_IMR);
|
|
macIntrMask.bits.rpkt_finish = 0;
|
|
macIntrMask.bits.norxbuf = 0;
|
|
macIntrMask.bits.rpkt_lost = 0;
|
|
write_reg_word(CR_MAC_IMR, macIntrMask.value);
|
|
__netif_rx_schedule(dev);
|
|
}
|
|
|
|
spin_unlock(&mac_p->lock);
|
|
if(isr.bits.norxbuf || isr.bits.rpkt_lost){
|
|
mac_p->macStat.MIB_II.inDiscards++;
|
|
mac_p->macStat.inSilicon.rxOverrunInt++;
|
|
}
|
|
#if 0
|
|
if(isr.bits.norxbuf)
|
|
printk("MAC : NO RX BUF\n");
|
|
if(isr.bits.rpkt_lost)
|
|
printk("MAC : RX BUF OVERRUN\n");
|
|
#endif
|
|
#else
|
|
macRxRingProc(dev);
|
|
#endif
|
|
}
|
|
|
|
#if 0
|
|
//remove unuse function. chih_huang 20101129.
|
|
int_eth = (VPint(CR_INTC_IMR) & (1 << MAC_INT));
|
|
if (int_eth)
|
|
VPint(CR_INTC_IMR) |= (1<<MAC_INT);
|
|
|
|
#endif
|
|
MAC_RX_POLL_DEMAND_(1);
|
|
|
|
return IRQ_HANDLED;
|
|
}
|
|
#ifdef TC3162_MAC_NAPI
|
|
#if 0
|
|
//solve a lot of out-of-order packet. shnwind 20110323.
|
|
static inline int macRxRingChk(void)
|
|
{
|
|
macRxDescr_t *rxDescrp;
|
|
|
|
rxDescrp = ((macRxDescr_t*)mac_p->rxDescrRingBaseVAddr) + mac_p->rxCurrentDescp;
|
|
if ((rxDescrp->rdes0.word & (1<<31)) == 0)
|
|
return 1;
|
|
return -1;
|
|
}
|
|
#endif
|
|
static int tc3162_mac_poll_napi(struct net_device *dev, int *budget)
|
|
{
|
|
int rx_work_limit = min(dev->quota, *budget);
|
|
int received = 0;
|
|
int n, done;
|
|
unsigned long flags;
|
|
macIntrMaskReg_t macIntrMask;
|
|
|
|
restart_poll:
|
|
n = macRxRingProc(dev, rx_work_limit);
|
|
if (n) {
|
|
received += n;
|
|
rx_work_limit -= n;
|
|
if (rx_work_limit <= 0) {
|
|
done = 0;
|
|
goto more_work;
|
|
}
|
|
}
|
|
|
|
done = 1;
|
|
|
|
spin_lock_irqsave(&mac_p->lock, flags);
|
|
__netif_rx_complete(dev);
|
|
macIntrMask.value = read_reg_word(CR_MAC_IMR);
|
|
macIntrMask.bits.rpkt_finish = 1;
|
|
macIntrMask.bits.norxbuf = 1;
|
|
macIntrMask.bits.rpkt_lost = 1;
|
|
write_reg_word(CR_MAC_IMR, macIntrMask.value);
|
|
#if 0
|
|
//solve a lot of out-of-order packet. shnwind 20110323.
|
|
/* check rotting packets */
|
|
if ((macRxRingChk() >= 0) && netif_rx_reschedule(dev, 0)) {
|
|
macIntrMask.value = read_reg_word(CR_MAC_IMR);
|
|
macIntrMask.bits.rpkt_finish = 0;
|
|
macIntrMask.bits.norxbuf = 0;
|
|
macIntrMask.bits.rpkt_lost = 0;
|
|
write_reg_word(CR_MAC_IMR, macIntrMask.value);
|
|
|
|
spin_unlock_irqrestore(&mac_p->lock, flags);
|
|
|
|
if (rx_work_limit <= 0) {
|
|
done = 0;
|
|
goto more_work;
|
|
} else {
|
|
goto restart_poll;
|
|
}
|
|
}
|
|
#endif
|
|
spin_unlock_irqrestore(&mac_p->lock, flags);
|
|
more_work:
|
|
*budget -= received;
|
|
dev->quota -= received;
|
|
return done ? 0 : 1;
|
|
}
|
|
#endif
|
|
|
|
static int tc3162_mac_start(struct net_device *dev)
|
|
{
|
|
int i;
|
|
|
|
uint8 *flash_mac_addr = (uint8 *)0xbfc0ff48;
|
|
|
|
if( (flash_mac_addr[0] == 0) && (flash_mac_addr[1] == 0) && (flash_mac_addr[2] == 0) &&
|
|
(flash_mac_addr[3] == 0) && (flash_mac_addr[4] == 0) && (flash_mac_addr[5] == 0) )
|
|
printk(KERN_INFO "The MAC address in flash is null!\n");
|
|
else
|
|
memcpy(def_mac_addr, flash_mac_addr, 6);
|
|
|
|
mac_p = netdev_priv(dev);
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
dev->dev_addr[i] = def_mac_addr[i];
|
|
}
|
|
|
|
spin_lock_init(&mac_p->lock);
|
|
spin_lock_init(&mac_p->phy_lock);
|
|
|
|
/* Hook up with handlers */
|
|
dev->get_stats = tc3162_mac_stats;
|
|
dev->hard_start_xmit = tc3162_mac_tx;
|
|
dev->open = tc3162_mac_open;
|
|
dev->stop = tc3162_mac_close;
|
|
dev->set_multicast_list = tc3162_mac_set_multicast_list;
|
|
dev->do_ioctl = tc3162_mac_ioctl;
|
|
dev->set_mac_address = tc3162_mac_set_macaddr;
|
|
#ifdef TC3162_MAC_NAPI
|
|
dev->poll = tc3162_mac_poll_napi;
|
|
dev->weight = MAC_NAPI_WEIGHT;
|
|
#endif
|
|
|
|
printk(KERN_INFO
|
|
"%s: TC3162 Ethernet address: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
|
dev->name,
|
|
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
|
|
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
|
|
|
|
/*
|
|
dev->tx_queue_len = MAC_TXDESCP_NO;
|
|
dev->flags &= ~IFF_MULTICAST;
|
|
dev->flags |= IFF_DEBUG;
|
|
*/
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if defined(TCSUPPORT_ETHER_ALL_LED)
|
|
static int ether_speed_read_proc(char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
int len;
|
|
|
|
len = sprintf(page, "%d %d %d %d\n", ether_speed[0], ether_speed[1], ether_speed[2], ether_speed[3]);
|
|
|
|
len -= off;
|
|
*start = page + off;
|
|
|
|
if (len > count)
|
|
len = count;
|
|
else
|
|
*eof = 1;
|
|
|
|
if (len < 0)
|
|
len = 0;
|
|
|
|
return len;
|
|
}
|
|
|
|
static int ether_speed_write_proc(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
int len;
|
|
char get_buf[32];
|
|
|
|
/* do a range checking, don't overflow buffers in kernel modules */
|
|
if(count > sizeof(get_buf)-1)
|
|
len = sizeof(get_buf)-1;
|
|
else
|
|
len = count;
|
|
|
|
|
|
/* use the copy_from_user function to copy buffer data to
|
|
* to our get_buf */
|
|
if(copy_from_user(get_buf, buffer, len)) {
|
|
return -EFAULT;
|
|
}
|
|
|
|
/* zero terminate get_buf */
|
|
get_buf[len]='\0';
|
|
|
|
if (sscanf(get_buf, "%d %d %d %d %d\n", ether_speed, (ether_speed+1), (ether_speed+2), (ether_speed+3)) != 4) {
|
|
printk("usage: <ether_speed [0 ~ 3]>\n");
|
|
}
|
|
return len;
|
|
}
|
|
#endif
|
|
|
|
static int __init tc3162_mac_init(void)
|
|
{
|
|
struct net_device *dev;
|
|
int err = 0;
|
|
struct proc_dir_entry *eth_proc;
|
|
#ifndef TC2031_SUPPORT
|
|
struct proc_dir_entry *port_reverse_proc, *stag_to_vtag_proc;
|
|
#endif
|
|
|
|
#ifdef TC3162_MAC_NAPI
|
|
printk(KERN_INFO "TC3162 Ethernet Driver NAPI version 1.5\n");
|
|
#else
|
|
printk(KERN_INFO "TC3162 Ethernet Driver version 1.5\n");
|
|
#endif
|
|
printk("\r\n%s\n", MODULE_VERSION_TC3162MAC);
|
|
|
|
dev = alloc_etherdev(sizeof(macAdapter_t));
|
|
if (!dev)
|
|
return -ENOMEM;
|
|
|
|
tc3162_mac_dev = dev;
|
|
|
|
dev->irq = MAC_INT;
|
|
|
|
mac_p = netdev_priv(dev);
|
|
|
|
dev->init = tc3162_mac_start;
|
|
|
|
err = register_netdev(dev);
|
|
if (err)
|
|
return err;
|
|
|
|
#if defined(TCSUPPORT_ETHER_ALL_LED)
|
|
/* all ethernet stats */
|
|
eth_proc = create_proc_entry("tc3162/ether_speed", 0, NULL);
|
|
eth_proc->read_proc = ether_speed_read_proc;
|
|
eth_proc->write_proc = ether_speed_write_proc;
|
|
#endif
|
|
/* ethernet related stats */
|
|
eth_proc = create_proc_entry("tc3162/eth_stats", 0, NULL);
|
|
eth_proc->read_proc = eth_stats_read_proc;
|
|
eth_proc->write_proc = eth_stats_write_proc;
|
|
#ifdef TCPHY_4PORT
|
|
/* ESD patch */
|
|
eth_proc = create_proc_entry("tc3162/mac_esd_check", 0, NULL);
|
|
eth_proc->read_proc = eth_esd_read_proc;
|
|
eth_proc->write_proc = eth_esd_write_proc;
|
|
#if !defined(TCSUPPORT_CT)
|
|
#if 1//def VPORT
|
|
/*vport enable/disable control*/
|
|
eth_proc = create_proc_entry("tc3162/vport_enable", 0, NULL);
|
|
eth_proc->read_proc = vport_enable_read_proc;
|
|
eth_proc->write_proc = vport_enable_write_proc;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
create_proc_read_entry("tc3162/eth_link_st", 0, NULL, eth_link_st_proc, NULL);
|
|
create_proc_read_entry("tc3162/eth_reg", 0, NULL, eth_reg_dump_proc, NULL);
|
|
#ifndef TC2031_SUPPORT
|
|
port_reverse_proc = create_proc_entry("tc3162/port_reverse", 0, NULL);
|
|
port_reverse_proc->read_proc = port_reverse_read_proc;
|
|
port_reverse_proc->write_proc = port_reverse_write_proc;
|
|
#if !defined(TCSUPPORT_CT)
|
|
stag_to_vtag_proc = create_proc_entry("tc3162/stag_to_vtag", 0, NULL);
|
|
stag_to_vtag_proc->read_proc = stag_to_vtag_read_proc;
|
|
stag_to_vtag_proc->write_proc = stag_to_vtag_write_proc;
|
|
#endif
|
|
#endif
|
|
skb_queue_head_init(&adsl_pkt_queue);
|
|
INIT_WORK(&tq_adsl, macSendReal);
|
|
|
|
#ifdef TCPHY_SUPPORT
|
|
#if !defined(TCSUPPORT_CT)
|
|
#ifndef TC2031_SUPPORT
|
|
create_proc_read_entry("tc3162/eth_port_status", 0, NULL, eth_port_stat_read_proc, NULL);
|
|
#endif
|
|
#endif
|
|
tcephydbgcmd();
|
|
#ifdef TC2031_DEBUG
|
|
tcethercmd();
|
|
#endif
|
|
#endif
|
|
#ifdef TC_CONSOLE_ENABLE
|
|
create_tcconsole_proc();
|
|
rcu_assign_pointer(send_uart_msg, uart_msg_to_tcconsole);
|
|
#endif
|
|
return(0);
|
|
}
|
|
|
|
static void __exit tc3162_mac_exit(void)
|
|
{
|
|
printk("tc3162_mac_exit.\n");
|
|
|
|
remove_proc_entry("tc3162/eth_stats", 0);
|
|
remove_proc_entry("tc3162/eth_link_st", 0);
|
|
remove_proc_entry("tc3162/eth_reg", 0);
|
|
#if !defined(TCSUPPORT_CT)
|
|
#ifdef TCPHY_SUPPORT
|
|
remove_proc_entry("tc3162/eth_port_status", 0);
|
|
#endif
|
|
#endif
|
|
#ifdef TCPHY_4PORT
|
|
remove_proc_entry("tc3162/mac_esd_check", 0);
|
|
#if !defined(TCSUPPORT_CT)
|
|
#if 1// def VPORT
|
|
remove_proc_entry("tc3162/vport_enable", 0);
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#ifndef TC2031_SUPPORT
|
|
remove_proc_entry("tc3162/port_reverse", 0);
|
|
#if !defined(TCSUPPORT_CT)
|
|
remove_proc_entry("tc3162/stag_to_vtag", 0);
|
|
#endif
|
|
#endif
|
|
#ifdef TCPHY_SUPPORT
|
|
/*unregister ci command */
|
|
cmd_unregister("tcephydbg");
|
|
#ifdef TC2031_DEBUG
|
|
cmd_unregister("ether");
|
|
#endif
|
|
#endif
|
|
#ifdef TC_CONSOLE_ENABLE
|
|
delete_tcconsole_proc();
|
|
rcu_assign_pointer(send_uart_msg, NULL);
|
|
#endif
|
|
}
|
|
|
|
/* Register startup/shutdown routines */
|
|
module_init(tc3162_mac_init);
|
|
module_exit(tc3162_mac_exit);
|
|
|