Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/tn40xx/TLK10232_phy.c
- This file was added.
#include "tn40.h" | |||||
#include "TLK10232_phy.h" | |||||
int bdx_speed_set(struct bdx_priv *priv, u32 speed); | |||||
void sff_reset(struct bdx_priv *priv); | |||||
int sff_read_str(struct bdx_priv *priv, unsigned char sfp_adr, unsigned char addr,int len, char *buf); | |||||
int sff_write_str(struct bdx_priv *priv, unsigned char sfp_adr, unsigned char addr,int len, char *buf); | |||||
int i2c_write_byte(struct bdx_priv *priv,int send_start, int send_stop, unsigned char byte); | |||||
unsigned char i2c_read_byte(struct bdx_priv *priv,int nack, int send_stop); | |||||
int i2c_read_bit(struct bdx_priv *priv); | |||||
int i2c_write_bit(struct bdx_priv *priv,int bit); | |||||
int i2c_start_cond(struct bdx_priv *priv, int I2C_started); | |||||
int i2c_stop_cond(struct bdx_priv *priv); | |||||
int i2c_SCL_stretch(struct bdx_priv *priv); | |||||
int read_sfp_id(struct bdx_priv *priv); | |||||
void set_GPIO(struct bdx_priv *priv); | |||||
void clear_GPIO_N(struct bdx_priv *priv, u32 n); | |||||
u32 read_GPIO_N(struct bdx_priv *priv, u32 n); | |||||
int TLK10232_phy_config(struct bdx_priv *priv); | |||||
int TLK10232_mdio_reset(struct bdx_priv *priv, int port, unsigned short phy); | |||||
u32 TLK10232_get_link_speed(struct bdx_priv *priv); | |||||
u32 TLK10232_link_changed(struct bdx_priv *priv); | |||||
void TLK10232_leds(struct bdx_priv *priv, enum PHY_LEDS_OP op); | |||||
#define LINK_LOOP_MAX (80) | |||||
void TLK10232_register_settings(struct bdx_priv *priv); | |||||
enum _SFP_MOD_TYPE{ | |||||
SFP_ABS=0, | |||||
SFP_NA, | |||||
SFP_1G, | |||||
SFP_10G, | |||||
SFP_10G_DA | |||||
}; | |||||
#define TEST_SFP_OM | |||||
#ifdef TEST_SFP_OM | |||||
#define SCL_GPIO 4 | |||||
#define SDA_GPIO 5 | |||||
#define TX_DISABLE_GPIO 1 | |||||
#define MOD_ABS_GPIO 2 | |||||
#define I2C_delay(priv) udelay(8) | |||||
#define RWDELAY(priv) udelay(1) | |||||
#define WRITE_GPOI_REG(priv,reg,val) do{\ | |||||
WRITE_REG(priv, 0x51E0,0x30010000|((reg&0xf)));\ | |||||
READ_REG(priv, 0x5030); WRITE_REG(priv, 0x51F0, ( val) );\ | |||||
} while(0) | |||||
#define READ_GPOI_REG(priv,reg,val) do{\ | |||||
WRITE_REG(priv, 0x51E0,0x30000000|((reg&0xf)));\ | |||||
READ_REG(priv, 0x5030); val=READ_REG(priv, 0x51F0);\ | |||||
} while(0) | |||||
#define LOG_I2C DBG | |||||
//------------------------------------------------------------------------------------------------- | |||||
u32 read_GPIO_N(struct bdx_priv *priv, u32 n){ | |||||
u32 ret,rw,i,msk=(1<<(n&0x7)); | |||||
// get current GPIO state | |||||
READ_GPOI_REG(priv,6,rw); | |||||
// set to input GPIO N | |||||
WRITE_GPOI_REG(priv,6,rw|msk); | |||||
RWDELAY(priv); | |||||
// read | |||||
READ_GPOI_REG(priv,4,i); | |||||
ret= (i&msk)?1:0; | |||||
LOG_I2C("read_GPIO_N(%x) 4= %x 6=(%x | %x) ret=%x) \n",n,i,rw,msk,ret); | |||||
return ret; | |||||
} // read_GPIO_N() | |||||
//------------------------------------------------------------------------------------------------- | |||||
void clear_GPIO_N(struct bdx_priv *priv, u32 n){ | |||||
u32 rw,msk= ~(1<<(n&0x7)); | |||||
// get current GPIO state | |||||
READ_GPOI_REG(priv,6,rw); | |||||
// set to output GPIO N | |||||
WRITE_GPOI_REG(priv,6,(rw & msk)); | |||||
RWDELAY(priv); | |||||
LOG_I2C("clear_GPIO_N(%x) 6=(%x & %x)\n",n,rw , msk); | |||||
} // clear_GPIO_N() | |||||
//------------------------------------------------------------------------------------------------- | |||||
// Set SCL as input and return current level of line, 0 or 1 | |||||
#define read_SCL(p) read_GPIO_N((p),SCL_GPIO) | |||||
// Set SDA as input and return current level of line, 0 or 1 | |||||
#define read_SDA(p) read_GPIO_N((p),SDA_GPIO) | |||||
// Actively drive SCL signal low | |||||
#define clear_SCL(p) clear_GPIO_N((p),SCL_GPIO) | |||||
// Actively drive SDA signal low | |||||
#define clear_SDA(p) clear_GPIO_N((p),SDA_GPIO) | |||||
//return 0-ok 1-CLK==0 | |||||
//------------------------------------------------------------------------------------------------- | |||||
int i2c_SCL_stretch(struct bdx_priv *priv){ | |||||
int i; | |||||
for(i=50;i;i--){ | |||||
if(read_SCL(priv)) break; | |||||
udelay(1); | |||||
} | |||||
return (i)?0:1; | |||||
} // i2c_SCL_stretch() | |||||
//------------------------------------------------------------------------------------------------- | |||||
int i2c_start_cond(struct bdx_priv *priv, int I2C_started) { | |||||
int ret=0; | |||||
LOG_I2C("TLK10232 i2c_start_cond start=====================\n"); | |||||
I2C_delay(priv); | |||||
I2C_delay(priv); | |||||
if(I2C_started){ | |||||
read_SDA(priv); | |||||
I2C_delay(priv); | |||||
ret=i2c_SCL_stretch(priv); | |||||
if(ret) { | |||||
LOG_I2C("TLK10232 i2c_start_cond failed SCL==0\n"); | |||||
} | |||||
I2C_delay(priv); | |||||
} | |||||
if (read_SDA(priv) == 0) { | |||||
LOG_I2C("TLK10232 i2c_start_cond failed SDA==0\n"); | |||||
ret=1; | |||||
} | |||||
// SCL is high, set SDA from 1 to 0. | |||||
clear_SDA(priv); | |||||
I2C_delay(priv); | |||||
clear_SCL(priv); | |||||
LOG_I2C("TLK10232 i2c_start_cond "STRING_FMT"======================\n",ret?"Failed ":"OK"); | |||||
return ret; | |||||
} // i2c_start_cond() | |||||
//------------------------------------------------------------------------------------------------- | |||||
int i2c_stop_cond(struct bdx_priv *priv){ | |||||
int ret=0; | |||||
LOG_I2C("TLK10232 i2c_stop_cond start===================\n"); | |||||
clear_SCL(priv); | |||||
// set SDA to 0 | |||||
clear_SDA(priv); | |||||
I2C_delay(priv); | |||||
// Clock stretching | |||||
ret=i2c_SCL_stretch(priv); | |||||
if(ret){ | |||||
LOG_I2C("TLK10232 i2c_stop_cond failed SCL==0\n"); | |||||
ret=1; | |||||
} | |||||
// Stop bit setup time, minimum 4us | |||||
I2C_delay(priv); | |||||
// SCL is high, set SDA from 0 to 1 | |||||
if (read_SDA(priv) == 0) { | |||||
LOG_I2C("TLK10232 i2c_stop_cond failed SDA==0\n"); | |||||
ret=1; | |||||
} | |||||
I2C_delay(priv); | |||||
LOG_I2C("TLK10232 i2c_stop_cond end===================\n"); | |||||
return ret; | |||||
} // i2c_stop_cond() | |||||
//------------------------------------------------------------------------------------------------- | |||||
// Write a bit to I2C bus | |||||
int i2c_write_bit(struct bdx_priv *priv,int bit) { | |||||
int ret=0; | |||||
LOG_I2C("TLK10232 i2c_write_bit ==%x start \n", bit); | |||||
if (bit) { | |||||
read_SDA(priv); | |||||
} else { | |||||
clear_SDA(priv); | |||||
} | |||||
i2c_SCL_stretch(priv); | |||||
I2C_delay(priv); | |||||
// SCL is high, now data is valid | |||||
// If SDA is high, check that nobody else is driving SDA | |||||
if (bit) if( read_SDA(priv) == 0) { | |||||
//arbitration_lost(); | |||||
ret=1; | |||||
} | |||||
I2C_delay(priv); | |||||
clear_SCL(priv); | |||||
LOG_I2C("TLK10232 i2c_write_bit "STRING_FMT"\n",ret?"failed":"OK"); | |||||
return ret; | |||||
} // i2c_write_bit() | |||||
//------------------------------------------------------------------------------------------------- | |||||
// Read a bit from I2C bus | |||||
int i2c_read_bit(struct bdx_priv *priv) { | |||||
int bit; | |||||
LOG_I2C("TLK10232 i2c_read_bit start \n"); | |||||
// Let the slave drive data | |||||
read_SDA(priv); | |||||
i2c_SCL_stretch(priv); | |||||
I2C_delay(priv); | |||||
// SCL is high, now data is valid | |||||
bit = read_SDA(priv); | |||||
I2C_delay(priv); | |||||
clear_SCL(priv); | |||||
LOG_I2C("TLK10232 i2c_read_bit %x \n",bit); | |||||
return bit?1:0; | |||||
} // i2c_read_bit() | |||||
//------------------------------------------------------------------------------------------------- | |||||
// Write a byte to I2C bus. Return 0 if ack by the slave. | |||||
int i2c_write_byte(struct bdx_priv *priv,int send_start, | |||||
int send_stop, | |||||
unsigned char byte) { | |||||
unsigned bit; | |||||
int nack; | |||||
LOG_I2C("i2c_write_byte 0x%x start\n",byte); | |||||
if (send_start) { | |||||
i2c_start_cond(priv,(send_start==2)?1:0); | |||||
} | |||||
for (bit = 0; bit < 8; bit++) { | |||||
i2c_write_bit(priv,(byte & 0x80) != 0); | |||||
byte <<= 1; | |||||
} | |||||
nack = i2c_read_bit(priv); | |||||
if (send_stop) { | |||||
i2c_stop_cond(priv); | |||||
} | |||||
LOG_I2C("i2c_write_byte end nack=%x\n",nack); | |||||
return nack; | |||||
} // i2c_write_byte() | |||||
//------------------------------------------------------------------------------------------------- | |||||
// Read a byte from I2C bus | |||||
unsigned char i2c_read_byte(struct bdx_priv *priv,int nack, int send_stop) { | |||||
unsigned char byte = 0; | |||||
unsigned bit; | |||||
LOG_I2C("i2c_read_byte start nack=%x\n",nack); | |||||
for (bit = 0; bit < 8; bit++) { | |||||
byte = (byte << 1); | |||||
byte |= i2c_read_bit(priv); | |||||
} | |||||
i2c_write_bit(priv, nack); | |||||
if (send_stop) { | |||||
i2c_stop_cond(priv); | |||||
} | |||||
LOG_I2C("i2c_read_byte stop byte=%x\n",byte); | |||||
return byte; | |||||
} // i2c_read_byte() | |||||
//------------------------------------------------------------------------------------------------- | |||||
void sff_reset(struct bdx_priv *priv){ | |||||
int i; | |||||
for (i=0;i<9;i++){ | |||||
i2c_read_bit(priv); | |||||
} | |||||
i2c_start_cond(priv,0); | |||||
I2C_delay(priv); | |||||
read_SDA(priv); | |||||
} // sff_reset() | |||||
//------------------------------------------------------------------------------------------------- | |||||
/* | |||||
Return len or 0 on error | |||||
*/ | |||||
int sff_read_str(struct bdx_priv *priv, unsigned char sfp_adr, unsigned char addr,int len, char *buf){ | |||||
unsigned char data; | |||||
int i=0,err=0; | |||||
if(buf==0) return 0; | |||||
if(len==0) return 0; | |||||
if(len&0xff00) return 0; | |||||
DBG("TLK10232 sff_read_str sfp_adr=%x addr=%x start \n",sfp_adr,addr); | |||||
do{ | |||||
err=i2c_write_byte(priv,/*send_start*/1,/*send_stop*/ 0,sfp_adr&0xfe); | |||||
if(err){ err=1; break;} | |||||
err=i2c_write_byte(priv,/*send_start*/0,/*send_stop*/ 1,addr&0xff); | |||||
if(err){ err=2; break;} | |||||
err=i2c_write_byte(priv,/*send_start*/1,/*send_stop*/ 0,sfp_adr|1); | |||||
if(err){ err=3; break;} | |||||
len--; | |||||
for(i=0;i<len;i++){ | |||||
data=i2c_read_byte(priv,/*nack*/ 0, /*send_stop*/ 0); | |||||
buf[i]=data; | |||||
} | |||||
data=i2c_read_byte(priv,/*nack*/ 1, /*send_stop*/ 1); | |||||
buf[i]=data; | |||||
i++; | |||||
DBG("TLK10232 sff_read_str sfp_adr=%x addr=%x end \n",sfp_adr,addr); | |||||
} while(0); | |||||
if(err){ | |||||
DBG("TLK10232 sff_read step %u failed\n",err); | |||||
i=0; | |||||
i2c_stop_cond(priv); | |||||
} | |||||
return i; | |||||
} // sff_read_str() | |||||
//------------------------------------------------------------------------------------------------- | |||||
int sff_write_str(struct bdx_priv *priv, unsigned char sfp_adr, unsigned char addr,int len, char *buf){ | |||||
int i=0,err=0; | |||||
if(buf==0) return 0; | |||||
if(len==0) return 0; | |||||
if(len>8) return 0; // not more then 7 bytes by SFF spec | |||||
if(len&0xff00) return 0; | |||||
DBG("TLK10232 sff_write_str sfp_adr=%x addr=%x start \n",sfp_adr,addr); | |||||
do{ | |||||
err=i2c_write_byte(priv,/*send_start*/1,/*send_stop*/ 0,sfp_adr&0xfe); | |||||
if(err){ err=1; break;} | |||||
err=i2c_write_byte(priv,/*send_start*/0,/*send_stop*/ 0,addr&0xff); | |||||
if(err){ err=2; break;} | |||||
len--; | |||||
for(i=0;i<len;i++){ | |||||
err=i2c_write_byte(priv,/*send_start*/ 0, /*send_stop*/ 0,buf[i]); | |||||
if(err){ err=4; break;} | |||||
} | |||||
if(err){ err=4; break;} | |||||
err=i2c_write_byte(priv,/*send_start*/0, /*send_stop*/ 1,buf[i]); | |||||
i++; | |||||
DBG("TLK10232 sff_write_str sfp_adr=%x addr=%x end \n",sfp_adr,addr); | |||||
} while(0); | |||||
if(err){ | |||||
ERR("TLK10232 sff_write step %u failed\n",err); | |||||
i=0; | |||||
i2c_stop_cond(priv); | |||||
} | |||||
return i; | |||||
} // sff_write_str() | |||||
//------------------------------------------------------------------------------------------------- | |||||
void set_GPIO(struct bdx_priv *priv){ | |||||
u32 input_msk=(1<<11)|(1<<SCL_GPIO)|(1<<SDA_GPIO)|(1<<MOD_ABS_GPIO); | |||||
WRITE_GPOI_REG(priv,4,0); | |||||
WRITE_GPOI_REG(priv,6,input_msk); | |||||
} // set_GPIO() | |||||
//------------------------------------------------------------------------------------------------- | |||||
int read_sfp_id(struct bdx_priv *priv){ | |||||
char buff[10]; | |||||
int i,ret; | |||||
int sff_addr=0xa0; | |||||
int addr=0x3; | |||||
int len=6; | |||||
set_GPIO(priv); | |||||
i=read_GPIO_N(priv,MOD_ABS_GPIO); | |||||
DBG("MOD_ABS_GPIO=%u \n",i); | |||||
if(i) return SFP_ABS; | |||||
ret=sff_read_str(priv, sff_addr, addr,len, buff); | |||||
DBG("sff_read_str(0x%x,0x%x,0x%x)=%x \n",sff_addr, addr,len,ret); | |||||
#if 0 | |||||
for(i=0;i<ret;i++){ | |||||
ERR("sff_read_str buf[%u]=0x%x \n",i,buff[i]&0xff); | |||||
} | |||||
#endif | |||||
if(buff[5]&0xF) return SFP_10G_DA; | |||||
if(buff[0]) return SFP_10G; | |||||
if(buff[3]&0xF) return SFP_1G; | |||||
return SFP_10G; | |||||
} // read_sfp_id() | |||||
//------------------------------------------------------------------------------------------------- | |||||
#else | |||||
#define read_sfp_id(p) (SFP_10G) | |||||
#endif | |||||
//------------------------------------------------------------------------------------------------- | |||||
int TLK10232_phy_config(struct bdx_priv *priv) | |||||
{ | |||||
int regVal, j=0; | |||||
int port=priv->phy_mdio_port; | |||||
u32 sfp_mod_type=priv->sfp_mod_type; | |||||
if(sfp_mod_type==SFP_ABS) return 0; | |||||
switch(sfp_mod_type){ | |||||
default: | |||||
case SFP_10G: | |||||
BDX_MDIO_WRITE(priv,0x1e, CHANNEL_CONTROL_1, 0x0B00); | |||||
BDX_MDIO_WRITE(priv,0x1e, HS_SERDES_CONTROL_2, 0xA848); //reg 1e.3 | |||||
BDX_MDIO_WRITE(priv,0x1e, HS_SERDES_CONTROL_3, 0x9518); //reg 1e.4 | |||||
BDX_MDIO_WRITE(priv,0x1e, HS_SERDES_CONTROL_4, 0x3300); //reg 1e.5 | |||||
break; | |||||
case SFP_10G_DA: | |||||
BDX_MDIO_WRITE(priv,0x1e, CHANNEL_CONTROL_1, 0x0B00); | |||||
BDX_MDIO_WRITE(priv,0x1e, HS_SERDES_CONTROL_2, 0xF848); //reg 1e.3 | |||||
BDX_MDIO_WRITE(priv,0x1e, HS_SERDES_CONTROL_3, 0x1500); //reg 1e.4 | |||||
BDX_MDIO_WRITE(priv,0x1e, HS_SERDES_CONTROL_4, 0x2000); //reg 1e.5 | |||||
break; | |||||
case SFP_1G: | |||||
BDX_MDIO_WRITE(priv,0x1e, CHANNEL_CONTROL_1, 0x0300); | |||||
BDX_MDIO_WRITE(priv,0x1e, HS_SERDES_CONTROL_2, 0xA848); //reg 1e.3 | |||||
BDX_MDIO_WRITE(priv,0x1e, HS_SERDES_CONTROL_3, 0x9518); //reg 1e.4 | |||||
BDX_MDIO_WRITE(priv,0x1e, HS_SERDES_CONTROL_4, 0x3300); //reg 1e.5 | |||||
break; | |||||
} | |||||
// Datapath reset | |||||
do | |||||
{ | |||||
udelay(25); | |||||
BDX_MDIO_WRITE(priv,0x1e, RESET_CONTROL, 0x8); | |||||
BDX_MDIO_WRITE(priv,0x1e, RESET_CONTROL, 0x0); | |||||
udelay(25); | |||||
regVal = bdx_mdio_read(priv, 0x1e, port, CHANNEL_STATUS_1); | |||||
regVal = bdx_mdio_read(priv, 0x1e, port, CHANNEL_STATUS_1); | |||||
DBG("TLK10232_phy_config() CHANNEL_STATUS_1 = 0x%x Fail:%x loops:%d (Fail mask 0x0100)\n", regVal, (regVal & 0x0100), j); | |||||
} while ((regVal & 0x0100) && (j++ < 100)); | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------------------------------- | |||||
int TLK10232_mdio_reset(struct bdx_priv *priv, int port, unsigned short phy) | |||||
{ | |||||
int regVal; | |||||
priv->sfp_mod_type=0; //read_sfp_id(priv); | |||||
// Device reset | |||||
BDX_MDIO_WRITE(priv,0x1e, GLOBAL_CONTROL_1, 0x8610); | |||||
regVal = bdx_mdio_read(priv, 0x1e, port, GLOBAL_CONTROL_1); | |||||
DBG("TLK10232_mdio_reset() GLOBAL_CONTROL_1 = 0x%x\n", regVal); | |||||
msleep(100); | |||||
BDX_MDIO_WRITE(priv,0x7, AN_CONTROL, 0x2000); | |||||
BDX_MDIO_WRITE(priv,0x1, LT_TRAIN_CONTROL, 0x0); | |||||
priv->link_speed = TLK10232_get_link_speed(priv); | |||||
bdx_speed_set(priv, priv->link_speed); | |||||
return 0; | |||||
} // TLK10232_mdio_reset | |||||
//------------------------------------------------------------------------------------------------- | |||||
u32 TLK10232_get_link_speed(struct bdx_priv *priv) | |||||
{ | |||||
u32 sfp_mod_type,speed; | |||||
sfp_mod_type=read_sfp_id(priv); | |||||
// ERR("TLK10232_get_link_speed sfp_mod_type=%u\n",sfp_mod_type); | |||||
if(priv->sfp_mod_type!=sfp_mod_type){ | |||||
priv->sfp_mod_type=sfp_mod_type; | |||||
TLK10232_phy_config(priv); | |||||
} | |||||
switch (sfp_mod_type){ | |||||
case SFP_10G: | |||||
case SFP_10G_DA: | |||||
speed=SPEED_10000;break; | |||||
case SFP_1G: | |||||
//speed=SPEED_1000; break; | |||||
default: | |||||
speed=0; break; | |||||
} | |||||
return speed; | |||||
} // TLK10232_get_link_speed() | |||||
//------------------------------------------------------------------------------------------------- | |||||
u32 TLK10232_link_changed(struct bdx_priv *priv) | |||||
{ | |||||
u32 link = 0; | |||||
link = READ_REG(priv,regMAC_LNK_STAT) & MAC_LINK_STAT; | |||||
if (link) | |||||
{ | |||||
priv->link_speed = TLK10232_get_link_speed(priv); | |||||
link = priv->link_speed; | |||||
DBG("TLK10232 link speed is "STRING_FMT"\n", (priv->link_speed == SPEED_10000) ? "10G" : "1G"); | |||||
WRITE_REG(priv, 0x5150,0); // stop timer | |||||
} | |||||
else | |||||
{ | |||||
if(priv->link_loop_cnt++ > LINK_LOOP_MAX) | |||||
{ | |||||
DBG("TLK10232 trying to recover link after %d tries\n", LINK_LOOP_MAX); | |||||
priv->link_speed = TLK10232_get_link_speed(priv); | |||||
// MAC reset | |||||
bdx_speed_set(priv,0); | |||||
bdx_speed_set(priv,priv->link_speed); | |||||
priv->link_loop_cnt = 0; | |||||
priv->sfp_mod_type=SFP_ABS; | |||||
} | |||||
//DBG("TLK10232 no link, setting 1/5 sec timer\n"); | |||||
WRITE_REG(priv, 0x5150,1000000); // 1/5 sec timeout | |||||
} | |||||
return link; | |||||
} // TLK10232_link_changed() | |||||
//------------------------------------------------------------------------------------------------- | |||||
void TLK10232_leds(struct bdx_priv *priv, enum PHY_LEDS_OP op) | |||||
{ | |||||
switch (op) | |||||
{ | |||||
case PHY_LEDS_SAVE: | |||||
break; | |||||
case PHY_LEDS_RESTORE: | |||||
break; | |||||
case PHY_LEDS_ON: | |||||
WRITE_REG(priv, regBLNK_LED, 4); | |||||
break; | |||||
case PHY_LEDS_OFF: | |||||
WRITE_REG(priv, regBLNK_LED, 0); | |||||
break; | |||||
default: | |||||
DBG("TLK10232_leds() unknown op 0x%x\n", op); | |||||
break; | |||||
} | |||||
} // TLK10232_leds() | |||||
//------------------------------------------------------------------------------------------------- | |||||
__init enum PHY_TYPE TLK10232_register(struct bdx_priv *priv) | |||||
{ | |||||
priv->isr_mask= IR_RX_FREE_0 | IR_LNKCHG0 | IR_PSE | IR_TMR0 | IR_RX_DESC_0 | IR_TX_FREE_0; | |||||
priv->phy_ops.mdio_reset = TLK10232_mdio_reset; | |||||
priv->phy_ops.link_changed = TLK10232_link_changed; | |||||
priv->phy_ops.ledset = TLK10232_leds; | |||||
priv->phy_ops.mdio_speed = MDIO_SPEED_1MHZ; | |||||
TLK10232_register_settings(priv); | |||||
return PHY_TYPE_TLK10232; | |||||
} // TLK10232_init() | |||||
//------------------------------------------------------------------------------------------------- | |||||