Commit 37c65969 authored by Peter Shih's avatar Peter Shih Committed by Guillaume Tucker

Add driver for RTL8153b based USB network dongles.

BUG=b:70655060
TEST=Booted into the netboot payload using image.dev.bin ctrl-n, using
     Servo v4 as network dongle.
BRANCH=none

Change-Id: Iab42412789e3db0d0ba47d11344546a4a33bd108
Signed-off-by: default avatarPi-Hsun Shih <pihsun@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1006566Reviewed-by: default avatarJulius Werner <jwerner@chromium.org>
parent 53b43ca6
......@@ -128,6 +128,28 @@ static int ocp_write_dword(usbdev_t *dev, uint16_t type, uint16_t index,
return ocp_write(dev, index, ByteEnDword, sizeof(val), &val, type);
}
static int ocp_dword_clrsetbits(usbdev_t *dev, uint16_t type, uint16_t index,
uint32_t clr_mask, uint32_t set_mask)
{
uint32_t data;
if (ocp_read_dword(dev, type, index, &data))
return 1;
data = (data & ~clr_mask) | set_mask;
return ocp_write_dword(dev, type, index, data);
}
static int ocp_dword_setbits(usbdev_t *dev, uint16_t type, uint16_t index,
uint32_t set_mask)
{
return ocp_dword_clrsetbits(dev, type, index, 0, set_mask);
}
static int ocp_dword_clearbits(usbdev_t *dev, uint16_t type, uint16_t index,
uint32_t clr_mask)
{
return ocp_dword_clrsetbits(dev, type, index, clr_mask, 0);
}
static int ocp_read_word(usbdev_t *dev, uint16_t type, uint16_t index,
uint16_t *val)
{
......@@ -456,16 +478,12 @@ static int r8153_hw_phy_cfg(usbdev_t *dev)
static int r8153_set_rx_mode(usbdev_t *dev)
{
uint32_t data;
uint32_t tmp[2] = { 0xffffffff, 0xffffffff };
if (ocp_write(dev, PlaMar, ByteEnDword, sizeof(tmp), tmp, McuTypePla))
return 1;
if (ocp_read_dword(dev, McuTypePla, PlaRcr, &data))
return 1;
data |= RcrAb | RcrApm | RcrAm;
if (ocp_write_dword(dev, McuTypePla, PlaRcr, data))
if (ocp_dword_setbits(dev, McuTypePla, PlaRcr, RcrAb | RcrApm | RcrAm))
return 1;
return 0;
......@@ -600,6 +618,135 @@ static int r8153_init(usbdev_t *dev)
return 0;
}
static int r8153b_power_cut_disable(usbdev_t *dev)
{
if (ocp_word_clearbits(dev, McuTypeUsb, UsbPowerCut, PwrEn))
return 1;
if (ocp_word_clearbits(dev, McuTypeUsb, UsbMisc0, PcutStatus))
return 1;
return 0;
}
static int r8153b_ups_disable(usbdev_t *dev)
{
if (ocp_byte_clearbits(dev, McuTypeUsb, UsbPowerCut,
UpsEn | UpsPrewake))
return 1;
if (ocp_byte_clearbits(dev, McuTypeUsb, 0xcfff, 1 << 0))
return 1;
if (ocp_byte_clearbits(dev, McuTypeUsb, UsbMisc0, PcutStatus))
return 1;
return 0;
}
static int r8153b_queue_wake_disable(usbdev_t *dev)
{
if (ocp_byte_clearbits(dev, McuTypePla, 0xd38a, 1 << 0))
return 1;
if (ocp_byte_clearbits(dev, McuTypePla, 0xd38c, 1 << 0))
return 1;
return 0;
}
static int rtl_runtime_suspend_disable(usbdev_t *dev)
{
if (ocp_write_byte(dev, McuTypePla, PlaCrwecr, CrwecrConfig))
return 1;
if (ocp_word_clearbits(dev, McuTypePla, PlaConfig34, LinkOffWakeEn))
return 1;
if (ocp_write_byte(dev, McuTypePla, PlaCrwecr, CrwecrNormal))
return 1;
return 0;
}
static int r8153b_eee_disable(usbdev_t *dev)
{
if (r8153_eee_disable(dev))
return 1;
if (ocp_dword_clearbits(dev, McuTypeUsb, UsbUpsFlags, UpsFlagsEnEee))
return 1;
return 0;
}
static int r8153b_hw_phy_cfg(usbdev_t *dev)
{
if (r8153b_eee_disable(dev))
return 1;
if (ocp_reg_write(dev, OcpEeeAdv, 0))
return 1;
if (ocp_reg_setbits(dev, OcpNctlCfg, PgaReturnEn))
return 1;
if (ocp_word_setbits(dev, McuTypePla, PlaPhyPwr, PfmPwmSwitch))
return 1;
return 0;
}
static int r8153b_init(usbdev_t *dev)
{
uint16_t data;
if (r8153_wait_autoload_done(dev))
return 1;
if (r8153_wait_for_phy_status(dev, 0))
return 1;
if (r8152_mdio_read(dev, MiiBmcr, &data))
return 1;
data &= ~BmcrPowerDown;
if (r8152_mdio_write(dev, MiiBmcr, data))
return 1;
if (r8153_wait_for_phy_status(dev, PhyStatLanOn))
return 1;
if (ocp_write_word(dev, McuTypeUsb, UsbMscTimer, 0x0fff))
return 1;
if (r8153b_power_cut_disable(dev))
return 1;
if (r8153b_ups_disable(dev))
return 1;
if (r8153b_queue_wake_disable(dev))
return 1;
if (rtl_runtime_suspend_disable(dev))
return 1;
if (ocp_word_clearbits(dev, McuTypeUsb, UsbUsbCtrl,
RxAggDisable | RxZeroEn))
return 1;
if (rtl_tally_reset(dev))
return 1;
if (rtl_enable(dev))
return 1;
if (r8153b_hw_phy_cfg(dev))
return 1;
return 0;
}
/*
* The higher-level commands
*/
......@@ -637,8 +784,9 @@ static int rtl8152_init(GenericUsbDevice *gen_dev)
break;
case RtlVersion08:
case RtlVersion09:
printf("RTL8153b is not supported yet.");
return 1;
if (r8153b_init(usb_dev))
return 1;
break;
}
printf("R8152: Done initializing\n");
......
......@@ -31,7 +31,6 @@ static const uint16_t ByteEnWord = 0x33;
static const uint16_t ByteEnByte = 0x11;
static const uint16_t ByteEnStartMask = 0x0f;
static const uint16_t ByteEnEndMask = 0xf0;
static const uint16_t ByteEnSixBytes = 0x3f;
enum {
RtlVersionUnknown = 0,
......@@ -54,7 +53,6 @@ enum {
PlaDmyReg0 = 0xc0b0,
PlaFmc = 0xc0b4,
PlaMar = 0xcd00,
PlaBackup = 0xd000,
PlaLedFeature = 0xdd92,
PlaBootCtrl = 0xe004,
PlaEeeCr = 0xe040,
......@@ -66,6 +64,7 @@ enum {
PlaRsttally = 0xe800,
PlaCr = 0xe813,
PlaCrwecr = 0xe81c,
PlaConfig34 = 0xe820,
PlaPhyPwr = 0xe84c,
PlaMisc1 = 0xe85a,
PlaOcpGphyBase = 0xe86c
......@@ -111,6 +110,11 @@ enum {
CrwecrConfig = 0xc0
};
/* PlaConfig34 */
enum {
LinkOffWakeEn = 0x0008
};
/* PlaPhyPwr */
enum {
PfmPwmSwitch = 0x0040
......@@ -123,12 +127,14 @@ enum {
UsbCsrDummy1 = 0xb464,
UsbCsrDummy2 = 0xb466,
UsbConnectTimer = 0xcbf8,
UsbMscTimer = 0xcbfc,
UsbBurstSize = 0xcfc0,
UsbUsbCtrl = 0xd406,
UsbLpmCtrl = 0xd41a,
UsbPowerCut = 0xd80a,
UsbMisc0 = 0xd81a,
UsbAfeCtrl2 = 0xd824,
UsbUpsFlags = 0xd848,
UsbWdt11Ctrl = 0xe43c
};
......@@ -152,7 +158,9 @@ static const uint8_t RokExitLpm = 0x02;
/* UsbPowerCut */
enum {
PwrEn = 0x0001,
Phase2En = 0x0008
Phase2En = 0x0008,
UpsEn = 1 << 4,
UpsPrewake = 1 << 5
};
/* UsbMisc0 */
......@@ -163,6 +171,11 @@ static const uint16_t SenValMask = 0xf800;
static const uint16_t SenValNormal = 0xa000;
static const uint16_t SelRxidle = 0x0100;
/* UsbUpsFlags */
enum {
UpsFlagsEnEee = 1 << 20
};
/* UsbWdt11Ctrl */
static const uint16_t Timer11En = 0x0001;
......@@ -174,6 +187,7 @@ enum {
enum {
OcpBaseMii = 0xa400,
OcpPhyStatus = 0xa420,
OcpNctlCfg = 0xa42c,
OcpPowerCfg = 0xa430,
OcpEeeCfg = 0xa432,
OcpSramAddr = 0xa436,
......@@ -190,6 +204,10 @@ enum {
PhyStatPwrdn = 0x5
};
enum {
PgaReturnEn = 1 << 1
};
/* OcpPowerCfg */
enum {
EeeClkdivEn = 0x8000,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment