netxen_nic_niu.c 6.9 KB
Newer Older
A
Amit S. Kale 已提交
1
/*
D
Dhananjay Phadke 已提交
2
 * Copyright (C) 2003 - 2009 NetXen, Inc.
A
Amit S. Kale 已提交
3
 * All rights reserved.
4
 *
A
Amit S. Kale 已提交
5 6 7 8
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
9
 *
A
Amit S. Kale 已提交
10 11 12 13
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
14
 *
A
Amit S. Kale 已提交
15 16 17 18
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA  02111-1307, USA.
19
 *
A
Amit S. Kale 已提交
20 21
 * The full GNU General Public License is included in this distribution
 * in the file called LICENSE.
22
 *
A
Amit S. Kale 已提交
23 24
 * Contact Information:
 *    info@netxen.com
D
Dhananjay Phadke 已提交
25 26 27
 * NetXen Inc,
 * 18922 Forge Drive
 * Cupertino, CA 95014-0701
A
Amit S. Kale 已提交
28 29 30 31
 *
 */

#include "netxen_nic.h"
32

33
/*
A
Amit S. Kale 已提交
34 35 36 37
 * netxen_niu_gbe_phy_read - read a register from the GbE PHY via
 * mii management interface.
 *
 * Note: The MII management interface goes through port 0.
38
 *	Individual phys are addressed as follows:
A
Amit S. Kale 已提交
39 40 41 42
 * @param phy  [15:8]  phy id
 * @param reg  [7:0]   register number
 *
 * @returns  0 on success
43
 *	  -1 on error
A
Amit S. Kale 已提交
44 45
 *
 */
46
int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
47
				__u32 * readval)
A
Amit S. Kale 已提交
48 49 50 51
{
	long timeout = 0;
	long result = 0;
	long restore = 0;
52
	long phy = adapter->physical_port;
A
Al Viro 已提交
53 54 55 56
	__u32 address;
	__u32 command;
	__u32 status;
	__u32 mac_cfg0;
A
Amit S. Kale 已提交
57

58
	if (netxen_phy_lock(adapter) != 0)
59 60 61 62 63 64 65
		return -1;

	/*
	 * MII mgmt all goes through port 0 MAC interface,
	 * so it cannot be in reset
	 */

66
	mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
A
Amit S. Kale 已提交
67
	if (netxen_gb_get_soft_reset(mac_cfg0)) {
A
Al Viro 已提交
68
		__u32 temp;
A
Amit S. Kale 已提交
69 70 71 72 73
		temp = 0;
		netxen_gb_tx_reset_pb(temp);
		netxen_gb_rx_reset_pb(temp);
		netxen_gb_tx_reset_mac(temp);
		netxen_gb_rx_reset_mac(temp);
74
		if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
A
Amit S. Kale 已提交
75 76 77 78 79 80 81
			return -EIO;
		restore = 1;
	}

	address = 0;
	netxen_gb_mii_mgmt_reg_addr(address, reg);
	netxen_gb_mii_mgmt_phy_addr(address, phy);
82
	if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
A
Amit S. Kale 已提交
83 84
		return -EIO;
	command = 0;		/* turn off any prior activity */
85
	if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
A
Amit S. Kale 已提交
86 87 88
		return -EIO;
	/* send read command */
	netxen_gb_mii_mgmt_set_read_cycle(command);
89
	if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
A
Amit S. Kale 已提交
90 91 92 93
		return -EIO;

	status = 0;
	do {
94
		status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
A
Amit S. Kale 已提交
95 96 97 98 99 100
		timeout++;
	} while ((netxen_get_gb_mii_mgmt_busy(status)
		  || netxen_get_gb_mii_mgmt_notvalid(status))
		 && (timeout++ < NETXEN_NIU_PHY_WAITMAX));

	if (timeout < NETXEN_NIU_PHY_WAITMAX) {
101
		*readval = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_STATUS(0));
A
Amit S. Kale 已提交
102 103 104 105 106
		result = 0;
	} else
		result = -1;

	if (restore)
107
		if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
A
Amit S. Kale 已提交
108
			return -EIO;
109
	netxen_phy_unlock(adapter);
A
Amit S. Kale 已提交
110 111 112
	return result;
}

113
/*
A
Amit S. Kale 已提交
114 115 116 117
 * netxen_niu_gbe_phy_write - write a register to the GbE PHY via
 * mii management interface.
 *
 * Note: The MII management interface goes through port 0.
118
 *	Individual phys are addressed as follows:
A
Amit S. Kale 已提交
119 120 121 122
 * @param phy      [15:8]  phy id
 * @param reg      [7:0]   register number
 *
 * @returns  0 on success
123
 *	  -1 on error
A
Amit S. Kale 已提交
124 125
 *
 */
126
int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
127
				__u32 val)
A
Amit S. Kale 已提交
128 129 130 131
{
	long timeout = 0;
	long result = 0;
	long restore = 0;
132
	long phy = adapter->physical_port;
A
Al Viro 已提交
133 134 135 136
	__u32 address;
	__u32 command;
	__u32 status;
	__u32 mac_cfg0;
A
Amit S. Kale 已提交
137

138 139 140 141 142
	/*
	 * MII mgmt all goes through port 0 MAC interface, so it
	 * cannot be in reset
	 */

143
	mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
A
Amit S. Kale 已提交
144
	if (netxen_gb_get_soft_reset(mac_cfg0)) {
A
Al Viro 已提交
145
		__u32 temp;
A
Amit S. Kale 已提交
146 147 148 149 150 151
		temp = 0;
		netxen_gb_tx_reset_pb(temp);
		netxen_gb_rx_reset_pb(temp);
		netxen_gb_tx_reset_mac(temp);
		netxen_gb_rx_reset_mac(temp);

152
		if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
A
Amit S. Kale 已提交
153 154 155 156 157
			return -EIO;
		restore = 1;
	}

	command = 0;		/* turn off any prior activity */
158
	if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
A
Amit S. Kale 已提交
159 160 161 162 163
		return -EIO;

	address = 0;
	netxen_gb_mii_mgmt_reg_addr(address, reg);
	netxen_gb_mii_mgmt_phy_addr(address, phy);
164
	if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
A
Amit S. Kale 已提交
165 166
		return -EIO;

167
	if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), val))
A
Amit S. Kale 已提交
168 169 170 171
		return -EIO;

	status = 0;
	do {
172
		status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
A
Amit S. Kale 已提交
173 174 175 176 177 178 179 180 181 182 183
		timeout++;
	} while ((netxen_get_gb_mii_mgmt_busy(status))
		 && (timeout++ < NETXEN_NIU_PHY_WAITMAX));

	if (timeout < NETXEN_NIU_PHY_WAITMAX)
		result = 0;
	else
		result = -EIO;

	/* restore the state of port 0 MAC in case we tampered with it */
	if (restore)
184
		if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
A
Amit S. Kale 已提交
185 186 187 188 189
			return -EIO;

	return result;
}

190 191
int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
{
192
	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
193 194
		NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
		NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
195
	}
196

197
	return 0;
198 199
}

A
Amit S. Kale 已提交
200
/* Disable an XG interface */
201
int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
A
Amit S. Kale 已提交
202
{
A
Al Viro 已提交
203
	__u32 mac_cfg;
204
	u32 port = adapter->physical_port;
A
Amit S. Kale 已提交
205

206 207 208
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
		return 0;

209
	if (port > NETXEN_NIU_MAX_XG_PORTS)
210
		return -EINVAL;
211

A
Amit S. Kale 已提交
212
	mac_cfg = 0;
213 214
	if (NXWR32(adapter,
			NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg))
A
Amit S. Kale 已提交
215 216 217 218 219
		return -EIO;
	return 0;
}

int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
220
		u32 mode)
A
Amit S. Kale 已提交
221
{
A
Al Viro 已提交
222
	__u32 reg;
223
	u32 port = adapter->physical_port;
A
Amit S. Kale 已提交
224

225
	if (port > NETXEN_NIU_MAX_XG_PORTS)
A
Amit S. Kale 已提交
226 227
		return -EINVAL;

228
	reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
A
Amit S. Kale 已提交
229 230 231 232 233
	if (mode == NETXEN_NIU_PROMISC_MODE)
		reg = (reg | 0x2000UL);
	else
		reg = (reg & ~0x2000UL);

234 235 236 237 238
	if (mode == NETXEN_NIU_ALLMULTI_MODE)
		reg = (reg | 0x1000UL);
	else
		reg = (reg & ~0x1000UL);

239
	NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
A
Amit S. Kale 已提交
240 241 242

	return 0;
}
D
Dhananjay Phadke 已提交
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275

int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
{
	u32 mac_hi, mac_lo;
	u32 reg_hi, reg_lo;

	u8 phy = adapter->physical_port;
	u8 phy_count = (adapter->ahw.port_type == NETXEN_NIC_XGBE) ?
		NETXEN_NIU_MAX_XG_PORTS : NETXEN_NIU_MAX_GBE_PORTS;

	if (phy >= phy_count)
		return -EINVAL;

	mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24);
	mac_hi = addr[2] | ((u32)addr[3] << 8) |
		((u32)addr[4] << 16) | ((u32)addr[5] << 24);

	if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
		reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy);
		reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy);
	} else {
		reg_lo = NETXEN_NIU_GB_STATION_ADDR_1(phy);
		reg_hi = NETXEN_NIU_GB_STATION_ADDR_0(phy);
	}

	/* write twice to flush */
	if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
		return -EIO;
	if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
		return -EIO;

	return 0;
}