|
11 | 11 | * (at your option) any later version. |
12 | 12 | */ |
13 | 13 |
|
14 | | -#include <linux/debugfs.h> |
15 | 14 | #include <linux/delay.h> |
16 | 15 | #include <linux/etherdevice.h> |
17 | 16 | #include <linux/ethtool.h> |
|
21 | 20 | #include <linux/module.h> |
22 | 21 | #include <linux/netdevice.h> |
23 | 22 | #include <linux/phy.h> |
24 | | -#include <linux/seq_file.h> |
25 | 23 | #include <net/dsa.h> |
26 | 24 | #include <net/switchdev.h> |
27 | 25 | #include "mv88e6xxx.h" |
@@ -876,13 +874,6 @@ static int _mv88e6xxx_atu_wait(struct dsa_switch *ds) |
876 | 874 | GLOBAL_ATU_OP_BUSY); |
877 | 875 | } |
878 | 876 |
|
879 | | -/* Must be called with SMI lock held */ |
880 | | -static int _mv88e6xxx_scratch_wait(struct dsa_switch *ds) |
881 | | -{ |
882 | | - return _mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_SCRATCH_MISC, |
883 | | - GLOBAL2_SCRATCH_BUSY); |
884 | | -} |
885 | | - |
886 | 877 | /* Must be called with SMI mutex held */ |
887 | 878 | static int _mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, |
888 | 879 | int regnum) |
@@ -2107,298 +2098,16 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds) |
2107 | 2098 | return 0; |
2108 | 2099 | } |
2109 | 2100 |
|
2110 | | -static int mv88e6xxx_regs_show(struct seq_file *s, void *p) |
2111 | | -{ |
2112 | | - struct dsa_switch *ds = s->private; |
2113 | | - |
2114 | | - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2115 | | - int reg, port; |
2116 | | - |
2117 | | - seq_puts(s, " GLOBAL GLOBAL2 "); |
2118 | | - for (port = 0 ; port < ps->num_ports; port++) |
2119 | | - seq_printf(s, " %2d ", port); |
2120 | | - seq_puts(s, "\n"); |
2121 | | - |
2122 | | - for (reg = 0; reg < 32; reg++) { |
2123 | | - seq_printf(s, "%2x: ", reg); |
2124 | | - seq_printf(s, " %4x %4x ", |
2125 | | - mv88e6xxx_reg_read(ds, REG_GLOBAL, reg), |
2126 | | - mv88e6xxx_reg_read(ds, REG_GLOBAL2, reg)); |
2127 | | - |
2128 | | - for (port = 0 ; port < ps->num_ports; port++) |
2129 | | - seq_printf(s, "%4x ", |
2130 | | - mv88e6xxx_reg_read(ds, REG_PORT(port), reg)); |
2131 | | - seq_puts(s, "\n"); |
2132 | | - } |
2133 | | - |
2134 | | - return 0; |
2135 | | -} |
2136 | | - |
2137 | | -static int mv88e6xxx_regs_open(struct inode *inode, struct file *file) |
2138 | | -{ |
2139 | | - return single_open(file, mv88e6xxx_regs_show, inode->i_private); |
2140 | | -} |
2141 | | - |
2142 | | -static const struct file_operations mv88e6xxx_regs_fops = { |
2143 | | - .open = mv88e6xxx_regs_open, |
2144 | | - .read = seq_read, |
2145 | | - .llseek = no_llseek, |
2146 | | - .release = single_release, |
2147 | | - .owner = THIS_MODULE, |
2148 | | -}; |
2149 | | - |
2150 | | -static void mv88e6xxx_atu_show_header(struct seq_file *s) |
2151 | | -{ |
2152 | | - seq_puts(s, "DB T/P Vec State Addr\n"); |
2153 | | -} |
2154 | | - |
2155 | | -static void mv88e6xxx_atu_show_entry(struct seq_file *s, int dbnum, |
2156 | | - unsigned char *addr, int data) |
2157 | | -{ |
2158 | | - bool trunk = !!(data & GLOBAL_ATU_DATA_TRUNK); |
2159 | | - int portvec = ((data & GLOBAL_ATU_DATA_PORT_VECTOR_MASK) >> |
2160 | | - GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT); |
2161 | | - int state = data & GLOBAL_ATU_DATA_STATE_MASK; |
2162 | | - |
2163 | | - seq_printf(s, "%03x %5s %10pb %x %pM\n", |
2164 | | - dbnum, (trunk ? "Trunk" : "Port"), &portvec, state, addr); |
2165 | | -} |
2166 | | - |
2167 | | -static int mv88e6xxx_atu_show_db(struct seq_file *s, struct dsa_switch *ds, |
2168 | | - int dbnum) |
2169 | | -{ |
2170 | | - unsigned char bcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
2171 | | - unsigned char addr[6]; |
2172 | | - int ret, data, state; |
2173 | | - |
2174 | | - ret = _mv88e6xxx_atu_mac_write(ds, bcast); |
2175 | | - if (ret < 0) |
2176 | | - return ret; |
2177 | | - |
2178 | | - do { |
2179 | | - ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_FID, |
2180 | | - dbnum); |
2181 | | - if (ret < 0) |
2182 | | - return ret; |
2183 | | - |
2184 | | - ret = _mv88e6xxx_atu_cmd(ds, GLOBAL_ATU_OP_GET_NEXT_DB); |
2185 | | - if (ret < 0) |
2186 | | - return ret; |
2187 | | - |
2188 | | - data = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_ATU_DATA); |
2189 | | - if (data < 0) |
2190 | | - return data; |
2191 | | - |
2192 | | - state = data & GLOBAL_ATU_DATA_STATE_MASK; |
2193 | | - if (state == GLOBAL_ATU_DATA_STATE_UNUSED) |
2194 | | - break; |
2195 | | - ret = _mv88e6xxx_atu_mac_read(ds, addr); |
2196 | | - if (ret < 0) |
2197 | | - return ret; |
2198 | | - mv88e6xxx_atu_show_entry(s, dbnum, addr, data); |
2199 | | - } while (state != GLOBAL_ATU_DATA_STATE_UNUSED); |
2200 | | - |
2201 | | - return 0; |
2202 | | -} |
2203 | | - |
2204 | | -static int mv88e6xxx_atu_show(struct seq_file *s, void *p) |
2205 | | -{ |
2206 | | - struct dsa_switch *ds = s->private; |
2207 | | - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2208 | | - int dbnum; |
2209 | | - |
2210 | | - mv88e6xxx_atu_show_header(s); |
2211 | | - |
2212 | | - for (dbnum = 0; dbnum < 255; dbnum++) { |
2213 | | - mutex_lock(&ps->smi_mutex); |
2214 | | - mv88e6xxx_atu_show_db(s, ds, dbnum); |
2215 | | - mutex_unlock(&ps->smi_mutex); |
2216 | | - } |
2217 | | - |
2218 | | - return 0; |
2219 | | -} |
2220 | | - |
2221 | | -static int mv88e6xxx_atu_open(struct inode *inode, struct file *file) |
2222 | | -{ |
2223 | | - return single_open(file, mv88e6xxx_atu_show, inode->i_private); |
2224 | | -} |
2225 | | - |
2226 | | -static const struct file_operations mv88e6xxx_atu_fops = { |
2227 | | - .open = mv88e6xxx_atu_open, |
2228 | | - .read = seq_read, |
2229 | | - .llseek = no_llseek, |
2230 | | - .release = single_release, |
2231 | | - .owner = THIS_MODULE, |
2232 | | -}; |
2233 | | - |
2234 | | -static void mv88e6xxx_stats_show_header(struct seq_file *s, |
2235 | | - struct mv88e6xxx_priv_state *ps) |
2236 | | -{ |
2237 | | - int port; |
2238 | | - |
2239 | | - seq_puts(s, " Statistic "); |
2240 | | - for (port = 0 ; port < ps->num_ports; port++) |
2241 | | - seq_printf(s, "Port %2d ", port); |
2242 | | - seq_puts(s, "\n"); |
2243 | | -} |
2244 | | - |
2245 | | -static int mv88e6xxx_stats_show(struct seq_file *s, void *p) |
2246 | | -{ |
2247 | | - struct dsa_switch *ds = s->private; |
2248 | | - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2249 | | - struct mv88e6xxx_hw_stat *stats = mv88e6xxx_hw_stats; |
2250 | | - int port, stat, max_stats; |
2251 | | - uint64_t value; |
2252 | | - |
2253 | | - if (have_sw_in_discards(ds)) |
2254 | | - max_stats = ARRAY_SIZE(mv88e6xxx_hw_stats); |
2255 | | - else |
2256 | | - max_stats = ARRAY_SIZE(mv88e6xxx_hw_stats) - 3; |
2257 | | - |
2258 | | - mv88e6xxx_stats_show_header(s, ps); |
2259 | | - |
2260 | | - mutex_lock(&ps->smi_mutex); |
2261 | | - |
2262 | | - for (stat = 0; stat < max_stats; stat++) { |
2263 | | - seq_printf(s, "%19s: ", stats[stat].string); |
2264 | | - for (port = 0 ; port < ps->num_ports; port++) { |
2265 | | - _mv88e6xxx_stats_snapshot(ds, port); |
2266 | | - value = _mv88e6xxx_get_ethtool_stat(ds, stat, stats, |
2267 | | - port); |
2268 | | - seq_printf(s, "%8llu ", value); |
2269 | | - } |
2270 | | - seq_puts(s, "\n"); |
2271 | | - } |
2272 | | - mutex_unlock(&ps->smi_mutex); |
2273 | | - |
2274 | | - return 0; |
2275 | | -} |
2276 | | - |
2277 | | -static int mv88e6xxx_stats_open(struct inode *inode, struct file *file) |
2278 | | -{ |
2279 | | - return single_open(file, mv88e6xxx_stats_show, inode->i_private); |
2280 | | -} |
2281 | | - |
2282 | | -static const struct file_operations mv88e6xxx_stats_fops = { |
2283 | | - .open = mv88e6xxx_stats_open, |
2284 | | - .read = seq_read, |
2285 | | - .llseek = no_llseek, |
2286 | | - .release = single_release, |
2287 | | - .owner = THIS_MODULE, |
2288 | | -}; |
2289 | | - |
2290 | | -static int mv88e6xxx_device_map_show(struct seq_file *s, void *p) |
2291 | | -{ |
2292 | | - struct dsa_switch *ds = s->private; |
2293 | | - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2294 | | - int target, ret; |
2295 | | - |
2296 | | - seq_puts(s, "Target Port\n"); |
2297 | | - |
2298 | | - mutex_lock(&ps->smi_mutex); |
2299 | | - for (target = 0; target < 32; target++) { |
2300 | | - ret = _mv88e6xxx_reg_write( |
2301 | | - ds, REG_GLOBAL2, GLOBAL2_DEVICE_MAPPING, |
2302 | | - target << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT); |
2303 | | - if (ret < 0) |
2304 | | - goto out; |
2305 | | - ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL2, |
2306 | | - GLOBAL2_DEVICE_MAPPING); |
2307 | | - seq_printf(s, " %2d %2d\n", target, |
2308 | | - ret & GLOBAL2_DEVICE_MAPPING_PORT_MASK); |
2309 | | - } |
2310 | | -out: |
2311 | | - mutex_unlock(&ps->smi_mutex); |
2312 | | - |
2313 | | - return 0; |
2314 | | -} |
2315 | | - |
2316 | | -static int mv88e6xxx_device_map_open(struct inode *inode, struct file *file) |
2317 | | -{ |
2318 | | - return single_open(file, mv88e6xxx_device_map_show, inode->i_private); |
2319 | | -} |
2320 | | - |
2321 | | -static const struct file_operations mv88e6xxx_device_map_fops = { |
2322 | | - .open = mv88e6xxx_device_map_open, |
2323 | | - .read = seq_read, |
2324 | | - .llseek = no_llseek, |
2325 | | - .release = single_release, |
2326 | | - .owner = THIS_MODULE, |
2327 | | -}; |
2328 | | - |
2329 | | -static int mv88e6xxx_scratch_show(struct seq_file *s, void *p) |
2330 | | -{ |
2331 | | - struct dsa_switch *ds = s->private; |
2332 | | - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2333 | | - int reg, ret; |
2334 | | - |
2335 | | - seq_puts(s, "Register Value\n"); |
2336 | | - |
2337 | | - mutex_lock(&ps->smi_mutex); |
2338 | | - for (reg = 0; reg < 0x80; reg++) { |
2339 | | - ret = _mv88e6xxx_reg_write( |
2340 | | - ds, REG_GLOBAL2, GLOBAL2_SCRATCH_MISC, |
2341 | | - reg << GLOBAL2_SCRATCH_REGISTER_SHIFT); |
2342 | | - if (ret < 0) |
2343 | | - goto out; |
2344 | | - |
2345 | | - ret = _mv88e6xxx_scratch_wait(ds); |
2346 | | - if (ret < 0) |
2347 | | - goto out; |
2348 | | - |
2349 | | - ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL2, |
2350 | | - GLOBAL2_SCRATCH_MISC); |
2351 | | - seq_printf(s, " %2x %2x\n", reg, |
2352 | | - ret & GLOBAL2_SCRATCH_VALUE_MASK); |
2353 | | - } |
2354 | | -out: |
2355 | | - mutex_unlock(&ps->smi_mutex); |
2356 | | - |
2357 | | - return 0; |
2358 | | -} |
2359 | | - |
2360 | | -static int mv88e6xxx_scratch_open(struct inode *inode, struct file *file) |
2361 | | -{ |
2362 | | - return single_open(file, mv88e6xxx_scratch_show, inode->i_private); |
2363 | | -} |
2364 | | - |
2365 | | -static const struct file_operations mv88e6xxx_scratch_fops = { |
2366 | | - .open = mv88e6xxx_scratch_open, |
2367 | | - .read = seq_read, |
2368 | | - .llseek = no_llseek, |
2369 | | - .release = single_release, |
2370 | | - .owner = THIS_MODULE, |
2371 | | -}; |
2372 | | - |
2373 | 2101 | int mv88e6xxx_setup_common(struct dsa_switch *ds) |
2374 | 2102 | { |
2375 | 2103 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2376 | | - char *name; |
2377 | 2104 |
|
2378 | 2105 | mutex_init(&ps->smi_mutex); |
2379 | 2106 |
|
2380 | 2107 | ps->id = REG_READ(REG_PORT(0), PORT_SWITCH_ID) & 0xfff0; |
2381 | 2108 |
|
2382 | 2109 | INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); |
2383 | 2110 |
|
2384 | | - name = kasprintf(GFP_KERNEL, "dsa%d", ds->index); |
2385 | | - ps->dbgfs = debugfs_create_dir(name, NULL); |
2386 | | - kfree(name); |
2387 | | - |
2388 | | - debugfs_create_file("regs", S_IRUGO, ps->dbgfs, ds, |
2389 | | - &mv88e6xxx_regs_fops); |
2390 | | - |
2391 | | - debugfs_create_file("atu", S_IRUGO, ps->dbgfs, ds, |
2392 | | - &mv88e6xxx_atu_fops); |
2393 | | - |
2394 | | - debugfs_create_file("stats", S_IRUGO, ps->dbgfs, ds, |
2395 | | - &mv88e6xxx_stats_fops); |
2396 | | - |
2397 | | - debugfs_create_file("device_map", S_IRUGO, ps->dbgfs, ds, |
2398 | | - &mv88e6xxx_device_map_fops); |
2399 | | - |
2400 | | - debugfs_create_file("scratch", S_IRUGO, ps->dbgfs, ds, |
2401 | | - &mv88e6xxx_scratch_fops); |
2402 | 2111 | return 0; |
2403 | 2112 | } |
2404 | 2113 |
|
|
0 commit comments