191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek/* 291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * net/dsa/mv88e6123_61_65.c - Marvell 88e6123/6161/6165 switch chip support 3e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * Copyright (c) 2008-2009 Marvell Semiconductor 491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * 591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * This program is free software; you can redistribute it and/or modify 691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * it under the terms of the GNU General Public License as published by 791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * the Free Software Foundation; either version 2 of the License, or 891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * (at your option) any later version. 991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 1091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 1191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek#include <linux/list.h> 122bbba277a554431a426e81f37d5c50ab6216c07dPaul Gortmaker#include <linux/module.h> 1391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek#include <linux/netdevice.h> 1491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek#include <linux/phy.h> 15c8f0b86996c88081095124d16b869e8d8a1c02c5Ben Hutchings#include <net/dsa.h> 1691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek#include "mv88e6xxx.h" 1791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 1891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekstatic char *mv88e6123_61_65_probe(struct mii_bus *bus, int sw_addr) 1991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek{ 2091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek int ret; 2191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 2291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03); 2391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek if (ret >= 0) { 24edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy if (ret == 0x1212) 25edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy return "Marvell 88E6123 (A1)"; 26edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy if (ret == 0x1213) 27edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy return "Marvell 88E6123 (A2)"; 28edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy if ((ret & 0xfff0) == 0x1210) 2991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return "Marvell 88E6123"; 30edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy 31edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy if (ret == 0x1612) 32edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy return "Marvell 88E6161 (A1)"; 33edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy if (ret == 0x1613) 34edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy return "Marvell 88E6161 (A2)"; 35edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy if ((ret & 0xfff0) == 0x1610) 3691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return "Marvell 88E6161"; 37edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy 38edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy if (ret == 0x1652) 39edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy return "Marvell 88E6165 (A1)"; 40edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy if (ret == 0x1653) 41edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy return "Marvell 88e6165 (A2)"; 42edd664bbba53f771d4a6d4559ed6e1ff48b46406Chris Healy if ((ret & 0xfff0) == 0x1650) 4391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return "Marvell 88E6165"; 4491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek } 4591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 4691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return NULL; 4791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek} 4891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 4991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekstatic int mv88e6123_61_65_switch_reset(struct dsa_switch *ds) 5091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek{ 5191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek int i; 5291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek int ret; 5391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 5491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 5591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Set all ports to the disabled state. 5691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 5791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek for (i = 0; i < 8; i++) { 5891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek ret = REG_READ(REG_PORT(i), 0x04); 5991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc); 6091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek } 6191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 6291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 6391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Wait for transmit queues to drain. 6491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 6591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek msleep(2); 6691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 6791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 6891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Reset the switch. 6991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 7091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(REG_GLOBAL, 0x04, 0xc400); 7191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 7291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 7391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Wait up to one second for reset to complete. 7491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 7591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek for (i = 0; i < 1000; i++) { 7691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek ret = REG_READ(REG_GLOBAL, 0x00); 7791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek if ((ret & 0xc800) == 0xc800) 7891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek break; 7991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 8091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek msleep(1); 8191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek } 8291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek if (i == 1000) 8391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return -ETIMEDOUT; 8491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 8591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return 0; 8691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek} 8791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 8891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekstatic int mv88e6123_61_65_setup_global(struct dsa_switch *ds) 8991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek{ 9091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek int ret; 9191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek int i; 9291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 9391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 9491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Disable the PHY polling unit (since there won't be any 9591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * external PHYs to poll), don't discard packets with 9691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * excessive collisions, and mask all interrupt sources. 9791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 9891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(REG_GLOBAL, 0x04, 0x0000); 9991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 10091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 10191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Set the default address aging time to 5 minutes, and 10291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * enable address learn messages to be sent to all message 10391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * ports. 10491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 10591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(REG_GLOBAL, 0x0a, 0x0148); 10691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 10791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 10891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Configure the priority mapping registers. 10991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 11091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek ret = mv88e6xxx_config_prio(ds); 11191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek if (ret < 0) 11291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return ret; 11391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 11491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 115e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * Configure the upstream port, and configure the upstream 116e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * port as the port to which ingress and egress monitor frames 117e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * are to be sent. 11891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 119e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek REG_WRITE(REG_GLOBAL, 0x1a, (dsa_upstream_port(ds) * 0x1110)); 12091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 12191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 12291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Disable remote management for now, and set the switch's 123e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * DSA device number. 12491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 125e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek REG_WRITE(REG_GLOBAL, 0x1c, ds->index & 0x1f); 12691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 12791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 12891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Send all frames with destination addresses matching 12991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * 01:80:c2:00:00:2x to the CPU port. 13091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 13191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(REG_GLOBAL2, 0x02, 0xffff); 13291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 13391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 13491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Send all frames with destination addresses matching 13591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * 01:80:c2:00:00:0x to the CPU port. 13691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 13791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(REG_GLOBAL2, 0x03, 0xffff); 13891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 13991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 14091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Disable the loopback filter, disable flow control 14191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * messages, disable flood broadcast override, disable 14291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * removing of provider tags, disable ATU age violation 14391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * interrupts, disable tag flow control, force flow 14491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * control priority to the highest, and send all special 14591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * multicast frames to the CPU at the highest priority. 14691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 14791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff); 14891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 14991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 150e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * Program the DSA routing table. 15191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 152e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek for (i = 0; i < 32; i++) { 153e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek int nexthop; 154e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek 155e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek nexthop = 0x1f; 156e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek if (i != ds->index && i < ds->dst->pd->nr_chips) 157e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek nexthop = ds->pd->rtable[i] & 0x1f; 158e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek 159e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | nexthop); 160e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek } 16191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 16291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 16391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Clear all trunk masks. 16491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 16591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek for (i = 0; i < 8; i++) 16691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(REG_GLOBAL2, 0x07, 0x8000 | (i << 12) | 0xff); 16791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 16891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 16991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Clear all trunk mappings. 17091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 17191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek for (i = 0; i < 16; i++) 17291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(REG_GLOBAL2, 0x08, 0x8000 | (i << 11)); 17391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 17491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 17591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Disable ingress rate limiting by resetting all ingress 17691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * rate limit registers to their initial state. 17791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 17891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek for (i = 0; i < 6; i++) 17991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(REG_GLOBAL2, 0x09, 0x9000 | (i << 8)); 18091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 18191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 18291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Initialise cross-chip port VLAN table to reset defaults. 18391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 18491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(REG_GLOBAL2, 0x0b, 0x9000); 18591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 18691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 18791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Clear the priority override table. 18891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 18991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek for (i = 0; i < 16; i++) 19091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(REG_GLOBAL2, 0x0f, 0x8000 | (i << 8)); 19191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 19291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* @@@ initialise AVB (22/23) watchdog (27) sdet (29) registers */ 19391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 19491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return 0; 19591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek} 19691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 19791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekstatic int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p) 19891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek{ 19991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek int addr = REG_PORT(p); 200e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek u16 val; 20191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 20291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 20391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * MAC Forcing register: don't force link, speed, duplex 204e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * or flow control state to any particular values on physical 205e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * ports, but force the CPU port and all DSA ports to 1000 Mb/s 206e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * full duplex. 20791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 208e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p)) 209e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek REG_WRITE(addr, 0x01, 0x003e); 210e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek else 211e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek REG_WRITE(addr, 0x01, 0x0003); 21291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 21391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 21491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Do not limit the period of time that this port can be 21591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * paused for by the remote end or the period of time that 21691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * this port can pause the remote end. 21791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 21891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(addr, 0x02, 0x0000); 21991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 22091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 22191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Port Control: disable Drop-on-Unlock, disable Drop-on-Lock, 222e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * disable Header mode, enable IGMP/MLD snooping, disable VLAN 223e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * tunneling, determine priority by looking at 802.1p and IP 224e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * priority fields (IP prio has precedence), and set STP state 225e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * to Forwarding. 226e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * 227e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * If this is the CPU link, use DSA or EDSA tagging depending 228e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * on which tagging mode was configured. 229e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * 230e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * If this is a link to another switch, use DSA tagging mode. 231e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * 232e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * If this is the upstream port for this switch, enable 233e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * forwarding of unknown unicasts and multicasts. 23491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 235e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek val = 0x0433; 236e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek if (dsa_is_cpu_port(ds, p)) { 237e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek if (ds->dst->tag_protocol == htons(ETH_P_EDSA)) 238e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek val |= 0x3300; 239e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek else 240e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek val |= 0x0100; 241e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek } 242e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek if (ds->dsa_port_mask & (1 << p)) 243e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek val |= 0x0100; 244e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek if (p == dsa_upstream_port(ds)) 245e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek val |= 0x000c; 246e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek REG_WRITE(addr, 0x04, val); 24791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 24891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 24991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Port Control 1: disable trunking. Also, if this is the 25091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * CPU port, enable learn messages to be sent to this port. 25191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 252e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000); 25391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 25491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 25591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Port based VLAN map: give each port its own address 25691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * database, allow the CPU port to talk to each of the 'real' 25791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * ports, and allow each of the 'real' ports to only talk to 258e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek * the upstream port. 25991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 260e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek val = (p & 0xf) << 12; 261e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek if (dsa_is_cpu_port(ds, p)) 262e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek val |= ds->phys_port_mask; 263e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek else 264e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek val |= 1 << dsa_upstream_port(ds); 265e84665c9cb4db963393fafad6fefe5efdd7e4a09Lennert Buytenhek REG_WRITE(addr, 0x06, val); 26691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 26791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 26891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Default VLAN ID and priority: don't set a default VLAN 26991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * ID, and set the default packet priority to zero. 27091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 27191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(addr, 0x07, 0x0000); 27291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 27391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 27491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Port Control 2: don't force a good FCS, set the maximum 27591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * frame size to 10240 bytes, don't let the switch add or 27691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * strip 802.1q tags, don't discard tagged or untagged frames 27791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * on this port, do a destination address lookup on all 27891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * received packets as usual, disable ARP mirroring and don't 27991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * send a copy of all transmitted/received frames on this port 28091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * to the CPU. 28191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 28291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(addr, 0x08, 0x2080); 28391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 28491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 28591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Egress rate control: disable egress rate control. 28691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 28791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(addr, 0x09, 0x0001); 28891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 28991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 29091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Egress rate control 2: disable egress rate control. 29191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 29291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(addr, 0x0a, 0x0000); 29391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 29491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 29591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Port Association Vector: when learning source addresses 29691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * of packets, add the address to the address database using 29791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * a port bitmap that has only the bit for this port set and 29891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * the other bits clear. 29991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 30091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(addr, 0x0b, 1 << p); 30191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 30291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 30391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Port ATU control: disable limiting the number of address 30491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * database entries that this port is allowed to use. 30591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 30691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(addr, 0x0c, 0x0000); 30791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 30891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 30991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Priorit Override: disable DA, SA and VTU priority override. 31091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 31191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(addr, 0x0d, 0x0000); 31291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 31391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 31491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Port Ethertype: use the Ethertype DSA Ethertype value. 31591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 31691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(addr, 0x0f, ETH_P_EDSA); 31791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 31891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 31991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Tag Remap: use an identity 802.1p prio -> switch prio 32091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * mapping. 32191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 32291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(addr, 0x18, 0x3210); 32391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 32491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* 32591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * Tag Remap 2: use an identity 802.1p prio -> switch prio 32691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek * mapping. 32791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek */ 32891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek REG_WRITE(addr, 0x19, 0x7654); 32991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 33091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return 0; 33191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek} 33291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 33391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekstatic int mv88e6123_61_65_setup(struct dsa_switch *ds) 33491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek{ 33591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek struct mv88e6xxx_priv_state *ps = (void *)(ds + 1); 33691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek int i; 33791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek int ret; 33891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 33991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek mutex_init(&ps->smi_mutex); 34091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek mutex_init(&ps->stats_mutex); 34191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 34291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek ret = mv88e6123_61_65_switch_reset(ds); 34391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek if (ret < 0) 34491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return ret; 34591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 34691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek /* @@@ initialise vtu and atu */ 34791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 34891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek ret = mv88e6123_61_65_setup_global(ds); 34991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek if (ret < 0) 35091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return ret; 35191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 35291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek for (i = 0; i < 6; i++) { 35391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek ret = mv88e6123_61_65_setup_port(ds, i); 35491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek if (ret < 0) 35591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return ret; 35691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek } 35791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 35891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return 0; 35991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek} 36091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 36191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekstatic int mv88e6123_61_65_port_to_phy_addr(int port) 36291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek{ 36391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek if (port >= 0 && port <= 4) 36491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return port; 36591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return -1; 36691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek} 36791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 36891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekstatic int 36991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekmv88e6123_61_65_phy_read(struct dsa_switch *ds, int port, int regnum) 37091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek{ 37191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek int addr = mv88e6123_61_65_port_to_phy_addr(port); 37291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return mv88e6xxx_phy_read(ds, addr, regnum); 37391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek} 37491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 37591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekstatic int 37691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekmv88e6123_61_65_phy_write(struct dsa_switch *ds, 37791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek int port, int regnum, u16 val) 37891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek{ 37991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek int addr = mv88e6123_61_65_port_to_phy_addr(port); 38091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return mv88e6xxx_phy_write(ds, addr, regnum, val); 38191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek} 38291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 38391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekstatic struct mv88e6xxx_hw_stat mv88e6123_61_65_hw_stats[] = { 38491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "in_good_octets", 8, 0x00, }, 38591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "in_bad_octets", 4, 0x02, }, 38691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "in_unicast", 4, 0x04, }, 38791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "in_broadcasts", 4, 0x06, }, 38891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "in_multicasts", 4, 0x07, }, 38991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "in_pause", 4, 0x16, }, 39091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "in_undersize", 4, 0x18, }, 39191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "in_fragments", 4, 0x19, }, 39291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "in_oversize", 4, 0x1a, }, 39391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "in_jabber", 4, 0x1b, }, 39491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "in_rx_error", 4, 0x1c, }, 39591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "in_fcs_error", 4, 0x1d, }, 39691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "out_octets", 8, 0x0e, }, 39791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "out_unicast", 4, 0x10, }, 39891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "out_broadcasts", 4, 0x13, }, 39991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "out_multicasts", 4, 0x12, }, 40091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "out_pause", 4, 0x15, }, 40191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "excessive", 4, 0x11, }, 40291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "collisions", 4, 0x1e, }, 40391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "deferred", 4, 0x05, }, 40491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "single", 4, 0x14, }, 40591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "multiple", 4, 0x17, }, 40691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "out_fcs_error", 4, 0x03, }, 40791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "late", 4, 0x1f, }, 40891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "hist_64bytes", 4, 0x08, }, 40991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "hist_65_127bytes", 4, 0x09, }, 41091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "hist_128_255bytes", 4, 0x0a, }, 41191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "hist_256_511bytes", 4, 0x0b, }, 41291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "hist_512_1023bytes", 4, 0x0c, }, 41391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek { "hist_1024_max_bytes", 4, 0x0d, }, 41491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek}; 41591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 41691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekstatic void 41791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekmv88e6123_61_65_get_strings(struct dsa_switch *ds, int port, uint8_t *data) 41891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek{ 41991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6123_61_65_hw_stats), 42091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek mv88e6123_61_65_hw_stats, port, data); 42191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek} 42291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 42391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekstatic void 42491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekmv88e6123_61_65_get_ethtool_stats(struct dsa_switch *ds, 42591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek int port, uint64_t *data) 42691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek{ 42791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek mv88e6xxx_get_ethtool_stats(ds, ARRAY_SIZE(mv88e6123_61_65_hw_stats), 42891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek mv88e6123_61_65_hw_stats, port, data); 42991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek} 43091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 43191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhekstatic int mv88e6123_61_65_get_sset_count(struct dsa_switch *ds) 43291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek{ 43391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek return ARRAY_SIZE(mv88e6123_61_65_hw_stats); 43491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek} 43591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek 43698e673080bd90b9338428be92dd3597798aac3edBen Hutchingsstruct dsa_switch_driver mv88e6123_61_65_switch_driver = { 43709640e6365c679b5642b1c41b6d7078f51689ddfHarvey Harrison .tag_protocol = cpu_to_be16(ETH_P_EDSA), 43891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek .priv_size = sizeof(struct mv88e6xxx_priv_state), 43991da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek .probe = mv88e6123_61_65_probe, 44091da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek .setup = mv88e6123_61_65_setup, 44191da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek .set_addr = mv88e6xxx_set_addr_indirect, 44291da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek .phy_read = mv88e6123_61_65_phy_read, 44391da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek .phy_write = mv88e6123_61_65_phy_write, 44491da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek .poll_link = mv88e6xxx_poll_link, 44591da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek .get_strings = mv88e6123_61_65_get_strings, 44691da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek .get_ethtool_stats = mv88e6123_61_65_get_ethtool_stats, 44791da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek .get_sset_count = mv88e6123_61_65_get_sset_count, 44891da11f870f00a3322b81c73042291d7f0be5a17Lennert Buytenhek}; 4493d825ede8c79a4799a6a3c34719551c7c1908b96Ben Hutchings 4503d825ede8c79a4799a6a3c34719551c7c1908b96Ben HutchingsMODULE_ALIAS("platform:mv88e6123"); 4513d825ede8c79a4799a6a3c34719551c7c1908b96Ben HutchingsMODULE_ALIAS("platform:mv88e6161"); 4523d825ede8c79a4799a6a3c34719551c7c1908b96Ben HutchingsMODULE_ALIAS("platform:mv88e6165"); 453