Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+212 -40
+212 -40
drivers/net/usb/r8152.c
··· 22 22 #include <linux/ip.h> 23 23 #include <linux/ipv6.h> 24 24 #include <net/ip6_checksum.h> 25 + #include <uapi/linux/mdio.h> 26 + #include <linux/mdio.h> 25 27 26 28 /* Version Information */ 27 29 #define DRIVER_VERSION "v1.06.0 (2014/03/03)" ··· 131 129 #define OCP_SRAM_ADDR 0xa436 132 130 #define OCP_SRAM_DATA 0xa438 133 131 #define OCP_DOWN_SPEED 0xa442 134 - #define OCP_EEE_CFG2 0xa5d0 132 + #define OCP_EEE_ABLE 0xa5c4 133 + #define OCP_EEE_ADV 0xa5d0 134 + #define OCP_EEE_LPABLE 0xa5d2 135 135 #define OCP_ADC_CFG 0xbc06 136 136 137 137 /* SRAM Register */ ··· 365 361 #define EEE_NWAY_EN 0x1000 366 362 #define TX_QUIET_EN 0x0200 367 363 #define RX_QUIET_EN 0x0100 368 - #define SDRISETIME 0x0010 /* bit 4 ~ 6 */ 364 + #define sd_rise_time_mask 0x0070 365 + #define sd_rise_time(x) (min(x, 7) << 4) /* bit 4 ~ 6 */ 369 366 #define RG_RXLPI_MSK_HFDUP 0x0008 370 367 #define SDFALLTIME 0x0007 /* bit 0 ~ 2 */ 371 368 ··· 378 373 #define RG_EEEPRG_EN 0x0010 379 374 380 375 /* OCP_EEE_CONFIG3 */ 381 - #define FST_SNR_EYE_R 0x1500 /* bit 7 ~ 15 */ 376 + #define fast_snr_mask 0xff80 377 + #define fast_snr(x) (min(x, 0x1ff) << 7) /* bit 7 ~ 15 */ 382 378 #define RG_LFS_SEL 0x0060 /* bit 6 ~ 5 */ 383 379 #define MSK_PH 0x0006 /* bit 0 ~ 3 */ 384 380 ··· 388 382 #define FUN_ADDR 0x0000 389 383 #define FUN_DATA 0x4000 390 384 /* bit[4:0] device addr */ 391 - #define DEVICE_ADDR 0x0007 392 - 393 - /* OCP_EEE_DATA */ 394 - #define EEE_ADDR 0x003C 395 - #define EEE_DATA 0x0002 396 385 397 386 /* OCP_EEE_CFG */ 398 387 #define CTAP_SHORT_EN 0x0040 ··· 395 394 396 395 /* OCP_DOWN_SPEED */ 397 396 #define EN_10M_BGOFF 0x0080 398 - 399 - /* OCP_EEE_CFG2 */ 400 - #define MY1000_EEE 0x0004 401 - #define MY100_EEE 0x0002 402 397 403 398 /* OCP_ADC_CFG */ 404 399 #define CKADSEL_L 0x0100 ··· 574 577 void (*up)(struct r8152 *); 575 578 void (*down)(struct r8152 *); 576 579 void (*unload)(struct r8152 *); 580 + int (*eee_get)(struct r8152 *, struct ethtool_eee *); 581 + int (*eee_set)(struct r8152 *, struct ethtool_eee *); 577 582 } rtl_ops; 578 583 579 584 int intr_interval; ··· 2956 2957 return res; 2957 2958 } 2958 2959 2959 - static void r8152b_enable_eee(struct r8152 *tp) 2960 + static inline void r8152_mmd_indirect(struct r8152 *tp, u16 dev, u16 reg) 2960 2961 { 2962 + ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | dev); 2963 + ocp_reg_write(tp, OCP_EEE_DATA, reg); 2964 + ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | dev); 2965 + } 2966 + 2967 + static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg) 2968 + { 2969 + u16 data; 2970 + 2971 + r8152_mmd_indirect(tp, dev, reg); 2972 + data = ocp_reg_read(tp, OCP_EEE_DATA); 2973 + ocp_reg_write(tp, OCP_EEE_AR, 0x0000); 2974 + 2975 + return data; 2976 + } 2977 + 2978 + static void r8152_mmd_write(struct r8152 *tp, u16 dev, u16 reg, u16 data) 2979 + { 2980 + r8152_mmd_indirect(tp, dev, reg); 2981 + ocp_reg_write(tp, OCP_EEE_DATA, data); 2982 + ocp_reg_write(tp, OCP_EEE_AR, 0x0000); 2983 + } 2984 + 2985 + static void r8152_eee_en(struct r8152 *tp, bool enable) 2986 + { 2987 + u16 config1, config2, config3; 2961 2988 u32 ocp_data; 2962 2989 2963 2990 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); 2964 - ocp_data |= EEE_RX_EN | EEE_TX_EN; 2991 + config1 = ocp_reg_read(tp, OCP_EEE_CONFIG1) & ~sd_rise_time_mask; 2992 + config2 = ocp_reg_read(tp, OCP_EEE_CONFIG2); 2993 + config3 = ocp_reg_read(tp, OCP_EEE_CONFIG3) & ~fast_snr_mask; 2994 + 2995 + if (enable) { 2996 + ocp_data |= EEE_RX_EN | EEE_TX_EN; 2997 + config1 |= EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | RX_QUIET_EN; 2998 + config1 |= sd_rise_time(1); 2999 + config2 |= RG_DACQUIET_EN | RG_LDVQUIET_EN; 3000 + config3 |= fast_snr(42); 3001 + } else { 3002 + ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); 3003 + config1 &= ~(EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | 3004 + RX_QUIET_EN); 3005 + config1 |= sd_rise_time(7); 3006 + config2 &= ~(RG_DACQUIET_EN | RG_LDVQUIET_EN); 3007 + config3 |= fast_snr(511); 3008 + } 3009 + 2965 3010 ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); 2966 - ocp_reg_write(tp, OCP_EEE_CONFIG1, RG_TXLPI_MSK_HFDUP | RG_MATCLR_EN | 2967 - EEE_10_CAP | EEE_NWAY_EN | 2968 - TX_QUIET_EN | RX_QUIET_EN | 2969 - SDRISETIME | RG_RXLPI_MSK_HFDUP | 2970 - SDFALLTIME); 2971 - ocp_reg_write(tp, OCP_EEE_CONFIG2, RG_LPIHYS_NUM | RG_DACQUIET_EN | 2972 - RG_LDVQUIET_EN | RG_CKRSEL | 2973 - RG_EEEPRG_EN); 2974 - ocp_reg_write(tp, OCP_EEE_CONFIG3, FST_SNR_EYE_R | RG_LFS_SEL | MSK_PH); 2975 - ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | DEVICE_ADDR); 2976 - ocp_reg_write(tp, OCP_EEE_DATA, EEE_ADDR); 2977 - ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | DEVICE_ADDR); 2978 - ocp_reg_write(tp, OCP_EEE_DATA, EEE_DATA); 2979 - ocp_reg_write(tp, OCP_EEE_AR, 0x0000); 3011 + ocp_reg_write(tp, OCP_EEE_CONFIG1, config1); 3012 + ocp_reg_write(tp, OCP_EEE_CONFIG2, config2); 3013 + ocp_reg_write(tp, OCP_EEE_CONFIG3, config3); 3014 + } 3015 + 3016 + static void r8152b_enable_eee(struct r8152 *tp) 3017 + { 3018 + r8152_eee_en(tp, true); 3019 + r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, MDIO_EEE_100TX); 3020 + } 3021 + 3022 + static void r8153_eee_en(struct r8152 *tp, bool enable) 3023 + { 3024 + u32 ocp_data; 3025 + u16 config; 3026 + 3027 + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); 3028 + config = ocp_reg_read(tp, OCP_EEE_CFG); 3029 + 3030 + if (enable) { 3031 + ocp_data |= EEE_RX_EN | EEE_TX_EN; 3032 + config |= EEE10_EN; 3033 + } else { 3034 + ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); 3035 + config &= ~EEE10_EN; 3036 + } 3037 + 3038 + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); 3039 + ocp_reg_write(tp, OCP_EEE_CFG, config); 2980 3040 } 2981 3041 2982 3042 static void r8153_enable_eee(struct r8152 *tp) 2983 3043 { 2984 - u32 ocp_data; 2985 - u16 data; 2986 - 2987 - ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); 2988 - ocp_data |= EEE_RX_EN | EEE_TX_EN; 2989 - ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); 2990 - data = ocp_reg_read(tp, OCP_EEE_CFG); 2991 - data |= EEE10_EN; 2992 - ocp_reg_write(tp, OCP_EEE_CFG, data); 2993 - data = ocp_reg_read(tp, OCP_EEE_CFG2); 2994 - data |= MY1000_EEE | MY100_EEE; 2995 - ocp_reg_write(tp, OCP_EEE_CFG2, data); 3044 + r8153_eee_en(tp, true); 3045 + ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX); 2996 3046 } 2997 3047 2998 3048 static void r8152b_enable_fc(struct r8152 *tp) ··· 3370 3322 } 3371 3323 } 3372 3324 3325 + static int r8152_get_eee(struct r8152 *tp, struct ethtool_eee *eee) 3326 + { 3327 + u32 ocp_data, lp, adv, supported = 0; 3328 + u16 val; 3329 + 3330 + val = r8152_mmd_read(tp, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); 3331 + supported = mmd_eee_cap_to_ethtool_sup_t(val); 3332 + 3333 + val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV); 3334 + adv = mmd_eee_adv_to_ethtool_adv_t(val); 3335 + 3336 + val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE); 3337 + lp = mmd_eee_adv_to_ethtool_adv_t(val); 3338 + 3339 + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); 3340 + ocp_data &= EEE_RX_EN | EEE_TX_EN; 3341 + 3342 + eee->eee_enabled = !!ocp_data; 3343 + eee->eee_active = !!(supported & adv & lp); 3344 + eee->supported = supported; 3345 + eee->advertised = adv; 3346 + eee->lp_advertised = lp; 3347 + 3348 + return 0; 3349 + } 3350 + 3351 + static int r8152_set_eee(struct r8152 *tp, struct ethtool_eee *eee) 3352 + { 3353 + u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); 3354 + 3355 + r8152_eee_en(tp, eee->eee_enabled); 3356 + 3357 + if (!eee->eee_enabled) 3358 + val = 0; 3359 + 3360 + r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); 3361 + 3362 + return 0; 3363 + } 3364 + 3365 + static int r8153_get_eee(struct r8152 *tp, struct ethtool_eee *eee) 3366 + { 3367 + u32 ocp_data, lp, adv, supported = 0; 3368 + u16 val; 3369 + 3370 + val = ocp_reg_read(tp, OCP_EEE_ABLE); 3371 + supported = mmd_eee_cap_to_ethtool_sup_t(val); 3372 + 3373 + val = ocp_reg_read(tp, OCP_EEE_ADV); 3374 + adv = mmd_eee_adv_to_ethtool_adv_t(val); 3375 + 3376 + val = ocp_reg_read(tp, OCP_EEE_LPABLE); 3377 + lp = mmd_eee_adv_to_ethtool_adv_t(val); 3378 + 3379 + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); 3380 + ocp_data &= EEE_RX_EN | EEE_TX_EN; 3381 + 3382 + eee->eee_enabled = !!ocp_data; 3383 + eee->eee_active = !!(supported & adv & lp); 3384 + eee->supported = supported; 3385 + eee->advertised = adv; 3386 + eee->lp_advertised = lp; 3387 + 3388 + return 0; 3389 + } 3390 + 3391 + static int r8153_set_eee(struct r8152 *tp, struct ethtool_eee *eee) 3392 + { 3393 + u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); 3394 + 3395 + r8153_eee_en(tp, eee->eee_enabled); 3396 + 3397 + if (!eee->eee_enabled) 3398 + val = 0; 3399 + 3400 + ocp_reg_write(tp, OCP_EEE_ADV, val); 3401 + 3402 + return 0; 3403 + } 3404 + 3405 + static int 3406 + rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *edata) 3407 + { 3408 + struct r8152 *tp = netdev_priv(net); 3409 + int ret; 3410 + 3411 + ret = usb_autopm_get_interface(tp->intf); 3412 + if (ret < 0) 3413 + goto out; 3414 + 3415 + ret = tp->rtl_ops.eee_get(tp, edata); 3416 + 3417 + usb_autopm_put_interface(tp->intf); 3418 + 3419 + out: 3420 + return ret; 3421 + } 3422 + 3423 + static int 3424 + rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata) 3425 + { 3426 + struct r8152 *tp = netdev_priv(net); 3427 + int ret; 3428 + 3429 + ret = usb_autopm_get_interface(tp->intf); 3430 + if (ret < 0) 3431 + goto out; 3432 + 3433 + ret = tp->rtl_ops.eee_set(tp, edata); 3434 + 3435 + usb_autopm_put_interface(tp->intf); 3436 + 3437 + out: 3438 + return ret; 3439 + } 3440 + 3373 3441 static struct ethtool_ops ops = { 3374 3442 .get_drvinfo = rtl8152_get_drvinfo, 3375 3443 .get_settings = rtl8152_get_settings, ··· 3498 3334 .get_strings = rtl8152_get_strings, 3499 3335 .get_sset_count = rtl8152_get_sset_count, 3500 3336 .get_ethtool_stats = rtl8152_get_ethtool_stats, 3337 + .get_eee = rtl_ethtool_get_eee, 3338 + .set_eee = rtl_ethtool_set_eee, 3501 3339 }; 3502 3340 3503 3341 static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) ··· 3641 3475 ops->up = rtl8152_up; 3642 3476 ops->down = rtl8152_down; 3643 3477 ops->unload = rtl8152_unload; 3478 + ops->eee_get = r8152_get_eee; 3479 + ops->eee_set = r8152_set_eee; 3644 3480 ret = 0; 3645 3481 break; 3646 3482 case PRODUCT_ID_RTL8153: ··· 3652 3484 ops->up = rtl8153_up; 3653 3485 ops->down = rtl8153_down; 3654 3486 ops->unload = rtl8153_unload; 3487 + ops->eee_get = r8153_get_eee; 3488 + ops->eee_set = r8153_set_eee; 3655 3489 ret = 0; 3656 3490 break; 3657 3491 default: ··· 3670 3500 ops->up = rtl8153_up; 3671 3501 ops->down = rtl8153_down; 3672 3502 ops->unload = rtl8153_unload; 3503 + ops->eee_get = r8153_get_eee; 3504 + ops->eee_set = r8153_set_eee; 3673 3505 ret = 0; 3674 3506 break; 3675 3507 default: