Merge branch 'r8152'
Hayes Wang says: ==================== r8152: support setting eee by ethtool Modify some definitions about EEE, and add the support of setting the EEE through ethtool. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
a8404ce5ae
1 changed files with 212 additions and 40 deletions
|
@ -22,6 +22,8 @@
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/ipv6.h>
|
#include <linux/ipv6.h>
|
||||||
#include <net/ip6_checksum.h>
|
#include <net/ip6_checksum.h>
|
||||||
|
#include <uapi/linux/mdio.h>
|
||||||
|
#include <linux/mdio.h>
|
||||||
|
|
||||||
/* Version Information */
|
/* Version Information */
|
||||||
#define DRIVER_VERSION "v1.06.0 (2014/03/03)"
|
#define DRIVER_VERSION "v1.06.0 (2014/03/03)"
|
||||||
|
@ -129,7 +131,9 @@
|
||||||
#define OCP_SRAM_ADDR 0xa436
|
#define OCP_SRAM_ADDR 0xa436
|
||||||
#define OCP_SRAM_DATA 0xa438
|
#define OCP_SRAM_DATA 0xa438
|
||||||
#define OCP_DOWN_SPEED 0xa442
|
#define OCP_DOWN_SPEED 0xa442
|
||||||
#define OCP_EEE_CFG2 0xa5d0
|
#define OCP_EEE_ABLE 0xa5c4
|
||||||
|
#define OCP_EEE_ADV 0xa5d0
|
||||||
|
#define OCP_EEE_LPABLE 0xa5d2
|
||||||
#define OCP_ADC_CFG 0xbc06
|
#define OCP_ADC_CFG 0xbc06
|
||||||
|
|
||||||
/* SRAM Register */
|
/* SRAM Register */
|
||||||
|
@ -361,7 +365,8 @@
|
||||||
#define EEE_NWAY_EN 0x1000
|
#define EEE_NWAY_EN 0x1000
|
||||||
#define TX_QUIET_EN 0x0200
|
#define TX_QUIET_EN 0x0200
|
||||||
#define RX_QUIET_EN 0x0100
|
#define RX_QUIET_EN 0x0100
|
||||||
#define SDRISETIME 0x0010 /* bit 4 ~ 6 */
|
#define sd_rise_time_mask 0x0070
|
||||||
|
#define sd_rise_time(x) (min(x, 7) << 4) /* bit 4 ~ 6 */
|
||||||
#define RG_RXLPI_MSK_HFDUP 0x0008
|
#define RG_RXLPI_MSK_HFDUP 0x0008
|
||||||
#define SDFALLTIME 0x0007 /* bit 0 ~ 2 */
|
#define SDFALLTIME 0x0007 /* bit 0 ~ 2 */
|
||||||
|
|
||||||
|
@ -373,7 +378,8 @@
|
||||||
#define RG_EEEPRG_EN 0x0010
|
#define RG_EEEPRG_EN 0x0010
|
||||||
|
|
||||||
/* OCP_EEE_CONFIG3 */
|
/* OCP_EEE_CONFIG3 */
|
||||||
#define FST_SNR_EYE_R 0x1500 /* bit 7 ~ 15 */
|
#define fast_snr_mask 0xff80
|
||||||
|
#define fast_snr(x) (min(x, 0x1ff) << 7) /* bit 7 ~ 15 */
|
||||||
#define RG_LFS_SEL 0x0060 /* bit 6 ~ 5 */
|
#define RG_LFS_SEL 0x0060 /* bit 6 ~ 5 */
|
||||||
#define MSK_PH 0x0006 /* bit 0 ~ 3 */
|
#define MSK_PH 0x0006 /* bit 0 ~ 3 */
|
||||||
|
|
||||||
|
@ -382,11 +388,6 @@
|
||||||
#define FUN_ADDR 0x0000
|
#define FUN_ADDR 0x0000
|
||||||
#define FUN_DATA 0x4000
|
#define FUN_DATA 0x4000
|
||||||
/* bit[4:0] device addr */
|
/* bit[4:0] device addr */
|
||||||
#define DEVICE_ADDR 0x0007
|
|
||||||
|
|
||||||
/* OCP_EEE_DATA */
|
|
||||||
#define EEE_ADDR 0x003C
|
|
||||||
#define EEE_DATA 0x0002
|
|
||||||
|
|
||||||
/* OCP_EEE_CFG */
|
/* OCP_EEE_CFG */
|
||||||
#define CTAP_SHORT_EN 0x0040
|
#define CTAP_SHORT_EN 0x0040
|
||||||
|
@ -395,10 +396,6 @@
|
||||||
/* OCP_DOWN_SPEED */
|
/* OCP_DOWN_SPEED */
|
||||||
#define EN_10M_BGOFF 0x0080
|
#define EN_10M_BGOFF 0x0080
|
||||||
|
|
||||||
/* OCP_EEE_CFG2 */
|
|
||||||
#define MY1000_EEE 0x0004
|
|
||||||
#define MY100_EEE 0x0002
|
|
||||||
|
|
||||||
/* OCP_ADC_CFG */
|
/* OCP_ADC_CFG */
|
||||||
#define CKADSEL_L 0x0100
|
#define CKADSEL_L 0x0100
|
||||||
#define ADC_EN 0x0080
|
#define ADC_EN 0x0080
|
||||||
|
@ -577,6 +574,8 @@ struct r8152 {
|
||||||
void (*up)(struct r8152 *);
|
void (*up)(struct r8152 *);
|
||||||
void (*down)(struct r8152 *);
|
void (*down)(struct r8152 *);
|
||||||
void (*unload)(struct r8152 *);
|
void (*unload)(struct r8152 *);
|
||||||
|
int (*eee_get)(struct r8152 *, struct ethtool_eee *);
|
||||||
|
int (*eee_set)(struct r8152 *, struct ethtool_eee *);
|
||||||
} rtl_ops;
|
} rtl_ops;
|
||||||
|
|
||||||
int intr_interval;
|
int intr_interval;
|
||||||
|
@ -2957,43 +2956,92 @@ static int rtl8152_close(struct net_device *netdev)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void r8152b_enable_eee(struct r8152 *tp)
|
static inline void r8152_mmd_indirect(struct r8152 *tp, u16 dev, u16 reg)
|
||||||
{
|
{
|
||||||
|
ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | dev);
|
||||||
|
ocp_reg_write(tp, OCP_EEE_DATA, reg);
|
||||||
|
ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg)
|
||||||
|
{
|
||||||
|
u16 data;
|
||||||
|
|
||||||
|
r8152_mmd_indirect(tp, dev, reg);
|
||||||
|
data = ocp_reg_read(tp, OCP_EEE_DATA);
|
||||||
|
ocp_reg_write(tp, OCP_EEE_AR, 0x0000);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void r8152_mmd_write(struct r8152 *tp, u16 dev, u16 reg, u16 data)
|
||||||
|
{
|
||||||
|
r8152_mmd_indirect(tp, dev, reg);
|
||||||
|
ocp_reg_write(tp, OCP_EEE_DATA, data);
|
||||||
|
ocp_reg_write(tp, OCP_EEE_AR, 0x0000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void r8152_eee_en(struct r8152 *tp, bool enable)
|
||||||
|
{
|
||||||
|
u16 config1, config2, config3;
|
||||||
u32 ocp_data;
|
u32 ocp_data;
|
||||||
|
|
||||||
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
|
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
|
||||||
ocp_data |= EEE_RX_EN | EEE_TX_EN;
|
config1 = ocp_reg_read(tp, OCP_EEE_CONFIG1) & ~sd_rise_time_mask;
|
||||||
|
config2 = ocp_reg_read(tp, OCP_EEE_CONFIG2);
|
||||||
|
config3 = ocp_reg_read(tp, OCP_EEE_CONFIG3) & ~fast_snr_mask;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
ocp_data |= EEE_RX_EN | EEE_TX_EN;
|
||||||
|
config1 |= EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | RX_QUIET_EN;
|
||||||
|
config1 |= sd_rise_time(1);
|
||||||
|
config2 |= RG_DACQUIET_EN | RG_LDVQUIET_EN;
|
||||||
|
config3 |= fast_snr(42);
|
||||||
|
} else {
|
||||||
|
ocp_data &= ~(EEE_RX_EN | EEE_TX_EN);
|
||||||
|
config1 &= ~(EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN |
|
||||||
|
RX_QUIET_EN);
|
||||||
|
config1 |= sd_rise_time(7);
|
||||||
|
config2 &= ~(RG_DACQUIET_EN | RG_LDVQUIET_EN);
|
||||||
|
config3 |= fast_snr(511);
|
||||||
|
}
|
||||||
|
|
||||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data);
|
ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data);
|
||||||
ocp_reg_write(tp, OCP_EEE_CONFIG1, RG_TXLPI_MSK_HFDUP | RG_MATCLR_EN |
|
ocp_reg_write(tp, OCP_EEE_CONFIG1, config1);
|
||||||
EEE_10_CAP | EEE_NWAY_EN |
|
ocp_reg_write(tp, OCP_EEE_CONFIG2, config2);
|
||||||
TX_QUIET_EN | RX_QUIET_EN |
|
ocp_reg_write(tp, OCP_EEE_CONFIG3, config3);
|
||||||
SDRISETIME | RG_RXLPI_MSK_HFDUP |
|
}
|
||||||
SDFALLTIME);
|
|
||||||
ocp_reg_write(tp, OCP_EEE_CONFIG2, RG_LPIHYS_NUM | RG_DACQUIET_EN |
|
static void r8152b_enable_eee(struct r8152 *tp)
|
||||||
RG_LDVQUIET_EN | RG_CKRSEL |
|
{
|
||||||
RG_EEEPRG_EN);
|
r8152_eee_en(tp, true);
|
||||||
ocp_reg_write(tp, OCP_EEE_CONFIG3, FST_SNR_EYE_R | RG_LFS_SEL | MSK_PH);
|
r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, MDIO_EEE_100TX);
|
||||||
ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | DEVICE_ADDR);
|
}
|
||||||
ocp_reg_write(tp, OCP_EEE_DATA, EEE_ADDR);
|
|
||||||
ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | DEVICE_ADDR);
|
static void r8153_eee_en(struct r8152 *tp, bool enable)
|
||||||
ocp_reg_write(tp, OCP_EEE_DATA, EEE_DATA);
|
{
|
||||||
ocp_reg_write(tp, OCP_EEE_AR, 0x0000);
|
u32 ocp_data;
|
||||||
|
u16 config;
|
||||||
|
|
||||||
|
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
|
||||||
|
config = ocp_reg_read(tp, OCP_EEE_CFG);
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
ocp_data |= EEE_RX_EN | EEE_TX_EN;
|
||||||
|
config |= EEE10_EN;
|
||||||
|
} else {
|
||||||
|
ocp_data &= ~(EEE_RX_EN | EEE_TX_EN);
|
||||||
|
config &= ~EEE10_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data);
|
||||||
|
ocp_reg_write(tp, OCP_EEE_CFG, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void r8153_enable_eee(struct r8152 *tp)
|
static void r8153_enable_eee(struct r8152 *tp)
|
||||||
{
|
{
|
||||||
u32 ocp_data;
|
r8153_eee_en(tp, true);
|
||||||
u16 data;
|
ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX);
|
||||||
|
|
||||||
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
|
|
||||||
ocp_data |= EEE_RX_EN | EEE_TX_EN;
|
|
||||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data);
|
|
||||||
data = ocp_reg_read(tp, OCP_EEE_CFG);
|
|
||||||
data |= EEE10_EN;
|
|
||||||
ocp_reg_write(tp, OCP_EEE_CFG, data);
|
|
||||||
data = ocp_reg_read(tp, OCP_EEE_CFG2);
|
|
||||||
data |= MY1000_EEE | MY100_EEE;
|
|
||||||
ocp_reg_write(tp, OCP_EEE_CFG2, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void r8152b_enable_fc(struct r8152 *tp)
|
static void r8152b_enable_fc(struct r8152 *tp)
|
||||||
|
@ -3322,6 +3370,122 @@ static void rtl8152_get_strings(struct net_device *dev, u32 stringset, u8 *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int r8152_get_eee(struct r8152 *tp, struct ethtool_eee *eee)
|
||||||
|
{
|
||||||
|
u32 ocp_data, lp, adv, supported = 0;
|
||||||
|
u16 val;
|
||||||
|
|
||||||
|
val = r8152_mmd_read(tp, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
|
||||||
|
supported = mmd_eee_cap_to_ethtool_sup_t(val);
|
||||||
|
|
||||||
|
val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
|
||||||
|
adv = mmd_eee_adv_to_ethtool_adv_t(val);
|
||||||
|
|
||||||
|
val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
|
||||||
|
lp = mmd_eee_adv_to_ethtool_adv_t(val);
|
||||||
|
|
||||||
|
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
|
||||||
|
ocp_data &= EEE_RX_EN | EEE_TX_EN;
|
||||||
|
|
||||||
|
eee->eee_enabled = !!ocp_data;
|
||||||
|
eee->eee_active = !!(supported & adv & lp);
|
||||||
|
eee->supported = supported;
|
||||||
|
eee->advertised = adv;
|
||||||
|
eee->lp_advertised = lp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int r8152_set_eee(struct r8152 *tp, struct ethtool_eee *eee)
|
||||||
|
{
|
||||||
|
u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised);
|
||||||
|
|
||||||
|
r8152_eee_en(tp, eee->eee_enabled);
|
||||||
|
|
||||||
|
if (!eee->eee_enabled)
|
||||||
|
val = 0;
|
||||||
|
|
||||||
|
r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int r8153_get_eee(struct r8152 *tp, struct ethtool_eee *eee)
|
||||||
|
{
|
||||||
|
u32 ocp_data, lp, adv, supported = 0;
|
||||||
|
u16 val;
|
||||||
|
|
||||||
|
val = ocp_reg_read(tp, OCP_EEE_ABLE);
|
||||||
|
supported = mmd_eee_cap_to_ethtool_sup_t(val);
|
||||||
|
|
||||||
|
val = ocp_reg_read(tp, OCP_EEE_ADV);
|
||||||
|
adv = mmd_eee_adv_to_ethtool_adv_t(val);
|
||||||
|
|
||||||
|
val = ocp_reg_read(tp, OCP_EEE_LPABLE);
|
||||||
|
lp = mmd_eee_adv_to_ethtool_adv_t(val);
|
||||||
|
|
||||||
|
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
|
||||||
|
ocp_data &= EEE_RX_EN | EEE_TX_EN;
|
||||||
|
|
||||||
|
eee->eee_enabled = !!ocp_data;
|
||||||
|
eee->eee_active = !!(supported & adv & lp);
|
||||||
|
eee->supported = supported;
|
||||||
|
eee->advertised = adv;
|
||||||
|
eee->lp_advertised = lp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int r8153_set_eee(struct r8152 *tp, struct ethtool_eee *eee)
|
||||||
|
{
|
||||||
|
u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised);
|
||||||
|
|
||||||
|
r8153_eee_en(tp, eee->eee_enabled);
|
||||||
|
|
||||||
|
if (!eee->eee_enabled)
|
||||||
|
val = 0;
|
||||||
|
|
||||||
|
ocp_reg_write(tp, OCP_EEE_ADV, val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *edata)
|
||||||
|
{
|
||||||
|
struct r8152 *tp = netdev_priv(net);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = usb_autopm_get_interface(tp->intf);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = tp->rtl_ops.eee_get(tp, edata);
|
||||||
|
|
||||||
|
usb_autopm_put_interface(tp->intf);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata)
|
||||||
|
{
|
||||||
|
struct r8152 *tp = netdev_priv(net);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = usb_autopm_get_interface(tp->intf);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = tp->rtl_ops.eee_set(tp, edata);
|
||||||
|
|
||||||
|
usb_autopm_put_interface(tp->intf);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static struct ethtool_ops ops = {
|
static struct ethtool_ops ops = {
|
||||||
.get_drvinfo = rtl8152_get_drvinfo,
|
.get_drvinfo = rtl8152_get_drvinfo,
|
||||||
.get_settings = rtl8152_get_settings,
|
.get_settings = rtl8152_get_settings,
|
||||||
|
@ -3334,6 +3498,8 @@ static struct ethtool_ops ops = {
|
||||||
.get_strings = rtl8152_get_strings,
|
.get_strings = rtl8152_get_strings,
|
||||||
.get_sset_count = rtl8152_get_sset_count,
|
.get_sset_count = rtl8152_get_sset_count,
|
||||||
.get_ethtool_stats = rtl8152_get_ethtool_stats,
|
.get_ethtool_stats = rtl8152_get_ethtool_stats,
|
||||||
|
.get_eee = rtl_ethtool_get_eee,
|
||||||
|
.set_eee = rtl_ethtool_set_eee,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
|
static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
|
||||||
|
@ -3475,6 +3641,8 @@ static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id)
|
||||||
ops->up = rtl8152_up;
|
ops->up = rtl8152_up;
|
||||||
ops->down = rtl8152_down;
|
ops->down = rtl8152_down;
|
||||||
ops->unload = rtl8152_unload;
|
ops->unload = rtl8152_unload;
|
||||||
|
ops->eee_get = r8152_get_eee;
|
||||||
|
ops->eee_set = r8152_set_eee;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
case PRODUCT_ID_RTL8153:
|
case PRODUCT_ID_RTL8153:
|
||||||
|
@ -3484,6 +3652,8 @@ static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id)
|
||||||
ops->up = rtl8153_up;
|
ops->up = rtl8153_up;
|
||||||
ops->down = rtl8153_down;
|
ops->down = rtl8153_down;
|
||||||
ops->unload = rtl8153_unload;
|
ops->unload = rtl8153_unload;
|
||||||
|
ops->eee_get = r8153_get_eee;
|
||||||
|
ops->eee_set = r8153_set_eee;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -3500,6 +3670,8 @@ static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id)
|
||||||
ops->up = rtl8153_up;
|
ops->up = rtl8153_up;
|
||||||
ops->down = rtl8153_down;
|
ops->down = rtl8153_down;
|
||||||
ops->unload = rtl8153_unload;
|
ops->unload = rtl8153_unload;
|
||||||
|
ops->eee_get = r8153_get_eee;
|
||||||
|
ops->eee_set = r8153_set_eee;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Add table
Reference in a new issue