Blame view

drivers/staging/octeon/ethernet-xaui.c 3.95 KB
80ff0fd3a   David Daney   Staging: Add octe...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  /**********************************************************************
   * Author: Cavium Networks
   *
   * Contact: support@caviumnetworks.com
   * This file is part of the OCTEON SDK
   *
   * Copyright (c) 2003-2007 Cavium Networks
   *
   * This file is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License, Version 2, as
   * published by the Free Software Foundation.
   *
   * This file is distributed in the hope that it will be useful, but
   * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
   * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
   * NONINFRINGEMENT.  See the GNU General Public License for more
   * details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this file; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
   * or visit http://www.gnu.org/licenses/.
   *
   * This file may also be available under a different license from Cavium.
   * Contact Cavium Networks for more information
  **********************************************************************/
ec3a2207c   David Daney   staging: octeon-e...
27
  #include <linux/phy.h>
80ff0fd3a   David Daney   Staging: Add octe...
28
29
  #include <linux/kernel.h>
  #include <linux/netdevice.h>
7a2eaf935   Christian Dietrich   staging: octeon: ...
30
  #include <linux/ratelimit.h>
80ff0fd3a   David Daney   Staging: Add octe...
31
32
33
34
35
36
  #include <net/dst.h>
  
  #include <asm/octeon/octeon.h>
  
  #include "ethernet-defines.h"
  #include "octeon-ethernet.h"
80ff0fd3a   David Daney   Staging: Add octe...
37
  #include "ethernet-util.h"
ec3a2207c   David Daney   staging: octeon-e...
38
  #include "ethernet-mdio.h"
80ff0fd3a   David Daney   Staging: Add octe...
39

af866496c   David Daney   MIPS: Octeon: Mov...
40
  #include <asm/octeon/cvmx-helper.h>
80ff0fd3a   David Daney   Staging: Add octe...
41

af866496c   David Daney   MIPS: Octeon: Mov...
42
  #include <asm/octeon/cvmx-gmxx-defs.h>
80ff0fd3a   David Daney   Staging: Add octe...
43

80ff0fd3a   David Daney   Staging: Add octe...
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  static void cvm_oct_xaui_poll(struct net_device *dev)
  {
  	struct octeon_ethernet *priv = netdev_priv(dev);
  	cvmx_helper_link_info_t link_info;
  
  	link_info = cvmx_helper_link_get(priv->port);
  	if (link_info.u64 == priv->link_info)
  		return;
  
  	link_info = cvmx_helper_link_autoconf(priv->port);
  	priv->link_info = link_info.u64;
  
  	/* Tell Linux */
  	if (link_info.s.link_up) {
  
  		if (!netif_carrier_ok(dev))
  			netif_carrier_on(dev);
  		if (priv->queue != -1)
7a2eaf935   Christian Dietrich   staging: octeon: ...
62
63
64
65
66
67
  			printk_ratelimited
  				("%s: %u Mbps %s duplex, port %2d, queue %2d
  ",
  				 dev->name, link_info.s.speed,
  				 (link_info.s.full_duplex) ? "Full" : "Half",
  				 priv->port, priv->queue);
80ff0fd3a   David Daney   Staging: Add octe...
68
  		else
7a2eaf935   Christian Dietrich   staging: octeon: ...
69
70
71
72
73
74
  			printk_ratelimited
  				("%s: %u Mbps %s duplex, port %2d, POW
  ",
  				 dev->name, link_info.s.speed,
  				 (link_info.s.full_duplex) ? "Full" : "Half",
  				 priv->port);
80ff0fd3a   David Daney   Staging: Add octe...
75
76
77
  	} else {
  		if (netif_carrier_ok(dev))
  			netif_carrier_off(dev);
7a2eaf935   Christian Dietrich   staging: octeon: ...
78
79
  		printk_ratelimited("%s: Link down
  ", dev->name);
80ff0fd3a   David Daney   Staging: Add octe...
80
81
  	}
  }
ec3a2207c   David Daney   staging: octeon-e...
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  int cvm_oct_xaui_open(struct net_device *dev)
  {
  	union cvmx_gmxx_prtx_cfg gmx_cfg;
  	struct octeon_ethernet *priv = netdev_priv(dev);
  	int interface = INTERFACE(priv->port);
  	int index = INDEX(priv->port);
  	cvmx_helper_link_info_t link_info;
  	int rv;
  
  	rv = cvm_oct_phy_setup_device(dev);
  	if (rv)
  		return rv;
  
  	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
  	gmx_cfg.s.en = 1;
  	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
  
  	if (octeon_is_simulation())
  		return 0;
  
  	if (priv->phydev) {
  		int r = phy_read_status(priv->phydev);
e2ce06152   Aybuke Ozdemir   Staging: octeon: ...
104

ec3a2207c   David Daney   staging: octeon-e...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  		if (r == 0 && priv->phydev->link == 0)
  			netif_carrier_off(dev);
  		cvm_oct_adjust_link(dev);
  	} else {
  		link_info = cvmx_helper_link_get(priv->port);
  		if (!link_info.s.link_up)
  			netif_carrier_off(dev);
  		priv->poll = cvm_oct_xaui_poll;
  		cvm_oct_xaui_poll(dev);
  	}
  	return 0;
  }
  
  int cvm_oct_xaui_stop(struct net_device *dev)
  {
  	union cvmx_gmxx_prtx_cfg gmx_cfg;
  	struct octeon_ethernet *priv = netdev_priv(dev);
  	int interface = INTERFACE(priv->port);
  	int index = INDEX(priv->port);
  
  	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
  	gmx_cfg.s.en = 0;
  	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
  	return cvm_oct_common_stop(dev);
  }
80ff0fd3a   David Daney   Staging: Add octe...
130
131
132
  int cvm_oct_xaui_init(struct net_device *dev)
  {
  	struct octeon_ethernet *priv = netdev_priv(dev);
38064eb1a   Rahul Bedarkar   staging: octeon: ...
133

80ff0fd3a   David Daney   Staging: Add octe...
134
  	cvm_oct_common_init(dev);
f696a1083   David Daney   Staging: octeon-e...
135
  	dev->netdev_ops->ndo_stop(dev);
f6ed1b3b3   David Daney   Staging: octeon-e...
136
  	if (!octeon_is_simulation() && priv->phydev == NULL)
80ff0fd3a   David Daney   Staging: Add octe...
137
138
139
140
141
142
143
144
145
  		priv->poll = cvm_oct_xaui_poll;
  
  	return 0;
  }
  
  void cvm_oct_xaui_uninit(struct net_device *dev)
  {
  	cvm_oct_common_uninit(dev);
  }