Skip to content

Commit 6b4950d

Browse files
committed
Merge branch 'r8152-adjust-flow-for-power-cut'
Hayes Wang says: ==================== r8152: adjust flow for power cut The two patches are used to adjust the flow about resuming from the state of power cut. For the purpose, some functions have to be updated first. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents add285b + 80fd850 commit 6b4950d

File tree

1 file changed

+89
-61
lines changed

1 file changed

+89
-61
lines changed

drivers/net/usb/r8152.c

Lines changed: 89 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,10 @@ void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val)
13711371
static int
13721372
r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags);
13731373

1374+
static int
1375+
rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex,
1376+
u32 advertising);
1377+
13741378
static int rtl8152_set_mac_address(struct net_device *netdev, void *p)
13751379
{
13761380
struct r8152 *tp = netdev_priv(netdev);
@@ -3205,40 +3209,27 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable)
32053209
ocp_data |= BIT(0);
32063210
ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data);
32073211
} else {
3208-
u16 data;
3209-
32103212
ocp_data &= ~(UPS_EN | USP_PREWAKE);
32113213
ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data);
32123214

32133215
ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xcfff);
32143216
ocp_data &= ~BIT(0);
32153217
ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data);
32163218

3217-
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0);
3218-
ocp_data &= ~PCUT_STATUS;
3219-
ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data);
3220-
3221-
data = r8153_phy_status(tp, 0);
3222-
3223-
switch (data) {
3224-
case PHY_STAT_PWRDN:
3225-
case PHY_STAT_EXT_INIT:
3226-
r8153b_green_en(tp,
3227-
test_bit(GREEN_ETHERNET, &tp->flags));
3219+
if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) {
3220+
int i;
32283221

3229-
data = r8152_mdio_read(tp, MII_BMCR);
3230-
data &= ~BMCR_PDOWN;
3231-
data |= BMCR_RESET;
3232-
r8152_mdio_write(tp, MII_BMCR, data);
3222+
for (i = 0; i < 500; i++) {
3223+
if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) &
3224+
AUTOLOAD_DONE)
3225+
break;
3226+
msleep(20);
3227+
}
32333228

3234-
data = r8153_phy_status(tp, PHY_STAT_LAN_ON);
3235-
fallthrough;
3229+
tp->rtl_ops.hw_phy_cfg(tp);
32363230

3237-
default:
3238-
if (data != PHY_STAT_LAN_ON)
3239-
netif_warn(tp, link, tp->netdev,
3240-
"PHY not ready");
3241-
break;
3231+
rtl8152_set_speed(tp, tp->autoneg, tp->speed,
3232+
tp->duplex, tp->advertising);
32423233
}
32433234
}
32443235
}
@@ -3468,59 +3459,76 @@ static void rtl_clear_bp(struct r8152 *tp, u16 type)
34683459
ocp_write_word(tp, type, PLA_BP_BA, 0);
34693460
}
34703461

3471-
static int r8153_patch_request(struct r8152 *tp, bool request)
3462+
static int rtl_phy_patch_request(struct r8152 *tp, bool request, bool wait)
34723463
{
3473-
u16 data;
3464+
u16 data, check;
34743465
int i;
34753466

34763467
data = ocp_reg_read(tp, OCP_PHY_PATCH_CMD);
3477-
if (request)
3468+
if (request) {
34783469
data |= PATCH_REQUEST;
3479-
else
3470+
check = 0;
3471+
} else {
34803472
data &= ~PATCH_REQUEST;
3473+
check = PATCH_READY;
3474+
}
34813475
ocp_reg_write(tp, OCP_PHY_PATCH_CMD, data);
34823476

3483-
for (i = 0; request && i < 5000; i++) {
3477+
for (i = 0; wait && i < 5000; i++) {
3478+
u32 ocp_data;
3479+
34843480
usleep_range(1000, 2000);
3485-
if (ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)
3481+
ocp_data = ocp_reg_read(tp, OCP_PHY_PATCH_STAT);
3482+
if ((ocp_data & PATCH_READY) ^ check)
34863483
break;
34873484
}
34883485

3489-
if (request && !(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) {
3490-
netif_err(tp, drv, tp->netdev, "patch request fail\n");
3491-
r8153_patch_request(tp, false);
3486+
if (request && wait &&
3487+
!(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) {
3488+
dev_err(&tp->intf->dev, "PHY patch request fail\n");
3489+
rtl_phy_patch_request(tp, false, false);
34923490
return -ETIME;
34933491
} else {
34943492
return 0;
34953493
}
34963494
}
34973495

3498-
static int r8153_pre_ram_code(struct r8152 *tp, u16 key_addr, u16 patch_key)
3496+
static void rtl_patch_key_set(struct r8152 *tp, u16 key_addr, u16 patch_key)
34993497
{
3500-
if (r8153_patch_request(tp, true)) {
3501-
dev_err(&tp->intf->dev, "patch request fail\n");
3502-
return -ETIME;
3503-
}
3498+
if (patch_key && key_addr) {
3499+
sram_write(tp, key_addr, patch_key);
3500+
sram_write(tp, SRAM_PHY_LOCK, PHY_PATCH_LOCK);
3501+
} else if (key_addr) {
3502+
u16 data;
35043503

3505-
sram_write(tp, key_addr, patch_key);
3506-
sram_write(tp, SRAM_PHY_LOCK, PHY_PATCH_LOCK);
3504+
sram_write(tp, 0x0000, 0x0000);
35073505

3508-
return 0;
3506+
data = ocp_reg_read(tp, OCP_PHY_LOCK);
3507+
data &= ~PATCH_LOCK;
3508+
ocp_reg_write(tp, OCP_PHY_LOCK, data);
3509+
3510+
sram_write(tp, key_addr, 0x0000);
3511+
} else {
3512+
WARN_ON_ONCE(1);
3513+
}
35093514
}
35103515

3511-
static int r8153_post_ram_code(struct r8152 *tp, u16 key_addr)
3516+
static int
3517+
rtl_pre_ram_code(struct r8152 *tp, u16 key_addr, u16 patch_key, bool wait)
35123518
{
3513-
u16 data;
3519+
if (rtl_phy_patch_request(tp, true, wait))
3520+
return -ETIME;
35143521

3515-
sram_write(tp, 0x0000, 0x0000);
3522+
rtl_patch_key_set(tp, key_addr, patch_key);
35163523

3517-
data = ocp_reg_read(tp, OCP_PHY_LOCK);
3518-
data &= ~PATCH_LOCK;
3519-
ocp_reg_write(tp, OCP_PHY_LOCK, data);
3524+
return 0;
3525+
}
35203526

3521-
sram_write(tp, key_addr, 0x0000);
3527+
static int rtl_post_ram_code(struct r8152 *tp, u16 key_addr, bool wait)
3528+
{
3529+
rtl_patch_key_set(tp, key_addr, 0);
35223530

3523-
r8153_patch_request(tp, false);
3531+
rtl_phy_patch_request(tp, false, wait);
35243532

35253533
ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base);
35263534

@@ -4005,7 +4013,7 @@ static void rtl8152_fw_mac_apply(struct r8152 *tp, struct fw_mac *mac)
40054013
dev_dbg(&tp->intf->dev, "successfully applied %s\n", mac->info);
40064014
}
40074015

4008-
static void rtl8152_apply_firmware(struct r8152 *tp)
4016+
static void rtl8152_apply_firmware(struct r8152 *tp, bool power_cut)
40094017
{
40104018
struct rtl_fw *rtl_fw = &tp->rtl_fw;
40114019
const struct firmware *fw;
@@ -4036,12 +4044,11 @@ static void rtl8152_apply_firmware(struct r8152 *tp)
40364044
case RTL_FW_PHY_START:
40374045
key = (struct fw_phy_patch_key *)block;
40384046
key_addr = __le16_to_cpu(key->key_reg);
4039-
r8153_pre_ram_code(tp, key_addr,
4040-
__le16_to_cpu(key->key_data));
4047+
rtl_pre_ram_code(tp, key_addr, __le16_to_cpu(key->key_data), !power_cut);
40414048
break;
40424049
case RTL_FW_PHY_STOP:
40434050
WARN_ON(!key_addr);
4044-
r8153_post_ram_code(tp, key_addr);
4051+
rtl_post_ram_code(tp, key_addr, !power_cut);
40454052
break;
40464053
case RTL_FW_PHY_NC:
40474054
rtl8152_fw_phy_nc_apply(tp, (struct fw_phy_nc *)block);
@@ -4246,7 +4253,7 @@ static void rtl8152_disable(struct r8152 *tp)
42464253

42474254
static void r8152b_hw_phy_cfg(struct r8152 *tp)
42484255
{
4249-
rtl8152_apply_firmware(tp);
4256+
rtl8152_apply_firmware(tp, false);
42504257
rtl_eee_enable(tp, tp->eee_en);
42514258
r8152_aldps_en(tp, true);
42524259
r8152b_enable_fc(tp);
@@ -4528,7 +4535,7 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
45284535
/* disable EEE before updating the PHY parameters */
45294536
rtl_eee_enable(tp, false);
45304537

4531-
rtl8152_apply_firmware(tp);
4538+
rtl8152_apply_firmware(tp, false);
45324539

45334540
if (tp->version == RTL_VER_03) {
45344541
data = ocp_reg_read(tp, OCP_EEE_CFG);
@@ -4596,13 +4603,37 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp)
45964603
u32 ocp_data;
45974604
u16 data;
45984605

4606+
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0);
4607+
if (ocp_data & PCUT_STATUS) {
4608+
ocp_data &= ~PCUT_STATUS;
4609+
ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data);
4610+
}
4611+
45994612
/* disable ALDPS before updating the PHY parameters */
46004613
r8153_aldps_en(tp, false);
46014614

46024615
/* disable EEE before updating the PHY parameters */
46034616
rtl_eee_enable(tp, false);
46044617

4605-
rtl8152_apply_firmware(tp);
4618+
/* U1/U2/L1 idle timer. 500 us */
4619+
ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500);
4620+
4621+
data = r8153_phy_status(tp, 0);
4622+
4623+
switch (data) {
4624+
case PHY_STAT_PWRDN:
4625+
case PHY_STAT_EXT_INIT:
4626+
rtl8152_apply_firmware(tp, true);
4627+
4628+
data = r8152_mdio_read(tp, MII_BMCR);
4629+
data &= ~BMCR_PDOWN;
4630+
r8152_mdio_write(tp, MII_BMCR, data);
4631+
break;
4632+
case PHY_STAT_LAN_ON:
4633+
default:
4634+
rtl8152_apply_firmware(tp, false);
4635+
break;
4636+
}
46064637

46074638
r8153b_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags));
46084639

@@ -4643,7 +4674,7 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp)
46434674
ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data);
46444675

46454676
/* Advnace EEE */
4646-
if (!r8153_patch_request(tp, true)) {
4677+
if (!rtl_phy_patch_request(tp, true, true)) {
46474678
data = ocp_reg_read(tp, OCP_POWER_CFG);
46484679
data |= EEE_CLKDIV_EN;
46494680
ocp_reg_write(tp, OCP_POWER_CFG, data);
@@ -4660,7 +4691,7 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp)
46604691
ocp_reg_write(tp, OCP_SYSCLK_CFG, clk_div_expo(5));
46614692
tp->ups_info._250m_ckdiv = true;
46624693

4663-
r8153_patch_request(tp, false);
4694+
rtl_phy_patch_request(tp, false, true);
46644695
}
46654696

46664697
if (tp->eee_en)
@@ -5528,9 +5559,6 @@ static void r8153b_init(struct r8152 *tp)
55285559
/* MSC timer = 0xfff * 8ms = 32760 ms */
55295560
ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff);
55305561

5531-
/* U1/U2/L1 idle timer. 500 us */
5532-
ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500);
5533-
55345562
r8153b_power_cut_en(tp, false);
55355563
r8153b_ups_en(tp, false);
55365564
r8153_queue_wake(tp, false);

0 commit comments

Comments
 (0)