diff options
Diffstat (limited to 'drivers/net/usb/r8152.c')
| -rw-r--r-- | drivers/net/usb/r8152.c | 87 | 
1 files changed, 60 insertions, 27 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index decb5ba56a25..0999a58ca9d2 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -199,6 +199,7 @@  #define OCP_EEE_AR		0xa41a  #define OCP_EEE_DATA		0xa41c  #define OCP_PHY_STATUS		0xa420 +#define OCP_INTR_EN		0xa424  #define OCP_NCTL_CFG		0xa42c  #define OCP_POWER_CFG		0xa430  #define OCP_EEE_CFG		0xa432 @@ -620,6 +621,9 @@ enum spd_duplex {  #define PHY_STAT_LAN_ON		3  #define PHY_STAT_PWRDN		5 +/* OCP_INTR_EN */ +#define INTR_SPEED_FORCE	BIT(3) +  /* OCP_NCTL_CFG */  #define PGA_RETURN_EN		BIT(1) @@ -1943,7 +1947,7 @@ static struct rx_agg *alloc_rx_agg(struct r8152 *tp, gfp_t mflags)  	if (!rx_agg)  		return NULL; -	rx_agg->page = alloc_pages(mflags | __GFP_COMP, order); +	rx_agg->page = alloc_pages(mflags | __GFP_COMP | __GFP_NOWARN, order);  	if (!rx_agg->page)  		goto free_rx; @@ -3023,12 +3027,16 @@ static int rtl_enable(struct r8152 *tp)  	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data);  	switch (tp->version) { -	case RTL_VER_08: -	case RTL_VER_09: -	case RTL_VER_14: -		r8153b_rx_agg_chg_indicate(tp); +	case RTL_VER_01: +	case RTL_VER_02: +	case RTL_VER_03: +	case RTL_VER_04: +	case RTL_VER_05: +	case RTL_VER_06: +	case RTL_VER_07:  		break;  	default: +		r8153b_rx_agg_chg_indicate(tp);  		break;  	} @@ -3082,7 +3090,6 @@ static void r8153_set_rx_early_timeout(struct r8152 *tp)  			       640 / 8);  		ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EXTRA_AGGR_TMR,  			       ocp_data); -		r8153b_rx_agg_chg_indicate(tp);  		break;  	default: @@ -3116,7 +3123,6 @@ static void r8153_set_rx_early_size(struct r8152 *tp)  	case RTL_VER_15:  		ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE,  			       ocp_data / 8); -		r8153b_rx_agg_chg_indicate(tp);  		break;  	default:  		WARN_ON_ONCE(1); @@ -5986,6 +5992,25 @@ static void rtl8153_disable(struct r8152 *tp)  	r8153_aldps_en(tp, true);  } +static u32 fc_pause_on_auto(struct r8152 *tp) +{ +	return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 6 * 1024); +} + +static u32 fc_pause_off_auto(struct r8152 *tp) +{ +	return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 14 * 1024); +} + +static void r8156_fc_parameter(struct r8152 *tp) +{ +	u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp); +	u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp); + +	ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16); +	ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16); +} +  static int rtl8156_enable(struct r8152 *tp)  {  	u32 ocp_data; @@ -5994,6 +6019,7 @@ static int rtl8156_enable(struct r8152 *tp)  	if (test_bit(RTL8152_UNPLUG, &tp->flags))  		return -ENODEV; +	r8156_fc_parameter(tp);  	set_tx_qlen(tp);  	rtl_set_eee_plus(tp);  	r8153_set_rx_early_timeout(tp); @@ -6025,9 +6051,24 @@ static int rtl8156_enable(struct r8152 *tp)  		ocp_write_word(tp, MCU_TYPE_USB, USB_L1_CTRL, ocp_data);  	} +	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); +	ocp_data &= ~FC_PATCH_TASK; +	ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); +	usleep_range(1000, 2000); +	ocp_data |= FC_PATCH_TASK; +	ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); +  	return rtl_enable(tp);  } +static void rtl8156_disable(struct r8152 *tp) +{ +	ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, 0); +	ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, 0); + +	rtl8153_disable(tp); +} +  static int rtl8156b_enable(struct r8152 *tp)  {  	u32 ocp_data; @@ -6429,25 +6470,6 @@ static void rtl8153c_up(struct r8152 *tp)  	r8153b_u1u2en(tp, true);  } -static inline u32 fc_pause_on_auto(struct r8152 *tp) -{ -	return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 6 * 1024); -} - -static inline u32 fc_pause_off_auto(struct r8152 *tp) -{ -	return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 14 * 1024); -} - -static void r8156_fc_parameter(struct r8152 *tp) -{ -	u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp); -	u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp); - -	ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16); -	ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16); -} -  static void rtl8156_change_mtu(struct r8152 *tp)  {  	u32 rx_max_size = mtu_to_size(tp->netdev->mtu); @@ -7538,6 +7560,11 @@ static void r8156_hw_phy_cfg(struct r8152 *tp)  				      ((swap_a & 0x1f) << 8) |  				      ((swap_a >> 8) & 0x1f));  		} + +		/* Notify the MAC when the speed is changed to force mode. */ +		data = ocp_reg_read(tp, OCP_INTR_EN); +		data |= INTR_SPEED_FORCE; +		ocp_reg_write(tp, OCP_INTR_EN, data);  		break;  	default:  		break; @@ -7933,6 +7960,11 @@ static void r8156b_hw_phy_cfg(struct r8152 *tp)  		break;  	} +	/* Notify the MAC when the speed is changed to force mode. */ +	data = ocp_reg_read(tp, OCP_INTR_EN); +	data |= INTR_SPEED_FORCE; +	ocp_reg_write(tp, OCP_INTR_EN, data); +  	if (rtl_phy_patch_request(tp, true, true))  		return; @@ -9340,7 +9372,7 @@ static int rtl_ops_init(struct r8152 *tp)  	case RTL_VER_10:  		ops->init		= r8156_init;  		ops->enable		= rtl8156_enable; -		ops->disable		= rtl8153_disable; +		ops->disable		= rtl8156_disable;  		ops->up			= rtl8156_up;  		ops->down		= rtl8156_down;  		ops->unload		= rtl8153_unload; @@ -9878,6 +9910,7 @@ static struct usb_device_driver rtl8152_cfgselector_driver = {  	.probe =	rtl8152_cfgselector_probe,  	.id_table =	rtl8152_table,  	.generic_subclass = 1, +	.supports_autosuspend = 1,  };  static int __init rtl8152_driver_init(void)  |