Ticket #7977: rtl8366rb.2.patch

File rtl8366rb.2.patch, 7.4 KB (added by lultimouomo@…, 6 years ago)

Implement advanced controls for rtl8366rb

  • drivers/net/phy/rtl8366rb.c

    a b  
    11/* 
    2  * Platform driver for the Realtek RTL8366S ethernet switch 
     2 * Platform driver for the Realtek RTL8366RB ethernet switch 
    33 * 
    44 * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org> 
    55 * Copyright (C) 2010 Antti SeppÀlÀ <a.seppala@gmail.com> 
     6 * Copyright (C) 2010 Luca Niccoli <lultimouomo@gmai.com> 
    67 * 
    78 * This program is free software; you can redistribute it and/or modify it 
    89 * under the terms of the GNU General Public License version 2 as published 
     
    117118#define RTL8366RB_PORT_STATUS_RXPAUSE_MASK      0x0040 
    118119#define RTL8366RB_PORT_STATUS_AN_MASK           0x0080 
    119120 
     121/* Port bandwidth control registers and Inter Frame Gap registers */ 
     122#define RTL8366RB_IN_BANDWIDTH_BASE             0x0200 
     123#define RTL8366RB_IN_BANDWIDTH_REG(_p)          (RTL8366RB_IN_BANDWIDTH_BASE+_p) 
     124#define RTL8366RB_IN_BANDWIDTH_MASK             0x3fff 
     125#define RTL8366RB_IN_PREIFG_BASE                0x0200 
     126#define RTL8366RB_IN_PREIFG_OFFSET              14 
     127#define RTL8366RB_IN_PREIFG_MASK                (0x1 << RTL8366RB_IN_PREIFG_OFFSET) 
     128#define RTL8366RB_EG_BANDWIDTH_BASE             0x02D1 
     129#define RTL8366RB_EG_BANDWIDTH_REG(_p)          (RTL8366RB_EG_BANDWIDTH_BASE+_p) 
     130#define RTL8366RB_EG_BANDWIDTH_MASK             0x3fff 
     131#define RTL8366RB_EG_PREIFG_BASE                0x02F8 
     132#define RTL8366RB_EG_PREIFG_OFFSET              9 
     133#define RTL8366RB_EG_PREIFG_MASK                (0x1 << RTL8366RB_EG_PREIFG_OFFSET) 
     134 
     135 
     136/* Port-based priority register */ 
     137#define RTL8366RB_PORT_PRIORITY_BASE            0x020C 
     138#define RTL8366RB_PORT_PRIORITY_BITS            3 
     139#define RTL8366RB_PORT_PRIORITY_MASK            0x7 
     140 
    120141 
    121142#define RTL8366RB_PORT_NUM_CPU          5 
    122143#define RTL8366RB_NUM_PORTS             6 
     
    650671        return 0; 
    651672} 
    652673 
     674static int rtl8366rb_sw_get_max_length(struct switch_dev *dev, 
     675                                     const struct switch_attr *attr, 
     676                                     struct switch_val *val) 
     677{ 
     678        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     679        u32 data; 
     680 
     681        rtl8366_smi_read_reg(smi, RTL8366RB_SGCR, &data); 
     682 
     683        val->value.i = ((data & (RTL8366RB_SGCR_MAX_LENGTH_MASK)) >> 4); 
     684 
     685        return 0; 
     686} 
     687 
     688static int rtl8366rb_sw_set_max_length(struct switch_dev *dev, 
     689                                    const struct switch_attr *attr, 
     690                                    struct switch_val *val) 
     691{ 
     692        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     693        char length_code; 
     694  
     695        switch (val->value.i) { 
     696                case 0: 
     697                        length_code = RTL8366RB_SGCR_MAX_LENGTH_1522; 
     698                        break; 
     699                case 1: 
     700                        length_code = RTL8366RB_SGCR_MAX_LENGTH_1536; 
     701                        break; 
     702                case 2: 
     703                        length_code = RTL8366RB_SGCR_MAX_LENGTH_1552; 
     704                        break; 
     705                case 3: 
     706                        length_code = RTL8366RB_SGCR_MAX_LENGTH_9216; 
     707                        break; 
     708                default: 
     709                        return -EINVAL; 
     710        } 
     711        return rtl8366_smi_rmwr(smi, RTL8366RB_SGCR, 
     712                                RTL8366RB_SGCR_MAX_LENGTH_MASK, 
     713                                length_code); 
     714} 
     715 
    653716 
    654717static const char *rtl8366rb_speed_str(unsigned speed) 
    655718{ 
     
    748811        return 0; 
    749812} 
    750813 
     814static int rtl8366rb_sw_set_port_ib(struct switch_dev *dev, 
     815                                    const struct switch_attr *attr, 
     816                                    struct switch_val *val) 
     817{ 
     818        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     819        u32 data; 
     820 
     821        if (val->port_vlan >= RTL8366RB_NUM_PORTS || val->value.i > attr->max) 
     822                return -EINVAL; 
     823 
     824        if (val->value.i == 0) 
     825                data = 0x3FFF; 
     826        else 
     827                data = ( val->value.i - 1); 
     828 
     829        return rtl8366_smi_rmwr(smi, RTL8366RB_IN_BANDWIDTH_REG(val->port_vlan), 
     830                                RTL8366RB_IN_BANDWIDTH_MASK, data); 
     831} 
     832 
     833static int rtl8366rb_sw_get_port_ib(struct switch_dev *dev, 
     834                                    const struct switch_attr *attr, 
     835                                    struct switch_val *val) 
     836{ 
     837        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     838        u32 data = 0; 
     839         
     840        if (val->port_vlan >= RTL8366RB_NUM_PORTS) 
     841                return -EINVAL; 
     842 
     843        rtl8366_smi_read_reg(smi, RTL8366RB_IN_BANDWIDTH_REG(val->port_vlan), &data); 
     844        data = data & RTL8366RB_IN_BANDWIDTH_MASK; 
     845        if (data == 0x3FFF) 
     846                data = 0; 
     847        val->value.i = data + 1; 
     848 
     849        return 0; 
     850} 
     851 
     852static int rtl8366rb_sw_set_port_eb(struct switch_dev *dev, 
     853                                    const struct switch_attr *attr, 
     854                                    struct switch_val *val) 
     855{ 
     856        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     857        u32 data; 
     858 
     859        if (val->port_vlan >= RTL8366RB_NUM_PORTS || val->value.i > attr->max) 
     860                return -EINVAL; 
     861 
     862        if (val->value.i == 0) 
     863                data = 0x3FFF; 
     864        else 
     865                data = ( val->value.i - 1); 
     866 
     867        return rtl8366_smi_rmwr(smi, RTL8366RB_EG_BANDWIDTH_REG(val->port_vlan), 
     868                                RTL8366RB_EG_BANDWIDTH_MASK, data); 
     869} 
     870 
     871static int rtl8366rb_sw_get_port_eb(struct switch_dev *dev, 
     872                                    const struct switch_attr *attr, 
     873                                    struct switch_val *val) 
     874{ 
     875        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     876        u32 data = 0; 
     877         
     878        if (val->port_vlan >= RTL8366RB_NUM_PORTS) 
     879                return -EINVAL; 
     880 
     881        rtl8366_smi_read_reg(smi, RTL8366RB_EG_BANDWIDTH_REG(val->port_vlan), &data); 
     882        data = data & RTL8366RB_EG_BANDWIDTH_MASK; 
     883        if (data == 0x3FFF) 
     884                data = 0; 
     885        val->value.i = data + 1; 
     886 
     887        return 0; 
     888} 
     889 
     890static int rtl8366rb_sw_set_port_pri(struct switch_dev *dev, 
     891                                    const struct switch_attr *attr, 
     892                                    struct switch_val *val) 
     893{ 
     894        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     895        u32 mask; 
     896        u32 reg; 
     897        u32 data; 
     898 
     899        if (val->port_vlan >= RTL8366RB_NUM_PORTS || val->value.i > attr->max) 
     900                return -EINVAL; 
     901 
     902        if (val->port_vlan < 5) { 
     903                mask = RTL8366RB_PORT_PRIORITY_MASK << 
     904                                (RTL8366RB_PORT_PRIORITY_BITS * val->port_vlan); 
     905                reg = RTL8366RB_PORT_PRIORITY_BASE; 
     906                data = val->value.i << 
     907                                (RTL8366RB_PORT_PRIORITY_BITS * val->port_vlan); 
     908        } else { 
     909                mask = RTL8366RB_PORT_PRIORITY_MASK; 
     910                reg = RTL8366RB_PORT_PRIORITY_BASE + 1; 
     911                data = val->value.i; 
     912        } 
     913 
     914        return rtl8366_smi_rmwr(smi, reg, mask, data); 
     915} 
     916 
     917static int rtl8366rb_sw_get_port_pri(struct switch_dev *dev, 
     918                                    const struct switch_attr *attr, 
     919                                    struct switch_val *val) 
     920{ 
     921        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     922        u32 reg; 
     923        u32 shift; 
     924        u32 data = 0; 
     925 
     926        if (val->port_vlan >= RTL8366RB_NUM_PORTS) 
     927                return -EINVAL; 
     928 
     929        if (val->port_vlan < 5) { 
     930                reg = RTL8366RB_PORT_PRIORITY_BASE; 
     931                shift = RTL8366RB_PORT_PRIORITY_BITS * val->port_vlan; 
     932 
     933        } else { 
     934                reg = RTL8366RB_PORT_PRIORITY_BASE + 1; 
     935                shift = 0; 
     936        } 
     937 
     938        rtl8366_smi_read_reg(smi, reg, &data); 
     939 
     940        val->value.i = ((data >> shift) & RTL8366RB_PORT_PRIORITY_MASK); 
     941 
     942        return 0; 
     943} 
     944 
    751945static int rtl8366rb_sw_reset_port_mibs(struct switch_dev *dev, 
    752946                                       const struct switch_attr *attr, 
    753947                                       struct switch_val *val) 
     
    8141008                .set = rtl8366rb_sw_set_blinkrate, 
    8151009                .get = rtl8366rb_sw_get_blinkrate, 
    8161010                .max = 5 
     1011        }, { 
     1012                .type = SWITCH_TYPE_INT, 
     1013                .name = "max_length", 
     1014                .description = "Get/Set the maximum length of valid packets" 
     1015                " (0 = 1522, 1 = 1536, 2 = 1552, 3 = 9216)", 
     1016                .set = rtl8366rb_sw_set_max_length, 
     1017                .get = rtl8366rb_sw_get_max_length, 
     1018                .max = 3, 
    8171019        }, 
    8181020}; 
    8191021 
     
    8441046                .max = 15, 
    8451047                .set = rtl8366rb_sw_set_port_led, 
    8461048                .get = rtl8366rb_sw_get_port_led, 
     1049        }, { 
     1050                .type = SWITCH_TYPE_INT, 
     1051                .name = "bandwidth_in", 
     1052                .description = "Get/Set port ingress bandwidth " 
     1053                "(bandwidth = n*64Kbps, 0 = disable bandwitdh control)", 
     1054                .set = rtl8366rb_sw_set_port_ib, 
     1055                .get = rtl8366rb_sw_get_port_ib, 
     1056                .max = 16383 
     1057        }, { 
     1058                .type = SWITCH_TYPE_INT, 
     1059                .name = "bandwidth_eg", 
     1060                .description = "Get/Set port egress bandwidth " 
     1061                "(bandwidth = n*64Kbps, 0 = disable bandwitdh control)", 
     1062                .set = rtl8366rb_sw_set_port_eb, 
     1063                .get = rtl8366rb_sw_get_port_eb, 
     1064                .max = 16383 
     1065        }, { 
     1066                .type = SWITCH_TYPE_INT, 
     1067                .name = "priority", 
     1068                .description = "Get/Set port priority (0-7)", 
     1069                .set = rtl8366rb_sw_set_port_pri, 
     1070                .get = rtl8366rb_sw_get_port_pri, 
     1071                .max = 7 
    8471072        }, 
     1073 
     1074 
    8481075}; 
    8491076 
    8501077static struct switch_attr rtl8366rb_vlan[] = {