Changeset 36847


Ignore:
Timestamp:
2013-06-04T15:25:52+02:00 (3 years ago)
Author:
juhosg
Message:

generic: add port mirroring/monitoring capability to rtl8366rb switch

This patch adds swlib attributes to the RTL8366RB switch/PHY found in the
TL-WR1043ND router that allow to mirror ethernet packets to a monitor port.

Signed-off-by: Colin Leitner <colin.leitner@…>
Signed-off-by: Gabor Juhos <juhosg@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/generic/files/drivers/net/phy/rtl8366rb.c

    r35328 r36847  
    55 * Copyright (C) 2010 Antti SeppÀlÀ <a.seppala@gmail.com> 
    66 * Copyright (C) 2010 Roman Yeryomin <roman@advem.lv> 
     7 * Copyright (C) 2011 Colin Leitner <colin.leitner@googlemail.com> 
    78 * 
    89 * This program is free software; you can redistribute it and/or modify it 
     
    2425 
    2526#define RTL8366RB_DRIVER_DESC   "Realtek RTL8366RB ethernet switch driver" 
    26 #define RTL8366RB_DRIVER_VER    "0.2.3" 
     27#define RTL8366RB_DRIVER_VER    "0.2.4" 
    2728 
    2829#define RTL8366RB_PHY_NO_MAX    4 
     
    4445/* Port Enable Control register */ 
    4546#define RTL8366RB_PECR                          0x0001 
     47 
     48/* Port Mirror Control Register */ 
     49#define RTL8366RB_PMCR                          0x0007 
     50#define RTL8366RB_PMCR_SOURCE_PORT(_x)          (_x) 
     51#define RTL8366RB_PMCR_SOURCE_PORT_MASK         0x000f 
     52#define RTL8366RB_PMCR_MONITOR_PORT(_x)         ((_x) << 4) 
     53#define RTL8366RB_PMCR_MONITOR_PORT_MASK        0x00f0 
     54#define RTL8366RB_PMCR_MIRROR_RX                BIT(8) 
     55#define RTL8366RB_PMCR_MIRROR_TX                BIT(9) 
     56#define RTL8366RB_PMCR_MIRROR_SPC               BIT(10) 
     57#define RTL8366RB_PMCR_MIRROR_ISO               BIT(11) 
    4658 
    4759/* Switch Security Control registers */ 
     
    923935} 
    924936 
     937static int rtl8366rb_sw_set_mirror_rx_enable(struct switch_dev *dev, 
     938                                    const struct switch_attr *attr, 
     939                                    struct switch_val *val) 
     940{ 
     941        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     942        u32 data; 
     943 
     944        if (val->value.i) 
     945                data = RTL8366RB_PMCR_MIRROR_RX; 
     946        else 
     947                data = 0; 
     948 
     949        return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MIRROR_RX, data); 
     950} 
     951 
     952static int rtl8366rb_sw_get_mirror_rx_enable(struct switch_dev *dev, 
     953                                    const struct switch_attr *attr, 
     954                                    struct switch_val *val) 
     955{ 
     956        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     957        u32 data; 
     958 
     959        rtl8366_smi_read_reg(smi, RTL8366RB_PMCR, &data); 
     960        if (data & RTL8366RB_PMCR_MIRROR_RX) 
     961                val->value.i = 1; 
     962        else 
     963                val->value.i = 0; 
     964 
     965        return 0; 
     966} 
     967 
     968static int rtl8366rb_sw_set_mirror_tx_enable(struct switch_dev *dev, 
     969                                    const struct switch_attr *attr, 
     970                                    struct switch_val *val) 
     971{ 
     972        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     973        u32 data; 
     974 
     975        if (val->value.i) 
     976                data = RTL8366RB_PMCR_MIRROR_TX; 
     977        else 
     978                data = 0; 
     979 
     980        return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MIRROR_TX, data); 
     981} 
     982 
     983static int rtl8366rb_sw_get_mirror_tx_enable(struct switch_dev *dev, 
     984                                    const struct switch_attr *attr, 
     985                                    struct switch_val *val) 
     986{ 
     987        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     988        u32 data; 
     989 
     990        rtl8366_smi_read_reg(smi, RTL8366RB_PMCR, &data); 
     991        if (data & RTL8366RB_PMCR_MIRROR_TX) 
     992                val->value.i = 1; 
     993        else 
     994                val->value.i = 0; 
     995 
     996        return 0; 
     997} 
     998 
     999static int rtl8366rb_sw_set_monitor_isolation_enable(struct switch_dev *dev, 
     1000                                    const struct switch_attr *attr, 
     1001                                    struct switch_val *val) 
     1002{ 
     1003        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     1004        u32 data; 
     1005 
     1006        if (val->value.i) 
     1007                data = RTL8366RB_PMCR_MIRROR_ISO; 
     1008        else 
     1009                data = 0; 
     1010 
     1011        return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MIRROR_ISO, data); 
     1012} 
     1013 
     1014static int rtl8366rb_sw_get_monitor_isolation_enable(struct switch_dev *dev, 
     1015                                    const struct switch_attr *attr, 
     1016                                    struct switch_val *val) 
     1017{ 
     1018        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     1019        u32 data; 
     1020 
     1021        rtl8366_smi_read_reg(smi, RTL8366RB_PMCR, &data); 
     1022        if (data & RTL8366RB_PMCR_MIRROR_ISO) 
     1023                val->value.i = 1; 
     1024        else 
     1025                val->value.i = 0; 
     1026 
     1027        return 0; 
     1028} 
     1029 
     1030static int rtl8366rb_sw_set_mirror_pause_frames_enable(struct switch_dev *dev, 
     1031                                    const struct switch_attr *attr, 
     1032                                    struct switch_val *val) 
     1033{ 
     1034        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     1035        u32 data; 
     1036 
     1037        if (val->value.i) 
     1038                data = RTL8366RB_PMCR_MIRROR_SPC; 
     1039        else 
     1040                data = 0; 
     1041 
     1042        return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MIRROR_SPC, data); 
     1043} 
     1044 
     1045static int rtl8366rb_sw_get_mirror_pause_frames_enable(struct switch_dev *dev, 
     1046                                    const struct switch_attr *attr, 
     1047                                    struct switch_val *val) 
     1048{ 
     1049        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     1050        u32 data; 
     1051 
     1052        rtl8366_smi_read_reg(smi, RTL8366RB_PMCR, &data); 
     1053        if (data & RTL8366RB_PMCR_MIRROR_SPC) 
     1054                val->value.i = 1; 
     1055        else 
     1056                val->value.i = 0; 
     1057 
     1058        return 0; 
     1059} 
     1060 
     1061static int rtl8366rb_sw_set_mirror_monitor_port(struct switch_dev *dev, 
     1062                                    const struct switch_attr *attr, 
     1063                                    struct switch_val *val) 
     1064{ 
     1065        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     1066        u32 data; 
     1067 
     1068        data = RTL8366RB_PMCR_MONITOR_PORT(val->value.i); 
     1069 
     1070        return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MONITOR_PORT_MASK, data); 
     1071} 
     1072 
     1073static int rtl8366rb_sw_get_mirror_monitor_port(struct switch_dev *dev, 
     1074                                    const struct switch_attr *attr, 
     1075                                    struct switch_val *val) 
     1076{ 
     1077        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     1078        u32 data; 
     1079 
     1080        rtl8366_smi_read_reg(smi, RTL8366RB_PMCR, &data); 
     1081        val->value.i = (data & RTL8366RB_PMCR_MONITOR_PORT_MASK) >> 4; 
     1082 
     1083        return 0; 
     1084} 
     1085 
     1086static int rtl8366rb_sw_set_mirror_source_port(struct switch_dev *dev, 
     1087                                    const struct switch_attr *attr, 
     1088                                    struct switch_val *val) 
     1089{ 
     1090        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     1091        u32 data; 
     1092 
     1093        data = RTL8366RB_PMCR_SOURCE_PORT(val->value.i); 
     1094 
     1095        return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_SOURCE_PORT_MASK, data); 
     1096} 
     1097 
     1098static int rtl8366rb_sw_get_mirror_source_port(struct switch_dev *dev, 
     1099                                    const struct switch_attr *attr, 
     1100                                    struct switch_val *val) 
     1101{ 
     1102        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); 
     1103        u32 data; 
     1104 
     1105        rtl8366_smi_read_reg(smi, RTL8366RB_PMCR, &data); 
     1106        val->value.i = data & RTL8366RB_PMCR_SOURCE_PORT_MASK; 
     1107 
     1108        return 0; 
     1109} 
     1110 
    9251111static int rtl8366rb_sw_reset_port_mibs(struct switch_dev *dev, 
    9261112                                       const struct switch_attr *attr, 
     
    9801166                .get = rtl8366rb_sw_get_qos_enable, 
    9811167                .max = 1 
     1168        }, { 
     1169                .type = SWITCH_TYPE_INT, 
     1170                .name = "enable_mirror_rx", 
     1171                .description = "Enable mirroring of RX packets", 
     1172                .set = rtl8366rb_sw_set_mirror_rx_enable, 
     1173                .get = rtl8366rb_sw_get_mirror_rx_enable, 
     1174                .max = 1 
     1175        }, { 
     1176                .type = SWITCH_TYPE_INT, 
     1177                .name = "enable_mirror_tx", 
     1178                .description = "Enable mirroring of TX packets", 
     1179                .set = rtl8366rb_sw_set_mirror_tx_enable, 
     1180                .get = rtl8366rb_sw_get_mirror_tx_enable, 
     1181                .max = 1 
     1182        }, { 
     1183                .type = SWITCH_TYPE_INT, 
     1184                .name = "enable_monitor_isolation", 
     1185                .description = "Enable isolation of monitor port (TX packets will be dropped)", 
     1186                .set = rtl8366rb_sw_set_monitor_isolation_enable, 
     1187                .get = rtl8366rb_sw_get_monitor_isolation_enable, 
     1188                .max = 1 
     1189        }, { 
     1190                .type = SWITCH_TYPE_INT, 
     1191                .name = "enable_mirror_pause_frames", 
     1192                .description = "Enable mirroring of RX pause frames", 
     1193                .set = rtl8366rb_sw_set_mirror_pause_frames_enable, 
     1194                .get = rtl8366rb_sw_get_mirror_pause_frames_enable, 
     1195                .max = 1 
     1196        }, { 
     1197                .type = SWITCH_TYPE_INT, 
     1198                .name = "mirror_monitor_port", 
     1199                .description = "Mirror monitor port", 
     1200                .set = rtl8366rb_sw_set_mirror_monitor_port, 
     1201                .get = rtl8366rb_sw_get_mirror_monitor_port, 
     1202                .max = 5 
     1203        }, { 
     1204                .type = SWITCH_TYPE_INT, 
     1205                .name = "mirror_source_port", 
     1206                .description = "Mirror source port", 
     1207                .set = rtl8366rb_sw_set_mirror_source_port, 
     1208                .get = rtl8366rb_sw_get_mirror_source_port, 
     1209                .max = 5 
    9821210        }, 
    9831211}; 
     
    12641492MODULE_AUTHOR("Antti SeppÀlÀ <a.seppala@gmail.com>"); 
    12651493MODULE_AUTHOR("Roman Yeryomin <roman@advem.lv>"); 
     1494MODULE_AUTHOR("Colin Leitner <colin.leitner@googlemail.com>"); 
    12661495MODULE_LICENSE("GPL v2"); 
    12671496MODULE_ALIAS("platform:" RTL8366RB_DRIVER_NAME); 
Note: See TracChangeset for help on using the changeset viewer.