diff options
Diffstat (limited to 'drivers/staging/octeon/ethernet-sgmii.c')
-rw-r--r-- | drivers/staging/octeon/ethernet-sgmii.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c new file mode 100644 index 00000000000..58fa39c1d67 --- /dev/null +++ b/drivers/staging/octeon/ethernet-sgmii.c | |||
@@ -0,0 +1,129 @@ | |||
1 | /********************************************************************** | ||
2 | * Author: Cavium Networks | ||
3 | * | ||
4 | * Contact: support@caviumnetworks.com | ||
5 | * This file is part of the OCTEON SDK | ||
6 | * | ||
7 | * Copyright (c) 2003-2007 Cavium Networks | ||
8 | * | ||
9 | * This file is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License, Version 2, as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This file is distributed in the hope that it will be useful, but | ||
14 | * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty | ||
15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or | ||
16 | * NONINFRINGEMENT. See the GNU General Public License for more | ||
17 | * details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this file; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
22 | * or visit http://www.gnu.org/licenses/. | ||
23 | * | ||
24 | * This file may also be available under a different license from Cavium. | ||
25 | * Contact Cavium Networks for more information | ||
26 | **********************************************************************/ | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/netdevice.h> | ||
29 | #include <linux/mii.h> | ||
30 | #include <net/dst.h> | ||
31 | |||
32 | #include <asm/octeon/octeon.h> | ||
33 | |||
34 | #include "ethernet-defines.h" | ||
35 | #include "octeon-ethernet.h" | ||
36 | #include "ethernet-util.h" | ||
37 | #include "ethernet-common.h" | ||
38 | |||
39 | #include "cvmx-helper.h" | ||
40 | |||
41 | #include "cvmx-gmxx-defs.h" | ||
42 | |||
43 | static int cvm_oct_sgmii_open(struct net_device *dev) | ||
44 | { | ||
45 | union cvmx_gmxx_prtx_cfg gmx_cfg; | ||
46 | struct octeon_ethernet *priv = netdev_priv(dev); | ||
47 | int interface = INTERFACE(priv->port); | ||
48 | int index = INDEX(priv->port); | ||
49 | cvmx_helper_link_info_t link_info; | ||
50 | |||
51 | gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); | ||
52 | gmx_cfg.s.en = 1; | ||
53 | cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); | ||
54 | |||
55 | if (!octeon_is_simulation()) { | ||
56 | link_info = cvmx_helper_link_get(priv->port); | ||
57 | if (!link_info.s.link_up) | ||
58 | netif_carrier_off(dev); | ||
59 | } | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static int cvm_oct_sgmii_stop(struct net_device *dev) | ||
65 | { | ||
66 | union cvmx_gmxx_prtx_cfg gmx_cfg; | ||
67 | struct octeon_ethernet *priv = netdev_priv(dev); | ||
68 | int interface = INTERFACE(priv->port); | ||
69 | int index = INDEX(priv->port); | ||
70 | |||
71 | gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); | ||
72 | gmx_cfg.s.en = 0; | ||
73 | cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static void cvm_oct_sgmii_poll(struct net_device *dev) | ||
78 | { | ||
79 | struct octeon_ethernet *priv = netdev_priv(dev); | ||
80 | cvmx_helper_link_info_t link_info; | ||
81 | |||
82 | link_info = cvmx_helper_link_get(priv->port); | ||
83 | if (link_info.u64 == priv->link_info) | ||
84 | return; | ||
85 | |||
86 | link_info = cvmx_helper_link_autoconf(priv->port); | ||
87 | priv->link_info = link_info.u64; | ||
88 | |||
89 | /* Tell Linux */ | ||
90 | if (link_info.s.link_up) { | ||
91 | |||
92 | if (!netif_carrier_ok(dev)) | ||
93 | netif_carrier_on(dev); | ||
94 | if (priv->queue != -1) | ||
95 | DEBUGPRINT | ||
96 | ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", | ||
97 | dev->name, link_info.s.speed, | ||
98 | (link_info.s.full_duplex) ? "Full" : "Half", | ||
99 | priv->port, priv->queue); | ||
100 | else | ||
101 | DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n", | ||
102 | dev->name, link_info.s.speed, | ||
103 | (link_info.s.full_duplex) ? "Full" : "Half", | ||
104 | priv->port); | ||
105 | } else { | ||
106 | if (netif_carrier_ok(dev)) | ||
107 | netif_carrier_off(dev); | ||
108 | DEBUGPRINT("%s: Link down\n", dev->name); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | int cvm_oct_sgmii_init(struct net_device *dev) | ||
113 | { | ||
114 | struct octeon_ethernet *priv = netdev_priv(dev); | ||
115 | cvm_oct_common_init(dev); | ||
116 | dev->open = cvm_oct_sgmii_open; | ||
117 | dev->stop = cvm_oct_sgmii_stop; | ||
118 | dev->stop(dev); | ||
119 | if (!octeon_is_simulation()) | ||
120 | priv->poll = cvm_oct_sgmii_poll; | ||
121 | |||
122 | /* FIXME: Need autoneg logic */ | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | void cvm_oct_sgmii_uninit(struct net_device *dev) | ||
127 | { | ||
128 | cvm_oct_common_uninit(dev); | ||
129 | } | ||