diff options
Diffstat (limited to 'drivers/net/sfc')
28 files changed, 3087 insertions, 1427 deletions
diff --git a/drivers/net/sfc/Kconfig b/drivers/net/sfc/Kconfig index 3be13b592b4d..c535408ad6be 100644 --- a/drivers/net/sfc/Kconfig +++ b/drivers/net/sfc/Kconfig | |||
@@ -12,3 +12,11 @@ config SFC | |||
12 | 12 | ||
13 | To compile this driver as a module, choose M here. The module | 13 | To compile this driver as a module, choose M here. The module |
14 | will be called sfc. | 14 | will be called sfc. |
15 | config SFC_MTD | ||
16 | bool "Solarflare Solarstorm SFC4000 flash MTD support" | ||
17 | depends on SFC && MTD && !(SFC=y && MTD=m) | ||
18 | default y | ||
19 | help | ||
20 | This exposes the on-board flash memory as an MTD device (e.g. | ||
21 | /dev/mtd1). This makes it possible to upload new boot code | ||
22 | to the NIC. | ||
diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile index c8f5704c8fb1..b89f9be3cb13 100644 --- a/drivers/net/sfc/Makefile +++ b/drivers/net/sfc/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | sfc-y += efx.o falcon.o tx.o rx.o falcon_xmac.o \ | 1 | sfc-y += efx.o falcon.o tx.o rx.o falcon_gmac.o \ |
2 | selftest.o ethtool.o xfp_phy.o \ | 2 | falcon_xmac.o selftest.o ethtool.o xfp_phy.o \ |
3 | mdio_10g.o tenxpress.o boards.o sfe4001.o | 3 | mdio_10g.o tenxpress.o boards.o sfe4001.o |
4 | sfc-$(CONFIG_SFC_MTD) += mtd.o | ||
4 | 5 | ||
5 | obj-$(CONFIG_SFC) += sfc.o | 6 | obj-$(CONFIG_SFC) += sfc.o |
diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c index 99e602373269..64903496aa9a 100644 --- a/drivers/net/sfc/boards.c +++ b/drivers/net/sfc/boards.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /**************************************************************************** | 1 | /**************************************************************************** |
2 | * Driver for Solarflare Solarstorm network controllers and boards | 2 | * Driver for Solarflare Solarstorm network controllers and boards |
3 | * Copyright 2007 Solarflare Communications Inc. | 3 | * Copyright 2007-2008 Solarflare Communications Inc. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 as published | 6 | * under the terms of the GNU General Public License version 2 as published |
@@ -11,6 +11,7 @@ | |||
11 | #include "phy.h" | 11 | #include "phy.h" |
12 | #include "boards.h" | 12 | #include "boards.h" |
13 | #include "efx.h" | 13 | #include "efx.h" |
14 | #include "workarounds.h" | ||
14 | 15 | ||
15 | /* Macros for unpacking the board revision */ | 16 | /* Macros for unpacking the board revision */ |
16 | /* The revision info is in host byte order. */ | 17 | /* The revision info is in host byte order. */ |
@@ -52,9 +53,128 @@ static void board_blink(struct efx_nic *efx, bool blink) | |||
52 | } | 53 | } |
53 | 54 | ||
54 | /***************************************************************************** | 55 | /***************************************************************************** |
56 | * Support for LM87 sensor chip used on several boards | ||
57 | */ | ||
58 | #define LM87_REG_ALARMS1 0x41 | ||
59 | #define LM87_REG_ALARMS2 0x42 | ||
60 | #define LM87_IN_LIMITS(nr, _min, _max) \ | ||
61 | 0x2B + (nr) * 2, _max, 0x2C + (nr) * 2, _min | ||
62 | #define LM87_AIN_LIMITS(nr, _min, _max) \ | ||
63 | 0x3B + (nr), _max, 0x1A + (nr), _min | ||
64 | #define LM87_TEMP_INT_LIMITS(_min, _max) \ | ||
65 | 0x39, _max, 0x3A, _min | ||
66 | #define LM87_TEMP_EXT1_LIMITS(_min, _max) \ | ||
67 | 0x37, _max, 0x38, _min | ||
68 | |||
69 | #define LM87_ALARM_TEMP_INT 0x10 | ||
70 | #define LM87_ALARM_TEMP_EXT1 0x20 | ||
71 | |||
72 | #if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE) | ||
73 | |||
74 | static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, | ||
75 | const u8 *reg_values) | ||
76 | { | ||
77 | struct i2c_client *client = i2c_new_device(&efx->i2c_adap, info); | ||
78 | int rc; | ||
79 | |||
80 | if (!client) | ||
81 | return -EIO; | ||
82 | |||
83 | while (*reg_values) { | ||
84 | u8 reg = *reg_values++; | ||
85 | u8 value = *reg_values++; | ||
86 | rc = i2c_smbus_write_byte_data(client, reg, value); | ||
87 | if (rc) | ||
88 | goto err; | ||
89 | } | ||
90 | |||
91 | efx->board_info.hwmon_client = client; | ||
92 | return 0; | ||
93 | |||
94 | err: | ||
95 | i2c_unregister_device(client); | ||
96 | return rc; | ||
97 | } | ||
98 | |||
99 | static void efx_fini_lm87(struct efx_nic *efx) | ||
100 | { | ||
101 | i2c_unregister_device(efx->board_info.hwmon_client); | ||
102 | } | ||
103 | |||
104 | static int efx_check_lm87(struct efx_nic *efx, unsigned mask) | ||
105 | { | ||
106 | struct i2c_client *client = efx->board_info.hwmon_client; | ||
107 | s32 alarms1, alarms2; | ||
108 | |||
109 | /* If link is up then do not monitor temperature */ | ||
110 | if (EFX_WORKAROUND_7884(efx) && efx->link_up) | ||
111 | return 0; | ||
112 | |||
113 | alarms1 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1); | ||
114 | alarms2 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2); | ||
115 | if (alarms1 < 0) | ||
116 | return alarms1; | ||
117 | if (alarms2 < 0) | ||
118 | return alarms2; | ||
119 | alarms1 &= mask; | ||
120 | alarms2 &= mask >> 8; | ||
121 | if (alarms1 || alarms2) { | ||
122 | EFX_ERR(efx, | ||
123 | "LM87 detected a hardware failure (status %02x:%02x)" | ||
124 | "%s%s\n", | ||
125 | alarms1, alarms2, | ||
126 | (alarms1 & LM87_ALARM_TEMP_INT) ? " INTERNAL" : "", | ||
127 | (alarms1 & LM87_ALARM_TEMP_EXT1) ? " EXTERNAL" : ""); | ||
128 | return -ERANGE; | ||
129 | } | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | #else /* !CONFIG_SENSORS_LM87 */ | ||
135 | |||
136 | static inline int | ||
137 | efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, | ||
138 | const u8 *reg_values) | ||
139 | { | ||
140 | return 0; | ||
141 | } | ||
142 | static inline void efx_fini_lm87(struct efx_nic *efx) | ||
143 | { | ||
144 | } | ||
145 | static inline int efx_check_lm87(struct efx_nic *efx, unsigned mask) | ||
146 | { | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | #endif /* CONFIG_SENSORS_LM87 */ | ||
151 | |||
152 | /***************************************************************************** | ||
55 | * Support for the SFE4002 | 153 | * Support for the SFE4002 |
56 | * | 154 | * |
57 | */ | 155 | */ |
156 | static u8 sfe4002_lm87_channel = 0x03; /* use AIN not FAN inputs */ | ||
157 | |||
158 | static const u8 sfe4002_lm87_regs[] = { | ||
159 | LM87_IN_LIMITS(0, 0x83, 0x91), /* 2.5V: 1.8V +/- 5% */ | ||
160 | LM87_IN_LIMITS(1, 0x51, 0x5a), /* Vccp1: 1.2V +/- 5% */ | ||
161 | LM87_IN_LIMITS(2, 0xb6, 0xca), /* 3.3V: 3.3V +/- 5% */ | ||
162 | LM87_IN_LIMITS(3, 0xb0, 0xc9), /* 5V: 4.6-5.2V */ | ||
163 | LM87_IN_LIMITS(4, 0xb0, 0xe0), /* 12V: 11-14V */ | ||
164 | LM87_IN_LIMITS(5, 0x44, 0x4b), /* Vccp2: 1.0V +/- 5% */ | ||
165 | LM87_AIN_LIMITS(0, 0xa0, 0xb2), /* AIN1: 1.66V +/- 5% */ | ||
166 | LM87_AIN_LIMITS(1, 0x91, 0xa1), /* AIN2: 1.5V +/- 5% */ | ||
167 | LM87_TEMP_INT_LIMITS(10, 60), /* board */ | ||
168 | LM87_TEMP_EXT1_LIMITS(10, 70), /* Falcon */ | ||
169 | 0 | ||
170 | }; | ||
171 | |||
172 | static struct i2c_board_info sfe4002_hwmon_info = { | ||
173 | I2C_BOARD_INFO("lm87", 0x2e), | ||
174 | .platform_data = &sfe4002_lm87_channel, | ||
175 | .irq = -1, | ||
176 | }; | ||
177 | |||
58 | /****************************************************************************/ | 178 | /****************************************************************************/ |
59 | /* LED allocations. Note that on rev A0 boards the schematic and the reality | 179 | /* LED allocations. Note that on rev A0 boards the schematic and the reality |
60 | * differ: red and green are swapped. Below is the fixed (A1) layout (there | 180 | * differ: red and green are swapped. Below is the fixed (A1) layout (there |
@@ -84,81 +204,67 @@ static void sfe4002_fault_led(struct efx_nic *efx, bool state) | |||
84 | QUAKE_LED_OFF); | 204 | QUAKE_LED_OFF); |
85 | } | 205 | } |
86 | 206 | ||
207 | static int sfe4002_check_hw(struct efx_nic *efx) | ||
208 | { | ||
209 | /* A0 board rev. 4002s report a temperature fault the whole time | ||
210 | * (bad sensor) so we mask it out. */ | ||
211 | unsigned alarm_mask = | ||
212 | (efx->board_info.major == 0 && efx->board_info.minor == 0) ? | ||
213 | ~LM87_ALARM_TEMP_EXT1 : ~0; | ||
214 | |||
215 | return efx_check_lm87(efx, alarm_mask); | ||
216 | } | ||
217 | |||
87 | static int sfe4002_init(struct efx_nic *efx) | 218 | static int sfe4002_init(struct efx_nic *efx) |
88 | { | 219 | { |
220 | int rc = efx_init_lm87(efx, &sfe4002_hwmon_info, sfe4002_lm87_regs); | ||
221 | if (rc) | ||
222 | return rc; | ||
223 | efx->board_info.monitor = sfe4002_check_hw; | ||
89 | efx->board_info.init_leds = sfe4002_init_leds; | 224 | efx->board_info.init_leds = sfe4002_init_leds; |
90 | efx->board_info.set_fault_led = sfe4002_fault_led; | 225 | efx->board_info.set_fault_led = sfe4002_fault_led; |
91 | efx->board_info.blink = board_blink; | 226 | efx->board_info.blink = board_blink; |
227 | efx->board_info.fini = efx_fini_lm87; | ||
92 | return 0; | 228 | return 0; |
93 | } | 229 | } |
94 | 230 | ||
95 | /* This will get expanded as board-specific details get moved out of the | 231 | /* This will get expanded as board-specific details get moved out of the |
96 | * PHY drivers. */ | 232 | * PHY drivers. */ |
97 | struct efx_board_data { | 233 | struct efx_board_data { |
234 | enum efx_board_type type; | ||
98 | const char *ref_model; | 235 | const char *ref_model; |
99 | const char *gen_type; | 236 | const char *gen_type; |
100 | int (*init) (struct efx_nic *nic); | 237 | int (*init) (struct efx_nic *nic); |
101 | }; | 238 | }; |
102 | 239 | ||
103 | static int dummy_init(struct efx_nic *nic) | ||
104 | { | ||
105 | return 0; | ||
106 | } | ||
107 | 240 | ||
108 | static struct efx_board_data board_data[] = { | 241 | static struct efx_board_data board_data[] = { |
109 | [EFX_BOARD_INVALID] = | 242 | { EFX_BOARD_SFE4001, "SFE4001", "10GBASE-T adapter", sfe4001_init }, |
110 | {NULL, NULL, dummy_init}, | 243 | { EFX_BOARD_SFE4002, "SFE4002", "XFP adapter", sfe4002_init }, |
111 | [EFX_BOARD_SFE4001] = | 244 | { EFX_BOARD_SFN4111T, "SFN4111T", "100/1000/10GBASE-T adapter", |
112 | {"SFE4001", "10GBASE-T adapter", sfe4001_init}, | 245 | sfn4111t_init }, |
113 | [EFX_BOARD_SFE4002] = | ||
114 | {"SFE4002", "XFP adapter", sfe4002_init}, | ||
115 | }; | 246 | }; |
116 | 247 | ||
117 | int efx_set_board_info(struct efx_nic *efx, u16 revision_info) | 248 | void efx_set_board_info(struct efx_nic *efx, u16 revision_info) |
118 | { | 249 | { |
119 | int rc = 0; | 250 | struct efx_board_data *data = NULL; |
120 | struct efx_board_data *data; | 251 | int i; |
121 | |||
122 | if (BOARD_TYPE(revision_info) >= EFX_BOARD_MAX) { | ||
123 | EFX_ERR(efx, "squashing unknown board type %d\n", | ||
124 | BOARD_TYPE(revision_info)); | ||
125 | revision_info = 0; | ||
126 | } | ||
127 | 252 | ||
128 | if (BOARD_TYPE(revision_info) == 0) { | 253 | efx->board_info.type = BOARD_TYPE(revision_info); |
129 | efx->board_info.major = 0; | 254 | efx->board_info.major = BOARD_MAJOR(revision_info); |
130 | efx->board_info.minor = 0; | 255 | efx->board_info.minor = BOARD_MINOR(revision_info); |
131 | /* For early boards that don't have revision info. there is | ||
132 | * only 1 board for each PHY type, so we can work it out, with | ||
133 | * the exception of the PHY-less boards. */ | ||
134 | switch (efx->phy_type) { | ||
135 | case PHY_TYPE_10XPRESS: | ||
136 | efx->board_info.type = EFX_BOARD_SFE4001; | ||
137 | break; | ||
138 | case PHY_TYPE_XFP: | ||
139 | efx->board_info.type = EFX_BOARD_SFE4002; | ||
140 | break; | ||
141 | default: | ||
142 | efx->board_info.type = 0; | ||
143 | break; | ||
144 | } | ||
145 | } else { | ||
146 | efx->board_info.type = BOARD_TYPE(revision_info); | ||
147 | efx->board_info.major = BOARD_MAJOR(revision_info); | ||
148 | efx->board_info.minor = BOARD_MINOR(revision_info); | ||
149 | } | ||
150 | 256 | ||
151 | data = &board_data[efx->board_info.type]; | 257 | for (i = 0; i < ARRAY_SIZE(board_data); i++) |
258 | if (board_data[i].type == efx->board_info.type) | ||
259 | data = &board_data[i]; | ||
152 | 260 | ||
153 | /* Report the board model number or generic type for recognisable | 261 | if (data) { |
154 | * boards. */ | ||
155 | if (efx->board_info.type != 0) | ||
156 | EFX_INFO(efx, "board is %s rev %c%d\n", | 262 | EFX_INFO(efx, "board is %s rev %c%d\n", |
157 | (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC) | 263 | (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC) |
158 | ? data->ref_model : data->gen_type, | 264 | ? data->ref_model : data->gen_type, |
159 | 'A' + efx->board_info.major, efx->board_info.minor); | 265 | 'A' + efx->board_info.major, efx->board_info.minor); |
160 | 266 | efx->board_info.init = data->init; | |
161 | efx->board_info.init = data->init; | 267 | } else { |
162 | 268 | EFX_ERR(efx, "unknown board type %d\n", efx->board_info.type); | |
163 | return rc; | 269 | } |
164 | } | 270 | } |
diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h index c6e01b64bfb4..d93c6c6a7548 100644 --- a/drivers/net/sfc/boards.h +++ b/drivers/net/sfc/boards.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /**************************************************************************** | 1 | /**************************************************************************** |
2 | * Driver for Solarflare Solarstorm network controllers and boards | 2 | * Driver for Solarflare Solarstorm network controllers and boards |
3 | * Copyright 2007 Solarflare Communications Inc. | 3 | * Copyright 2007-2008 Solarflare Communications Inc. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 as published | 6 | * under the terms of the GNU General Public License version 2 as published |
@@ -12,14 +12,16 @@ | |||
12 | 12 | ||
13 | /* Board IDs (must fit in 8 bits) */ | 13 | /* Board IDs (must fit in 8 bits) */ |
14 | enum efx_board_type { | 14 | enum efx_board_type { |
15 | EFX_BOARD_INVALID = 0, | 15 | EFX_BOARD_SFE4001 = 1, |
16 | EFX_BOARD_SFE4001 = 1, /* SFE4001 (10GBASE-T) */ | ||
17 | EFX_BOARD_SFE4002 = 2, | 16 | EFX_BOARD_SFE4002 = 2, |
18 | /* Insert new types before here */ | 17 | EFX_BOARD_SFN4111T = 0x51, |
19 | EFX_BOARD_MAX | ||
20 | }; | 18 | }; |
21 | 19 | ||
22 | extern int efx_set_board_info(struct efx_nic *efx, u16 revision_info); | 20 | extern void efx_set_board_info(struct efx_nic *efx, u16 revision_info); |
21 | |||
22 | /* SFE4001 (10GBASE-T) */ | ||
23 | extern int sfe4001_init(struct efx_nic *efx); | 23 | extern int sfe4001_init(struct efx_nic *efx); |
24 | /* SFN4111T (100/1000/10GBASE-T) */ | ||
25 | extern int sfn4111t_init(struct efx_nic *efx); | ||
24 | 26 | ||
25 | #endif | 27 | #endif |
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 06ea71c7e34e..847e9bb0098f 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -21,14 +21,12 @@ | |||
21 | #include <linux/ethtool.h> | 21 | #include <linux/ethtool.h> |
22 | #include <linux/topology.h> | 22 | #include <linux/topology.h> |
23 | #include "net_driver.h" | 23 | #include "net_driver.h" |
24 | #include "gmii.h" | ||
25 | #include "ethtool.h" | 24 | #include "ethtool.h" |
26 | #include "tx.h" | 25 | #include "tx.h" |
27 | #include "rx.h" | 26 | #include "rx.h" |
28 | #include "efx.h" | 27 | #include "efx.h" |
29 | #include "mdio_10g.h" | 28 | #include "mdio_10g.h" |
30 | #include "falcon.h" | 29 | #include "falcon.h" |
31 | #include "mac.h" | ||
32 | 30 | ||
33 | #define EFX_MAX_MTU (9 * 1024) | 31 | #define EFX_MAX_MTU (9 * 1024) |
34 | 32 | ||
@@ -39,6 +37,12 @@ | |||
39 | */ | 37 | */ |
40 | static struct workqueue_struct *refill_workqueue; | 38 | static struct workqueue_struct *refill_workqueue; |
41 | 39 | ||
40 | /* Reset workqueue. If any NIC has a hardware failure then a reset will be | ||
41 | * queued onto this work queue. This is not a per-nic work queue, because | ||
42 | * efx_reset_work() acquires the rtnl lock, so resets are naturally serialised. | ||
43 | */ | ||
44 | static struct workqueue_struct *reset_workqueue; | ||
45 | |||
42 | /************************************************************************** | 46 | /************************************************************************** |
43 | * | 47 | * |
44 | * Configurable values | 48 | * Configurable values |
@@ -58,13 +62,15 @@ MODULE_PARM_DESC(lro, "Large receive offload acceleration"); | |||
58 | /* | 62 | /* |
59 | * Use separate channels for TX and RX events | 63 | * Use separate channels for TX and RX events |
60 | * | 64 | * |
61 | * Set this to 1 to use separate channels for TX and RX. It allows us to | 65 | * Set this to 1 to use separate channels for TX and RX. It allows us |
62 | * apply a higher level of interrupt moderation to TX events. | 66 | * to control interrupt affinity separately for TX and RX. |
63 | * | 67 | * |
64 | * This is forced to 0 for MSI interrupt mode as the interrupt vector | 68 | * This is only used in MSI-X interrupt mode |
65 | * is not written | ||
66 | */ | 69 | */ |
67 | static unsigned int separate_tx_and_rx_channels = true; | 70 | static unsigned int separate_tx_channels; |
71 | module_param(separate_tx_channels, uint, 0644); | ||
72 | MODULE_PARM_DESC(separate_tx_channels, | ||
73 | "Use separate channels for TX and RX"); | ||
68 | 74 | ||
69 | /* This is the weight assigned to each of the (per-channel) virtual | 75 | /* This is the weight assigned to each of the (per-channel) virtual |
70 | * NAPI devices. | 76 | * NAPI devices. |
@@ -77,11 +83,6 @@ static int napi_weight = 64; | |||
77 | */ | 83 | */ |
78 | unsigned int efx_monitor_interval = 1 * HZ; | 84 | unsigned int efx_monitor_interval = 1 * HZ; |
79 | 85 | ||
80 | /* This controls whether or not the hardware monitor will trigger a | ||
81 | * reset when it detects an error condition. | ||
82 | */ | ||
83 | static unsigned int monitor_reset = true; | ||
84 | |||
85 | /* This controls whether or not the driver will initialise devices | 86 | /* This controls whether or not the driver will initialise devices |
86 | * with invalid MAC addresses stored in the EEPROM or flash. If true, | 87 | * with invalid MAC addresses stored in the EEPROM or flash. If true, |
87 | * such devices will be initialised with a random locally-generated | 88 | * such devices will be initialised with a random locally-generated |
@@ -128,6 +129,10 @@ static unsigned int rss_cpus; | |||
128 | module_param(rss_cpus, uint, 0444); | 129 | module_param(rss_cpus, uint, 0444); |
129 | MODULE_PARM_DESC(rss_cpus, "Number of CPUs to use for Receive-Side Scaling"); | 130 | MODULE_PARM_DESC(rss_cpus, "Number of CPUs to use for Receive-Side Scaling"); |
130 | 131 | ||
132 | static int phy_flash_cfg; | ||
133 | module_param(phy_flash_cfg, int, 0644); | ||
134 | MODULE_PARM_DESC(phy_flash_cfg, "Set PHYs into reflash mode initially"); | ||
135 | |||
131 | /************************************************************************** | 136 | /************************************************************************** |
132 | * | 137 | * |
133 | * Utility functions and prototypes | 138 | * Utility functions and prototypes |
@@ -211,7 +216,6 @@ static int efx_poll(struct napi_struct *napi, int budget) | |||
211 | { | 216 | { |
212 | struct efx_channel *channel = | 217 | struct efx_channel *channel = |
213 | container_of(napi, struct efx_channel, napi_str); | 218 | container_of(napi, struct efx_channel, napi_str); |
214 | struct net_device *napi_dev = channel->napi_dev; | ||
215 | int rx_packets; | 219 | int rx_packets; |
216 | 220 | ||
217 | EFX_TRACE(channel->efx, "channel %d NAPI poll executing on CPU %d\n", | 221 | EFX_TRACE(channel->efx, "channel %d NAPI poll executing on CPU %d\n", |
@@ -225,7 +229,7 @@ static int efx_poll(struct napi_struct *napi, int budget) | |||
225 | * since efx_channel_processed() will have no effect if | 229 | * since efx_channel_processed() will have no effect if |
226 | * interrupts have already been disabled. | 230 | * interrupts have already been disabled. |
227 | */ | 231 | */ |
228 | netif_rx_complete(napi_dev, napi); | 232 | netif_rx_complete(napi); |
229 | efx_channel_processed(channel); | 233 | efx_channel_processed(channel); |
230 | } | 234 | } |
231 | 235 | ||
@@ -349,6 +353,27 @@ static int efx_probe_channel(struct efx_channel *channel) | |||
349 | } | 353 | } |
350 | 354 | ||
351 | 355 | ||
356 | static void efx_set_channel_names(struct efx_nic *efx) | ||
357 | { | ||
358 | struct efx_channel *channel; | ||
359 | const char *type = ""; | ||
360 | int number; | ||
361 | |||
362 | efx_for_each_channel(channel, efx) { | ||
363 | number = channel->channel; | ||
364 | if (efx->n_channels > efx->n_rx_queues) { | ||
365 | if (channel->channel < efx->n_rx_queues) { | ||
366 | type = "-rx"; | ||
367 | } else { | ||
368 | type = "-tx"; | ||
369 | number -= efx->n_rx_queues; | ||
370 | } | ||
371 | } | ||
372 | snprintf(channel->name, sizeof(channel->name), | ||
373 | "%s%s-%d", efx->name, type, number); | ||
374 | } | ||
375 | } | ||
376 | |||
352 | /* Channels are shutdown and reinitialised whilst the NIC is running | 377 | /* Channels are shutdown and reinitialised whilst the NIC is running |
353 | * to propagate configuration changes (mtu, checksum offload), or | 378 | * to propagate configuration changes (mtu, checksum offload), or |
354 | * to clear hardware error conditions | 379 | * to clear hardware error conditions |
@@ -523,26 +548,8 @@ static void efx_link_status_changed(struct efx_nic *efx) | |||
523 | 548 | ||
524 | /* Status message for kernel log */ | 549 | /* Status message for kernel log */ |
525 | if (efx->link_up) { | 550 | if (efx->link_up) { |
526 | struct mii_if_info *gmii = &efx->mii; | 551 | EFX_INFO(efx, "link up at %uMbps %s-duplex (MTU %d)%s\n", |
527 | unsigned adv, lpa; | 552 | efx->link_speed, efx->link_fd ? "full" : "half", |
528 | /* NONE here means direct XAUI from the controller, with no | ||
529 | * MDIO-attached device we can query. */ | ||
530 | if (efx->phy_type != PHY_TYPE_NONE) { | ||
531 | adv = gmii_advertised(gmii); | ||
532 | lpa = gmii_lpa(gmii); | ||
533 | } else { | ||
534 | lpa = GM_LPA_10000 | LPA_DUPLEX; | ||
535 | adv = lpa; | ||
536 | } | ||
537 | EFX_INFO(efx, "link up at %dMbps %s-duplex " | ||
538 | "(adv %04x lpa %04x) (MTU %d)%s\n", | ||
539 | (efx->link_options & GM_LPA_10000 ? 10000 : | ||
540 | (efx->link_options & GM_LPA_1000 ? 1000 : | ||
541 | (efx->link_options & GM_LPA_100 ? 100 : | ||
542 | 10))), | ||
543 | (efx->link_options & GM_LPA_DUPLEX ? | ||
544 | "full" : "half"), | ||
545 | adv, lpa, | ||
546 | efx->net_dev->mtu, | 553 | efx->net_dev->mtu, |
547 | (efx->promiscuous ? " [PROMISC]" : "")); | 554 | (efx->promiscuous ? " [PROMISC]" : "")); |
548 | } else { | 555 | } else { |
@@ -566,10 +573,28 @@ void __efx_reconfigure_port(struct efx_nic *efx) | |||
566 | netif_addr_unlock_bh(efx->net_dev); | 573 | netif_addr_unlock_bh(efx->net_dev); |
567 | } | 574 | } |
568 | 575 | ||
569 | falcon_reconfigure_xmac(efx); | 576 | falcon_deconfigure_mac_wrapper(efx); |
577 | |||
578 | /* Reconfigure the PHY, disabling transmit in mac level loopback. */ | ||
579 | if (LOOPBACK_INTERNAL(efx)) | ||
580 | efx->phy_mode |= PHY_MODE_TX_DISABLED; | ||
581 | else | ||
582 | efx->phy_mode &= ~PHY_MODE_TX_DISABLED; | ||
583 | efx->phy_op->reconfigure(efx); | ||
584 | |||
585 | if (falcon_switch_mac(efx)) | ||
586 | goto fail; | ||
587 | |||
588 | efx->mac_op->reconfigure(efx); | ||
570 | 589 | ||
571 | /* Inform kernel of loss/gain of carrier */ | 590 | /* Inform kernel of loss/gain of carrier */ |
572 | efx_link_status_changed(efx); | 591 | efx_link_status_changed(efx); |
592 | return; | ||
593 | |||
594 | fail: | ||
595 | EFX_ERR(efx, "failed to reconfigure MAC\n"); | ||
596 | efx->phy_op->fini(efx); | ||
597 | efx->port_initialized = false; | ||
573 | } | 598 | } |
574 | 599 | ||
575 | /* Reinitialise the MAC to pick up new PHY settings, even if the port is | 600 | /* Reinitialise the MAC to pick up new PHY settings, even if the port is |
@@ -586,10 +611,9 @@ void efx_reconfigure_port(struct efx_nic *efx) | |||
586 | /* Asynchronous efx_reconfigure_port work item. To speed up efx_flush_all() | 611 | /* Asynchronous efx_reconfigure_port work item. To speed up efx_flush_all() |
587 | * we don't efx_reconfigure_port() if the port is disabled. Care is taken | 612 | * we don't efx_reconfigure_port() if the port is disabled. Care is taken |
588 | * in efx_stop_all() and efx_start_port() to prevent PHY events being lost */ | 613 | * in efx_stop_all() and efx_start_port() to prevent PHY events being lost */ |
589 | static void efx_reconfigure_work(struct work_struct *data) | 614 | static void efx_phy_work(struct work_struct *data) |
590 | { | 615 | { |
591 | struct efx_nic *efx = container_of(data, struct efx_nic, | 616 | struct efx_nic *efx = container_of(data, struct efx_nic, phy_work); |
592 | reconfigure_work); | ||
593 | 617 | ||
594 | mutex_lock(&efx->mac_lock); | 618 | mutex_lock(&efx->mac_lock); |
595 | if (efx->port_enabled) | 619 | if (efx->port_enabled) |
@@ -597,6 +621,16 @@ static void efx_reconfigure_work(struct work_struct *data) | |||
597 | mutex_unlock(&efx->mac_lock); | 621 | mutex_unlock(&efx->mac_lock); |
598 | } | 622 | } |
599 | 623 | ||
624 | static void efx_mac_work(struct work_struct *data) | ||
625 | { | ||
626 | struct efx_nic *efx = container_of(data, struct efx_nic, mac_work); | ||
627 | |||
628 | mutex_lock(&efx->mac_lock); | ||
629 | if (efx->port_enabled) | ||
630 | efx->mac_op->irq(efx); | ||
631 | mutex_unlock(&efx->mac_lock); | ||
632 | } | ||
633 | |||
600 | static int efx_probe_port(struct efx_nic *efx) | 634 | static int efx_probe_port(struct efx_nic *efx) |
601 | { | 635 | { |
602 | int rc; | 636 | int rc; |
@@ -608,21 +642,22 @@ static int efx_probe_port(struct efx_nic *efx) | |||
608 | if (rc) | 642 | if (rc) |
609 | goto err; | 643 | goto err; |
610 | 644 | ||
645 | if (phy_flash_cfg) | ||
646 | efx->phy_mode = PHY_MODE_SPECIAL; | ||
647 | |||
611 | /* Sanity check MAC address */ | 648 | /* Sanity check MAC address */ |
612 | if (is_valid_ether_addr(efx->mac_address)) { | 649 | if (is_valid_ether_addr(efx->mac_address)) { |
613 | memcpy(efx->net_dev->dev_addr, efx->mac_address, ETH_ALEN); | 650 | memcpy(efx->net_dev->dev_addr, efx->mac_address, ETH_ALEN); |
614 | } else { | 651 | } else { |
615 | DECLARE_MAC_BUF(mac); | 652 | EFX_ERR(efx, "invalid MAC address %pM\n", |
616 | 653 | efx->mac_address); | |
617 | EFX_ERR(efx, "invalid MAC address %s\n", | ||
618 | print_mac(mac, efx->mac_address)); | ||
619 | if (!allow_bad_hwaddr) { | 654 | if (!allow_bad_hwaddr) { |
620 | rc = -EINVAL; | 655 | rc = -EINVAL; |
621 | goto err; | 656 | goto err; |
622 | } | 657 | } |
623 | random_ether_addr(efx->net_dev->dev_addr); | 658 | random_ether_addr(efx->net_dev->dev_addr); |
624 | EFX_INFO(efx, "using locally-generated MAC %s\n", | 659 | EFX_INFO(efx, "using locally-generated MAC %pM\n", |
625 | print_mac(mac, efx->net_dev->dev_addr)); | 660 | efx->net_dev->dev_addr); |
626 | } | 661 | } |
627 | 662 | ||
628 | return 0; | 663 | return 0; |
@@ -638,23 +673,29 @@ static int efx_init_port(struct efx_nic *efx) | |||
638 | 673 | ||
639 | EFX_LOG(efx, "init port\n"); | 674 | EFX_LOG(efx, "init port\n"); |
640 | 675 | ||
641 | /* Initialise the MAC and PHY */ | 676 | rc = efx->phy_op->init(efx); |
642 | rc = falcon_init_xmac(efx); | ||
643 | if (rc) | 677 | if (rc) |
644 | return rc; | 678 | return rc; |
679 | mutex_lock(&efx->mac_lock); | ||
680 | efx->phy_op->reconfigure(efx); | ||
681 | rc = falcon_switch_mac(efx); | ||
682 | mutex_unlock(&efx->mac_lock); | ||
683 | if (rc) | ||
684 | goto fail; | ||
685 | efx->mac_op->reconfigure(efx); | ||
645 | 686 | ||
646 | efx->port_initialized = true; | 687 | efx->port_initialized = true; |
647 | efx->stats_enabled = true; | 688 | efx_stats_enable(efx); |
648 | |||
649 | /* Reconfigure port to program MAC registers */ | ||
650 | falcon_reconfigure_xmac(efx); | ||
651 | |||
652 | return 0; | 689 | return 0; |
690 | |||
691 | fail: | ||
692 | efx->phy_op->fini(efx); | ||
693 | return rc; | ||
653 | } | 694 | } |
654 | 695 | ||
655 | /* Allow efx_reconfigure_port() to be scheduled, and close the window | 696 | /* Allow efx_reconfigure_port() to be scheduled, and close the window |
656 | * between efx_stop_port and efx_flush_all whereby a previously scheduled | 697 | * between efx_stop_port and efx_flush_all whereby a previously scheduled |
657 | * efx_reconfigure_port() may have been cancelled */ | 698 | * efx_phy_work()/efx_mac_work() may have been cancelled */ |
658 | static void efx_start_port(struct efx_nic *efx) | 699 | static void efx_start_port(struct efx_nic *efx) |
659 | { | 700 | { |
660 | EFX_LOG(efx, "start port\n"); | 701 | EFX_LOG(efx, "start port\n"); |
@@ -663,13 +704,14 @@ static void efx_start_port(struct efx_nic *efx) | |||
663 | mutex_lock(&efx->mac_lock); | 704 | mutex_lock(&efx->mac_lock); |
664 | efx->port_enabled = true; | 705 | efx->port_enabled = true; |
665 | __efx_reconfigure_port(efx); | 706 | __efx_reconfigure_port(efx); |
707 | efx->mac_op->irq(efx); | ||
666 | mutex_unlock(&efx->mac_lock); | 708 | mutex_unlock(&efx->mac_lock); |
667 | } | 709 | } |
668 | 710 | ||
669 | /* Prevent efx_reconfigure_work and efx_monitor() from executing, and | 711 | /* Prevent efx_phy_work, efx_mac_work, and efx_monitor() from executing, |
670 | * efx_set_multicast_list() from scheduling efx_reconfigure_work. | 712 | * and efx_set_multicast_list() from scheduling efx_phy_work. efx_phy_work |
671 | * efx_reconfigure_work can still be scheduled via NAPI processing | 713 | * and efx_mac_work may still be scheduled via NAPI processing until |
672 | * until efx_flush_all() is called */ | 714 | * efx_flush_all() is called */ |
673 | static void efx_stop_port(struct efx_nic *efx) | 715 | static void efx_stop_port(struct efx_nic *efx) |
674 | { | 716 | { |
675 | EFX_LOG(efx, "stop port\n"); | 717 | EFX_LOG(efx, "stop port\n"); |
@@ -692,7 +734,8 @@ static void efx_fini_port(struct efx_nic *efx) | |||
692 | if (!efx->port_initialized) | 734 | if (!efx->port_initialized) |
693 | return; | 735 | return; |
694 | 736 | ||
695 | falcon_fini_xmac(efx); | 737 | efx_stats_disable(efx); |
738 | efx->phy_op->fini(efx); | ||
696 | efx->port_initialized = false; | 739 | efx->port_initialized = false; |
697 | 740 | ||
698 | efx->link_up = false; | 741 | efx->link_up = false; |
@@ -811,20 +854,27 @@ static void efx_fini_io(struct efx_nic *efx) | |||
811 | * interrupts across them. */ | 854 | * interrupts across them. */ |
812 | static int efx_wanted_rx_queues(void) | 855 | static int efx_wanted_rx_queues(void) |
813 | { | 856 | { |
814 | cpumask_t core_mask; | 857 | cpumask_var_t core_mask; |
815 | int count; | 858 | int count; |
816 | int cpu; | 859 | int cpu; |
817 | 860 | ||
818 | cpus_clear(core_mask); | 861 | if (!alloc_cpumask_var(&core_mask, GFP_KERNEL)) { |
862 | printk(KERN_WARNING | ||
863 | "efx.c: allocation failure, irq balancing hobbled\n"); | ||
864 | return 1; | ||
865 | } | ||
866 | |||
867 | cpumask_clear(core_mask); | ||
819 | count = 0; | 868 | count = 0; |
820 | for_each_online_cpu(cpu) { | 869 | for_each_online_cpu(cpu) { |
821 | if (!cpu_isset(cpu, core_mask)) { | 870 | if (!cpumask_test_cpu(cpu, core_mask)) { |
822 | ++count; | 871 | ++count; |
823 | cpus_or(core_mask, core_mask, | 872 | cpumask_or(core_mask, core_mask, |
824 | topology_core_siblings(cpu)); | 873 | topology_core_cpumask(cpu)); |
825 | } | 874 | } |
826 | } | 875 | } |
827 | 876 | ||
877 | free_cpumask_var(core_mask); | ||
828 | return count; | 878 | return count; |
829 | } | 879 | } |
830 | 880 | ||
@@ -840,26 +890,33 @@ static void efx_probe_interrupts(struct efx_nic *efx) | |||
840 | if (efx->interrupt_mode == EFX_INT_MODE_MSIX) { | 890 | if (efx->interrupt_mode == EFX_INT_MODE_MSIX) { |
841 | struct msix_entry xentries[EFX_MAX_CHANNELS]; | 891 | struct msix_entry xentries[EFX_MAX_CHANNELS]; |
842 | int wanted_ints; | 892 | int wanted_ints; |
893 | int rx_queues; | ||
843 | 894 | ||
844 | /* We want one RX queue and interrupt per CPU package | 895 | /* We want one RX queue and interrupt per CPU package |
845 | * (or as specified by the rss_cpus module parameter). | 896 | * (or as specified by the rss_cpus module parameter). |
846 | * We will need one channel per interrupt. | 897 | * We will need one channel per interrupt. |
847 | */ | 898 | */ |
848 | wanted_ints = rss_cpus ? rss_cpus : efx_wanted_rx_queues(); | 899 | rx_queues = rss_cpus ? rss_cpus : efx_wanted_rx_queues(); |
849 | efx->n_rx_queues = min(wanted_ints, max_channels); | 900 | wanted_ints = rx_queues + (separate_tx_channels ? 1 : 0); |
901 | wanted_ints = min(wanted_ints, max_channels); | ||
850 | 902 | ||
851 | for (i = 0; i < efx->n_rx_queues; i++) | 903 | for (i = 0; i < wanted_ints; i++) |
852 | xentries[i].entry = i; | 904 | xentries[i].entry = i; |
853 | rc = pci_enable_msix(efx->pci_dev, xentries, efx->n_rx_queues); | 905 | rc = pci_enable_msix(efx->pci_dev, xentries, wanted_ints); |
854 | if (rc > 0) { | 906 | if (rc > 0) { |
855 | EFX_BUG_ON_PARANOID(rc >= efx->n_rx_queues); | 907 | EFX_ERR(efx, "WARNING: Insufficient MSI-X vectors" |
856 | efx->n_rx_queues = rc; | 908 | " available (%d < %d).\n", rc, wanted_ints); |
909 | EFX_ERR(efx, "WARNING: Performance may be reduced.\n"); | ||
910 | EFX_BUG_ON_PARANOID(rc >= wanted_ints); | ||
911 | wanted_ints = rc; | ||
857 | rc = pci_enable_msix(efx->pci_dev, xentries, | 912 | rc = pci_enable_msix(efx->pci_dev, xentries, |
858 | efx->n_rx_queues); | 913 | wanted_ints); |
859 | } | 914 | } |
860 | 915 | ||
861 | if (rc == 0) { | 916 | if (rc == 0) { |
862 | for (i = 0; i < efx->n_rx_queues; i++) | 917 | efx->n_rx_queues = min(rx_queues, wanted_ints); |
918 | efx->n_channels = wanted_ints; | ||
919 | for (i = 0; i < wanted_ints; i++) | ||
863 | efx->channel[i].irq = xentries[i].vector; | 920 | efx->channel[i].irq = xentries[i].vector; |
864 | } else { | 921 | } else { |
865 | /* Fall back to single channel MSI */ | 922 | /* Fall back to single channel MSI */ |
@@ -871,6 +928,7 @@ static void efx_probe_interrupts(struct efx_nic *efx) | |||
871 | /* Try single interrupt MSI */ | 928 | /* Try single interrupt MSI */ |
872 | if (efx->interrupt_mode == EFX_INT_MODE_MSI) { | 929 | if (efx->interrupt_mode == EFX_INT_MODE_MSI) { |
873 | efx->n_rx_queues = 1; | 930 | efx->n_rx_queues = 1; |
931 | efx->n_channels = 1; | ||
874 | rc = pci_enable_msi(efx->pci_dev); | 932 | rc = pci_enable_msi(efx->pci_dev); |
875 | if (rc == 0) { | 933 | if (rc == 0) { |
876 | efx->channel[0].irq = efx->pci_dev->irq; | 934 | efx->channel[0].irq = efx->pci_dev->irq; |
@@ -883,6 +941,7 @@ static void efx_probe_interrupts(struct efx_nic *efx) | |||
883 | /* Assume legacy interrupts */ | 941 | /* Assume legacy interrupts */ |
884 | if (efx->interrupt_mode == EFX_INT_MODE_LEGACY) { | 942 | if (efx->interrupt_mode == EFX_INT_MODE_LEGACY) { |
885 | efx->n_rx_queues = 1; | 943 | efx->n_rx_queues = 1; |
944 | efx->n_channels = 1 + (separate_tx_channels ? 1 : 0); | ||
886 | efx->legacy_irq = efx->pci_dev->irq; | 945 | efx->legacy_irq = efx->pci_dev->irq; |
887 | } | 946 | } |
888 | } | 947 | } |
@@ -907,8 +966,8 @@ static void efx_set_channels(struct efx_nic *efx) | |||
907 | struct efx_rx_queue *rx_queue; | 966 | struct efx_rx_queue *rx_queue; |
908 | 967 | ||
909 | efx_for_each_tx_queue(tx_queue, efx) { | 968 | efx_for_each_tx_queue(tx_queue, efx) { |
910 | if (!EFX_INT_MODE_USE_MSI(efx) && separate_tx_and_rx_channels) | 969 | if (separate_tx_channels) |
911 | tx_queue->channel = &efx->channel[1]; | 970 | tx_queue->channel = &efx->channel[efx->n_channels-1]; |
912 | else | 971 | else |
913 | tx_queue->channel = &efx->channel[0]; | 972 | tx_queue->channel = &efx->channel[0]; |
914 | tx_queue->channel->used_flags |= EFX_USED_BY_TX; | 973 | tx_queue->channel->used_flags |= EFX_USED_BY_TX; |
@@ -985,6 +1044,7 @@ static int efx_probe_all(struct efx_nic *efx) | |||
985 | goto fail3; | 1044 | goto fail3; |
986 | } | 1045 | } |
987 | } | 1046 | } |
1047 | efx_set_channel_names(efx); | ||
988 | 1048 | ||
989 | return 0; | 1049 | return 0; |
990 | 1050 | ||
@@ -1050,7 +1110,8 @@ static void efx_flush_all(struct efx_nic *efx) | |||
1050 | cancel_delayed_work_sync(&rx_queue->work); | 1110 | cancel_delayed_work_sync(&rx_queue->work); |
1051 | 1111 | ||
1052 | /* Stop scheduled port reconfigurations */ | 1112 | /* Stop scheduled port reconfigurations */ |
1053 | cancel_work_sync(&efx->reconfigure_work); | 1113 | cancel_work_sync(&efx->mac_work); |
1114 | cancel_work_sync(&efx->phy_work); | ||
1054 | 1115 | ||
1055 | } | 1116 | } |
1056 | 1117 | ||
@@ -1087,7 +1148,7 @@ static void efx_stop_all(struct efx_nic *efx) | |||
1087 | * window to loose phy events */ | 1148 | * window to loose phy events */ |
1088 | efx_stop_port(efx); | 1149 | efx_stop_port(efx); |
1089 | 1150 | ||
1090 | /* Flush reconfigure_work, refill_workqueue, monitor_work */ | 1151 | /* Flush efx_phy_work, efx_mac_work, refill_workqueue, monitor_work */ |
1091 | efx_flush_all(efx); | 1152 | efx_flush_all(efx); |
1092 | 1153 | ||
1093 | /* Isolate the MAC from the TX and RX engines, so that queue | 1154 | /* Isolate the MAC from the TX and RX engines, so that queue |
@@ -1159,36 +1220,31 @@ static void efx_monitor(struct work_struct *data) | |||
1159 | { | 1220 | { |
1160 | struct efx_nic *efx = container_of(data, struct efx_nic, | 1221 | struct efx_nic *efx = container_of(data, struct efx_nic, |
1161 | monitor_work.work); | 1222 | monitor_work.work); |
1162 | int rc = 0; | 1223 | int rc; |
1163 | 1224 | ||
1164 | EFX_TRACE(efx, "hardware monitor executing on CPU %d\n", | 1225 | EFX_TRACE(efx, "hardware monitor executing on CPU %d\n", |
1165 | raw_smp_processor_id()); | 1226 | raw_smp_processor_id()); |
1166 | 1227 | ||
1167 | |||
1168 | /* If the mac_lock is already held then it is likely a port | 1228 | /* If the mac_lock is already held then it is likely a port |
1169 | * reconfiguration is already in place, which will likely do | 1229 | * reconfiguration is already in place, which will likely do |
1170 | * most of the work of check_hw() anyway. */ | 1230 | * most of the work of check_hw() anyway. */ |
1171 | if (!mutex_trylock(&efx->mac_lock)) { | 1231 | if (!mutex_trylock(&efx->mac_lock)) |
1172 | queue_delayed_work(efx->workqueue, &efx->monitor_work, | 1232 | goto out_requeue; |
1173 | efx_monitor_interval); | 1233 | if (!efx->port_enabled) |
1174 | return; | 1234 | goto out_unlock; |
1175 | } | 1235 | rc = efx->board_info.monitor(efx); |
1176 | |||
1177 | if (efx->port_enabled) | ||
1178 | rc = falcon_check_xmac(efx); | ||
1179 | mutex_unlock(&efx->mac_lock); | ||
1180 | |||
1181 | if (rc) { | 1236 | if (rc) { |
1182 | if (monitor_reset) { | 1237 | EFX_ERR(efx, "Board sensor %s; shutting down PHY\n", |
1183 | EFX_ERR(efx, "hardware monitor detected a fault: " | 1238 | (rc == -ERANGE) ? "reported fault" : "failed"); |
1184 | "triggering reset\n"); | 1239 | efx->phy_mode |= PHY_MODE_LOW_POWER; |
1185 | efx_schedule_reset(efx, RESET_TYPE_MONITOR); | 1240 | falcon_sim_phy_event(efx); |
1186 | } else { | ||
1187 | EFX_ERR(efx, "hardware monitor detected a fault, " | ||
1188 | "skipping reset\n"); | ||
1189 | } | ||
1190 | } | 1241 | } |
1242 | efx->phy_op->poll(efx); | ||
1243 | efx->mac_op->poll(efx); | ||
1191 | 1244 | ||
1245 | out_unlock: | ||
1246 | mutex_unlock(&efx->mac_lock); | ||
1247 | out_requeue: | ||
1192 | queue_delayed_work(efx->workqueue, &efx->monitor_work, | 1248 | queue_delayed_work(efx->workqueue, &efx->monitor_work, |
1193 | efx_monitor_interval); | 1249 | efx_monitor_interval); |
1194 | } | 1250 | } |
@@ -1282,6 +1338,8 @@ static int efx_net_open(struct net_device *net_dev) | |||
1282 | EFX_LOG(efx, "opening device %s on CPU %d\n", net_dev->name, | 1338 | EFX_LOG(efx, "opening device %s on CPU %d\n", net_dev->name, |
1283 | raw_smp_processor_id()); | 1339 | raw_smp_processor_id()); |
1284 | 1340 | ||
1341 | if (efx->state == STATE_DISABLED) | ||
1342 | return -EIO; | ||
1285 | if (efx->phy_mode & PHY_MODE_SPECIAL) | 1343 | if (efx->phy_mode & PHY_MODE_SPECIAL) |
1286 | return -EBUSY; | 1344 | return -EBUSY; |
1287 | 1345 | ||
@@ -1300,14 +1358,30 @@ static int efx_net_stop(struct net_device *net_dev) | |||
1300 | EFX_LOG(efx, "closing %s on CPU %d\n", net_dev->name, | 1358 | EFX_LOG(efx, "closing %s on CPU %d\n", net_dev->name, |
1301 | raw_smp_processor_id()); | 1359 | raw_smp_processor_id()); |
1302 | 1360 | ||
1303 | /* Stop the device and flush all the channels */ | 1361 | if (efx->state != STATE_DISABLED) { |
1304 | efx_stop_all(efx); | 1362 | /* Stop the device and flush all the channels */ |
1305 | efx_fini_channels(efx); | 1363 | efx_stop_all(efx); |
1306 | efx_init_channels(efx); | 1364 | efx_fini_channels(efx); |
1365 | efx_init_channels(efx); | ||
1366 | } | ||
1307 | 1367 | ||
1308 | return 0; | 1368 | return 0; |
1309 | } | 1369 | } |
1310 | 1370 | ||
1371 | void efx_stats_disable(struct efx_nic *efx) | ||
1372 | { | ||
1373 | spin_lock(&efx->stats_lock); | ||
1374 | ++efx->stats_disable_count; | ||
1375 | spin_unlock(&efx->stats_lock); | ||
1376 | } | ||
1377 | |||
1378 | void efx_stats_enable(struct efx_nic *efx) | ||
1379 | { | ||
1380 | spin_lock(&efx->stats_lock); | ||
1381 | --efx->stats_disable_count; | ||
1382 | spin_unlock(&efx->stats_lock); | ||
1383 | } | ||
1384 | |||
1311 | /* Context: process, dev_base_lock or RTNL held, non-blocking. */ | 1385 | /* Context: process, dev_base_lock or RTNL held, non-blocking. */ |
1312 | static struct net_device_stats *efx_net_stats(struct net_device *net_dev) | 1386 | static struct net_device_stats *efx_net_stats(struct net_device *net_dev) |
1313 | { | 1387 | { |
@@ -1316,13 +1390,13 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev) | |||
1316 | struct net_device_stats *stats = &net_dev->stats; | 1390 | struct net_device_stats *stats = &net_dev->stats; |
1317 | 1391 | ||
1318 | /* Update stats if possible, but do not wait if another thread | 1392 | /* Update stats if possible, but do not wait if another thread |
1319 | * is updating them (or resetting the NIC); slightly stale | 1393 | * is updating them or if MAC stats fetches are temporarily |
1320 | * stats are acceptable. | 1394 | * disabled; slightly stale stats are acceptable. |
1321 | */ | 1395 | */ |
1322 | if (!spin_trylock(&efx->stats_lock)) | 1396 | if (!spin_trylock(&efx->stats_lock)) |
1323 | return stats; | 1397 | return stats; |
1324 | if (efx->stats_enabled) { | 1398 | if (!efx->stats_disable_count) { |
1325 | falcon_update_stats_xmac(efx); | 1399 | efx->mac_op->update_stats(efx); |
1326 | falcon_update_nic_stats(efx); | 1400 | falcon_update_nic_stats(efx); |
1327 | } | 1401 | } |
1328 | spin_unlock(&efx->stats_lock); | 1402 | spin_unlock(&efx->stats_lock); |
@@ -1360,12 +1434,11 @@ static void efx_watchdog(struct net_device *net_dev) | |||
1360 | { | 1434 | { |
1361 | struct efx_nic *efx = netdev_priv(net_dev); | 1435 | struct efx_nic *efx = netdev_priv(net_dev); |
1362 | 1436 | ||
1363 | EFX_ERR(efx, "TX stuck with stop_count=%d port_enabled=%d: %s\n", | 1437 | EFX_ERR(efx, "TX stuck with stop_count=%d port_enabled=%d:" |
1364 | atomic_read(&efx->netif_stop_count), efx->port_enabled, | 1438 | " resetting channels\n", |
1365 | monitor_reset ? "resetting channels" : "skipping reset"); | 1439 | atomic_read(&efx->netif_stop_count), efx->port_enabled); |
1366 | 1440 | ||
1367 | if (monitor_reset) | 1441 | efx_schedule_reset(efx, RESET_TYPE_TX_WATCHDOG); |
1368 | efx_schedule_reset(efx, RESET_TYPE_MONITOR); | ||
1369 | } | 1442 | } |
1370 | 1443 | ||
1371 | 1444 | ||
@@ -1401,9 +1474,8 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data) | |||
1401 | EFX_ASSERT_RESET_SERIALISED(efx); | 1474 | EFX_ASSERT_RESET_SERIALISED(efx); |
1402 | 1475 | ||
1403 | if (!is_valid_ether_addr(new_addr)) { | 1476 | if (!is_valid_ether_addr(new_addr)) { |
1404 | DECLARE_MAC_BUF(mac); | 1477 | EFX_ERR(efx, "invalid ethernet MAC address requested: %pM\n", |
1405 | EFX_ERR(efx, "invalid ethernet MAC address requested: %s\n", | 1478 | new_addr); |
1406 | print_mac(mac, new_addr)); | ||
1407 | return -EINVAL; | 1479 | return -EINVAL; |
1408 | } | 1480 | } |
1409 | 1481 | ||
@@ -1447,22 +1519,43 @@ static void efx_set_multicast_list(struct net_device *net_dev) | |||
1447 | return; | 1519 | return; |
1448 | 1520 | ||
1449 | if (changed) | 1521 | if (changed) |
1450 | queue_work(efx->workqueue, &efx->reconfigure_work); | 1522 | queue_work(efx->workqueue, &efx->phy_work); |
1451 | 1523 | ||
1452 | /* Create and activate new global multicast hash table */ | 1524 | /* Create and activate new global multicast hash table */ |
1453 | falcon_set_multicast_hash(efx); | 1525 | falcon_set_multicast_hash(efx); |
1454 | } | 1526 | } |
1455 | 1527 | ||
1528 | static const struct net_device_ops efx_netdev_ops = { | ||
1529 | .ndo_open = efx_net_open, | ||
1530 | .ndo_stop = efx_net_stop, | ||
1531 | .ndo_get_stats = efx_net_stats, | ||
1532 | .ndo_tx_timeout = efx_watchdog, | ||
1533 | .ndo_start_xmit = efx_hard_start_xmit, | ||
1534 | .ndo_validate_addr = eth_validate_addr, | ||
1535 | .ndo_do_ioctl = efx_ioctl, | ||
1536 | .ndo_change_mtu = efx_change_mtu, | ||
1537 | .ndo_set_mac_address = efx_set_mac_address, | ||
1538 | .ndo_set_multicast_list = efx_set_multicast_list, | ||
1539 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1540 | .ndo_poll_controller = efx_netpoll, | ||
1541 | #endif | ||
1542 | }; | ||
1543 | |||
1544 | static void efx_update_name(struct efx_nic *efx) | ||
1545 | { | ||
1546 | strcpy(efx->name, efx->net_dev->name); | ||
1547 | efx_mtd_rename(efx); | ||
1548 | efx_set_channel_names(efx); | ||
1549 | } | ||
1550 | |||
1456 | static int efx_netdev_event(struct notifier_block *this, | 1551 | static int efx_netdev_event(struct notifier_block *this, |
1457 | unsigned long event, void *ptr) | 1552 | unsigned long event, void *ptr) |
1458 | { | 1553 | { |
1459 | struct net_device *net_dev = ptr; | 1554 | struct net_device *net_dev = ptr; |
1460 | 1555 | ||
1461 | if (net_dev->open == efx_net_open && event == NETDEV_CHANGENAME) { | 1556 | if (net_dev->netdev_ops == &efx_netdev_ops && |
1462 | struct efx_nic *efx = netdev_priv(net_dev); | 1557 | event == NETDEV_CHANGENAME) |
1463 | 1558 | efx_update_name(netdev_priv(net_dev)); | |
1464 | strcpy(efx->name, net_dev->name); | ||
1465 | } | ||
1466 | 1559 | ||
1467 | return NOTIFY_DONE; | 1560 | return NOTIFY_DONE; |
1468 | } | 1561 | } |
@@ -1471,6 +1564,14 @@ static struct notifier_block efx_netdev_notifier = { | |||
1471 | .notifier_call = efx_netdev_event, | 1564 | .notifier_call = efx_netdev_event, |
1472 | }; | 1565 | }; |
1473 | 1566 | ||
1567 | static ssize_t | ||
1568 | show_phy_type(struct device *dev, struct device_attribute *attr, char *buf) | ||
1569 | { | ||
1570 | struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); | ||
1571 | return sprintf(buf, "%d\n", efx->phy_type); | ||
1572 | } | ||
1573 | static DEVICE_ATTR(phy_type, 0644, show_phy_type, NULL); | ||
1574 | |||
1474 | static int efx_register_netdev(struct efx_nic *efx) | 1575 | static int efx_register_netdev(struct efx_nic *efx) |
1475 | { | 1576 | { |
1476 | struct net_device *net_dev = efx->net_dev; | 1577 | struct net_device *net_dev = efx->net_dev; |
@@ -1478,18 +1579,7 @@ static int efx_register_netdev(struct efx_nic *efx) | |||
1478 | 1579 | ||
1479 | net_dev->watchdog_timeo = 5 * HZ; | 1580 | net_dev->watchdog_timeo = 5 * HZ; |
1480 | net_dev->irq = efx->pci_dev->irq; | 1581 | net_dev->irq = efx->pci_dev->irq; |
1481 | net_dev->open = efx_net_open; | 1582 | net_dev->netdev_ops = &efx_netdev_ops; |
1482 | net_dev->stop = efx_net_stop; | ||
1483 | net_dev->get_stats = efx_net_stats; | ||
1484 | net_dev->tx_timeout = &efx_watchdog; | ||
1485 | net_dev->hard_start_xmit = efx_hard_start_xmit; | ||
1486 | net_dev->do_ioctl = efx_ioctl; | ||
1487 | net_dev->change_mtu = efx_change_mtu; | ||
1488 | net_dev->set_mac_address = efx_set_mac_address; | ||
1489 | net_dev->set_multicast_list = efx_set_multicast_list; | ||
1490 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1491 | net_dev->poll_controller = efx_netpoll; | ||
1492 | #endif | ||
1493 | SET_NETDEV_DEV(net_dev, &efx->pci_dev->dev); | 1583 | SET_NETDEV_DEV(net_dev, &efx->pci_dev->dev); |
1494 | SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops); | 1584 | SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops); |
1495 | 1585 | ||
@@ -1497,7 +1587,7 @@ static int efx_register_netdev(struct efx_nic *efx) | |||
1497 | netif_carrier_off(efx->net_dev); | 1587 | netif_carrier_off(efx->net_dev); |
1498 | 1588 | ||
1499 | /* Clear MAC statistics */ | 1589 | /* Clear MAC statistics */ |
1500 | falcon_update_stats_xmac(efx); | 1590 | efx->mac_op->update_stats(efx); |
1501 | memset(&efx->mac_stats, 0, sizeof(efx->mac_stats)); | 1591 | memset(&efx->mac_stats, 0, sizeof(efx->mac_stats)); |
1502 | 1592 | ||
1503 | rc = register_netdev(net_dev); | 1593 | rc = register_netdev(net_dev); |
@@ -1505,9 +1595,22 @@ static int efx_register_netdev(struct efx_nic *efx) | |||
1505 | EFX_ERR(efx, "could not register net dev\n"); | 1595 | EFX_ERR(efx, "could not register net dev\n"); |
1506 | return rc; | 1596 | return rc; |
1507 | } | 1597 | } |
1508 | strcpy(efx->name, net_dev->name); | 1598 | |
1599 | rtnl_lock(); | ||
1600 | efx_update_name(efx); | ||
1601 | rtnl_unlock(); | ||
1602 | |||
1603 | rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_type); | ||
1604 | if (rc) { | ||
1605 | EFX_ERR(efx, "failed to init net dev attributes\n"); | ||
1606 | goto fail_registered; | ||
1607 | } | ||
1509 | 1608 | ||
1510 | return 0; | 1609 | return 0; |
1610 | |||
1611 | fail_registered: | ||
1612 | unregister_netdev(net_dev); | ||
1613 | return rc; | ||
1511 | } | 1614 | } |
1512 | 1615 | ||
1513 | static void efx_unregister_netdev(struct efx_nic *efx) | 1616 | static void efx_unregister_netdev(struct efx_nic *efx) |
@@ -1527,6 +1630,7 @@ static void efx_unregister_netdev(struct efx_nic *efx) | |||
1527 | 1630 | ||
1528 | if (efx_dev_registered(efx)) { | 1631 | if (efx_dev_registered(efx)) { |
1529 | strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); | 1632 | strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); |
1633 | device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); | ||
1530 | unregister_netdev(efx->net_dev); | 1634 | unregister_netdev(efx->net_dev); |
1531 | } | 1635 | } |
1532 | } | 1636 | } |
@@ -1539,26 +1643,21 @@ static void efx_unregister_netdev(struct efx_nic *efx) | |||
1539 | 1643 | ||
1540 | /* Tears down the entire software state and most of the hardware state | 1644 | /* Tears down the entire software state and most of the hardware state |
1541 | * before reset. */ | 1645 | * before reset. */ |
1542 | void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) | 1646 | void efx_reset_down(struct efx_nic *efx, enum reset_type method, |
1647 | struct ethtool_cmd *ecmd) | ||
1543 | { | 1648 | { |
1544 | int rc; | ||
1545 | |||
1546 | EFX_ASSERT_RESET_SERIALISED(efx); | 1649 | EFX_ASSERT_RESET_SERIALISED(efx); |
1547 | 1650 | ||
1548 | /* The net_dev->get_stats handler is quite slow, and will fail | 1651 | efx_stats_disable(efx); |
1549 | * if a fetch is pending over reset. Serialise against it. */ | ||
1550 | spin_lock(&efx->stats_lock); | ||
1551 | efx->stats_enabled = false; | ||
1552 | spin_unlock(&efx->stats_lock); | ||
1553 | |||
1554 | efx_stop_all(efx); | 1652 | efx_stop_all(efx); |
1555 | mutex_lock(&efx->mac_lock); | 1653 | mutex_lock(&efx->mac_lock); |
1654 | mutex_lock(&efx->spi_lock); | ||
1556 | 1655 | ||
1557 | rc = falcon_xmac_get_settings(efx, ecmd); | 1656 | efx->phy_op->get_settings(efx, ecmd); |
1558 | if (rc) | ||
1559 | EFX_ERR(efx, "could not back up PHY settings\n"); | ||
1560 | 1657 | ||
1561 | efx_fini_channels(efx); | 1658 | efx_fini_channels(efx); |
1659 | if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) | ||
1660 | efx->phy_op->fini(efx); | ||
1562 | } | 1661 | } |
1563 | 1662 | ||
1564 | /* This function will always ensure that the locks acquired in | 1663 | /* This function will always ensure that the locks acquired in |
@@ -1566,7 +1665,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) | |||
1566 | * that we were unable to reinitialise the hardware, and the | 1665 | * that we were unable to reinitialise the hardware, and the |
1567 | * driver should be disabled. If ok is false, then the rx and tx | 1666 | * driver should be disabled. If ok is false, then the rx and tx |
1568 | * engines are not restarted, pending a RESET_DISABLE. */ | 1667 | * engines are not restarted, pending a RESET_DISABLE. */ |
1569 | int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok) | 1668 | int efx_reset_up(struct efx_nic *efx, enum reset_type method, |
1669 | struct ethtool_cmd *ecmd, bool ok) | ||
1570 | { | 1670 | { |
1571 | int rc; | 1671 | int rc; |
1572 | 1672 | ||
@@ -1578,18 +1678,28 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok) | |||
1578 | ok = false; | 1678 | ok = false; |
1579 | } | 1679 | } |
1580 | 1680 | ||
1681 | if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) { | ||
1682 | if (ok) { | ||
1683 | rc = efx->phy_op->init(efx); | ||
1684 | if (rc) | ||
1685 | ok = false; | ||
1686 | } else | ||
1687 | efx->port_initialized = false; | ||
1688 | } | ||
1689 | |||
1581 | if (ok) { | 1690 | if (ok) { |
1582 | efx_init_channels(efx); | 1691 | efx_init_channels(efx); |
1583 | 1692 | ||
1584 | if (falcon_xmac_set_settings(efx, ecmd)) | 1693 | if (efx->phy_op->set_settings(efx, ecmd)) |
1585 | EFX_ERR(efx, "could not restore PHY settings\n"); | 1694 | EFX_ERR(efx, "could not restore PHY settings\n"); |
1586 | } | 1695 | } |
1587 | 1696 | ||
1697 | mutex_unlock(&efx->spi_lock); | ||
1588 | mutex_unlock(&efx->mac_lock); | 1698 | mutex_unlock(&efx->mac_lock); |
1589 | 1699 | ||
1590 | if (ok) { | 1700 | if (ok) { |
1591 | efx_start_all(efx); | 1701 | efx_start_all(efx); |
1592 | efx->stats_enabled = true; | 1702 | efx_stats_enable(efx); |
1593 | } | 1703 | } |
1594 | return rc; | 1704 | return rc; |
1595 | } | 1705 | } |
@@ -1607,7 +1717,7 @@ static int efx_reset(struct efx_nic *efx) | |||
1607 | { | 1717 | { |
1608 | struct ethtool_cmd ecmd; | 1718 | struct ethtool_cmd ecmd; |
1609 | enum reset_type method = efx->reset_pending; | 1719 | enum reset_type method = efx->reset_pending; |
1610 | int rc; | 1720 | int rc = 0; |
1611 | 1721 | ||
1612 | /* Serialise with kernel interfaces */ | 1722 | /* Serialise with kernel interfaces */ |
1613 | rtnl_lock(); | 1723 | rtnl_lock(); |
@@ -1616,17 +1726,17 @@ static int efx_reset(struct efx_nic *efx) | |||
1616 | * flag set so that efx_pci_probe_main will be retried */ | 1726 | * flag set so that efx_pci_probe_main will be retried */ |
1617 | if (efx->state != STATE_RUNNING) { | 1727 | if (efx->state != STATE_RUNNING) { |
1618 | EFX_INFO(efx, "scheduled reset quenched. NIC not RUNNING\n"); | 1728 | EFX_INFO(efx, "scheduled reset quenched. NIC not RUNNING\n"); |
1619 | goto unlock_rtnl; | 1729 | goto out_unlock; |
1620 | } | 1730 | } |
1621 | 1731 | ||
1622 | EFX_INFO(efx, "resetting (%d)\n", method); | 1732 | EFX_INFO(efx, "resetting (%d)\n", method); |
1623 | 1733 | ||
1624 | efx_reset_down(efx, &ecmd); | 1734 | efx_reset_down(efx, method, &ecmd); |
1625 | 1735 | ||
1626 | rc = falcon_reset_hw(efx, method); | 1736 | rc = falcon_reset_hw(efx, method); |
1627 | if (rc) { | 1737 | if (rc) { |
1628 | EFX_ERR(efx, "failed to reset hardware\n"); | 1738 | EFX_ERR(efx, "failed to reset hardware\n"); |
1629 | goto fail; | 1739 | goto out_disable; |
1630 | } | 1740 | } |
1631 | 1741 | ||
1632 | /* Allow resets to be rescheduled. */ | 1742 | /* Allow resets to be rescheduled. */ |
@@ -1640,28 +1750,23 @@ static int efx_reset(struct efx_nic *efx) | |||
1640 | 1750 | ||
1641 | /* Leave device stopped if necessary */ | 1751 | /* Leave device stopped if necessary */ |
1642 | if (method == RESET_TYPE_DISABLE) { | 1752 | if (method == RESET_TYPE_DISABLE) { |
1753 | efx_reset_up(efx, method, &ecmd, false); | ||
1643 | rc = -EIO; | 1754 | rc = -EIO; |
1644 | goto fail; | 1755 | } else { |
1756 | rc = efx_reset_up(efx, method, &ecmd, true); | ||
1645 | } | 1757 | } |
1646 | 1758 | ||
1647 | rc = efx_reset_up(efx, &ecmd, true); | 1759 | out_disable: |
1648 | if (rc) | 1760 | if (rc) { |
1649 | goto disable; | 1761 | EFX_ERR(efx, "has been disabled\n"); |
1650 | 1762 | efx->state = STATE_DISABLED; | |
1651 | EFX_LOG(efx, "reset complete\n"); | 1763 | dev_close(efx->net_dev); |
1652 | unlock_rtnl: | 1764 | } else { |
1653 | rtnl_unlock(); | 1765 | EFX_LOG(efx, "reset complete\n"); |
1654 | return 0; | 1766 | } |
1655 | |||
1656 | fail: | ||
1657 | efx_reset_up(efx, &ecmd, false); | ||
1658 | disable: | ||
1659 | EFX_ERR(efx, "has been disabled\n"); | ||
1660 | efx->state = STATE_DISABLED; | ||
1661 | 1767 | ||
1768 | out_unlock: | ||
1662 | rtnl_unlock(); | 1769 | rtnl_unlock(); |
1663 | efx_unregister_netdev(efx); | ||
1664 | efx_fini_port(efx); | ||
1665 | return rc; | 1770 | return rc; |
1666 | } | 1771 | } |
1667 | 1772 | ||
@@ -1709,7 +1814,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) | |||
1709 | 1814 | ||
1710 | efx->reset_pending = method; | 1815 | efx->reset_pending = method; |
1711 | 1816 | ||
1712 | queue_work(efx->reset_workqueue, &efx->reset_work); | 1817 | queue_work(reset_workqueue, &efx->reset_work); |
1713 | } | 1818 | } |
1714 | 1819 | ||
1715 | /************************************************************************** | 1820 | /************************************************************************** |
@@ -1743,10 +1848,16 @@ int efx_port_dummy_op_int(struct efx_nic *efx) | |||
1743 | void efx_port_dummy_op_void(struct efx_nic *efx) {} | 1848 | void efx_port_dummy_op_void(struct efx_nic *efx) {} |
1744 | void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {} | 1849 | void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {} |
1745 | 1850 | ||
1851 | static struct efx_mac_operations efx_dummy_mac_operations = { | ||
1852 | .reconfigure = efx_port_dummy_op_void, | ||
1853 | .poll = efx_port_dummy_op_void, | ||
1854 | .irq = efx_port_dummy_op_void, | ||
1855 | }; | ||
1856 | |||
1746 | static struct efx_phy_operations efx_dummy_phy_operations = { | 1857 | static struct efx_phy_operations efx_dummy_phy_operations = { |
1747 | .init = efx_port_dummy_op_int, | 1858 | .init = efx_port_dummy_op_int, |
1748 | .reconfigure = efx_port_dummy_op_void, | 1859 | .reconfigure = efx_port_dummy_op_void, |
1749 | .check_hw = efx_port_dummy_op_int, | 1860 | .poll = efx_port_dummy_op_void, |
1750 | .fini = efx_port_dummy_op_void, | 1861 | .fini = efx_port_dummy_op_void, |
1751 | .clear_interrupt = efx_port_dummy_op_void, | 1862 | .clear_interrupt = efx_port_dummy_op_void, |
1752 | }; | 1863 | }; |
@@ -1755,6 +1866,7 @@ static struct efx_board efx_dummy_board_info = { | |||
1755 | .init = efx_port_dummy_op_int, | 1866 | .init = efx_port_dummy_op_int, |
1756 | .init_leds = efx_port_dummy_op_int, | 1867 | .init_leds = efx_port_dummy_op_int, |
1757 | .set_fault_led = efx_port_dummy_op_blink, | 1868 | .set_fault_led = efx_port_dummy_op_blink, |
1869 | .monitor = efx_port_dummy_op_int, | ||
1758 | .blink = efx_port_dummy_op_blink, | 1870 | .blink = efx_port_dummy_op_blink, |
1759 | .fini = efx_port_dummy_op_void, | 1871 | .fini = efx_port_dummy_op_void, |
1760 | }; | 1872 | }; |
@@ -1774,12 +1886,13 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, | |||
1774 | struct efx_channel *channel; | 1886 | struct efx_channel *channel; |
1775 | struct efx_tx_queue *tx_queue; | 1887 | struct efx_tx_queue *tx_queue; |
1776 | struct efx_rx_queue *rx_queue; | 1888 | struct efx_rx_queue *rx_queue; |
1777 | int i, rc; | 1889 | int i; |
1778 | 1890 | ||
1779 | /* Initialise common structures */ | 1891 | /* Initialise common structures */ |
1780 | memset(efx, 0, sizeof(*efx)); | 1892 | memset(efx, 0, sizeof(*efx)); |
1781 | spin_lock_init(&efx->biu_lock); | 1893 | spin_lock_init(&efx->biu_lock); |
1782 | spin_lock_init(&efx->phy_lock); | 1894 | spin_lock_init(&efx->phy_lock); |
1895 | mutex_init(&efx->spi_lock); | ||
1783 | INIT_WORK(&efx->reset_work, efx_reset_work); | 1896 | INIT_WORK(&efx->reset_work, efx_reset_work); |
1784 | INIT_DELAYED_WORK(&efx->monitor_work, efx_monitor); | 1897 | INIT_DELAYED_WORK(&efx->monitor_work, efx_monitor); |
1785 | efx->pci_dev = pci_dev; | 1898 | efx->pci_dev = pci_dev; |
@@ -1792,10 +1905,13 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, | |||
1792 | efx->rx_checksum_enabled = true; | 1905 | efx->rx_checksum_enabled = true; |
1793 | spin_lock_init(&efx->netif_stop_lock); | 1906 | spin_lock_init(&efx->netif_stop_lock); |
1794 | spin_lock_init(&efx->stats_lock); | 1907 | spin_lock_init(&efx->stats_lock); |
1908 | efx->stats_disable_count = 1; | ||
1795 | mutex_init(&efx->mac_lock); | 1909 | mutex_init(&efx->mac_lock); |
1910 | efx->mac_op = &efx_dummy_mac_operations; | ||
1796 | efx->phy_op = &efx_dummy_phy_operations; | 1911 | efx->phy_op = &efx_dummy_phy_operations; |
1797 | efx->mii.dev = net_dev; | 1912 | efx->mii.dev = net_dev; |
1798 | INIT_WORK(&efx->reconfigure_work, efx_reconfigure_work); | 1913 | INIT_WORK(&efx->phy_work, efx_phy_work); |
1914 | INIT_WORK(&efx->mac_work, efx_mac_work); | ||
1799 | atomic_set(&efx->netif_stop_count, 1); | 1915 | atomic_set(&efx->netif_stop_count, 1); |
1800 | 1916 | ||
1801 | for (i = 0; i < EFX_MAX_CHANNELS; i++) { | 1917 | for (i = 0; i < EFX_MAX_CHANNELS; i++) { |
@@ -1841,34 +1957,18 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, | |||
1841 | efx->interrupt_mode = max(efx->type->max_interrupt_mode, | 1957 | efx->interrupt_mode = max(efx->type->max_interrupt_mode, |
1842 | interrupt_mode); | 1958 | interrupt_mode); |
1843 | 1959 | ||
1844 | efx->workqueue = create_singlethread_workqueue("sfc_work"); | 1960 | /* Would be good to use the net_dev name, but we're too early */ |
1845 | if (!efx->workqueue) { | 1961 | snprintf(efx->workqueue_name, sizeof(efx->workqueue_name), "sfc%s", |
1846 | rc = -ENOMEM; | 1962 | pci_name(pci_dev)); |
1847 | goto fail1; | 1963 | efx->workqueue = create_singlethread_workqueue(efx->workqueue_name); |
1848 | } | 1964 | if (!efx->workqueue) |
1849 | 1965 | return -ENOMEM; | |
1850 | efx->reset_workqueue = create_singlethread_workqueue("sfc_reset"); | ||
1851 | if (!efx->reset_workqueue) { | ||
1852 | rc = -ENOMEM; | ||
1853 | goto fail2; | ||
1854 | } | ||
1855 | 1966 | ||
1856 | return 0; | 1967 | return 0; |
1857 | |||
1858 | fail2: | ||
1859 | destroy_workqueue(efx->workqueue); | ||
1860 | efx->workqueue = NULL; | ||
1861 | |||
1862 | fail1: | ||
1863 | return rc; | ||
1864 | } | 1968 | } |
1865 | 1969 | ||
1866 | static void efx_fini_struct(struct efx_nic *efx) | 1970 | static void efx_fini_struct(struct efx_nic *efx) |
1867 | { | 1971 | { |
1868 | if (efx->reset_workqueue) { | ||
1869 | destroy_workqueue(efx->reset_workqueue); | ||
1870 | efx->reset_workqueue = NULL; | ||
1871 | } | ||
1872 | if (efx->workqueue) { | 1972 | if (efx->workqueue) { |
1873 | destroy_workqueue(efx->workqueue); | 1973 | destroy_workqueue(efx->workqueue); |
1874 | efx->workqueue = NULL; | 1974 | efx->workqueue = NULL; |
@@ -1927,11 +2027,13 @@ static void efx_pci_remove(struct pci_dev *pci_dev) | |||
1927 | 2027 | ||
1928 | efx_unregister_netdev(efx); | 2028 | efx_unregister_netdev(efx); |
1929 | 2029 | ||
2030 | efx_mtd_remove(efx); | ||
2031 | |||
1930 | /* Wait for any scheduled resets to complete. No more will be | 2032 | /* Wait for any scheduled resets to complete. No more will be |
1931 | * scheduled from this point because efx_stop_all() has been | 2033 | * scheduled from this point because efx_stop_all() has been |
1932 | * called, we are no longer registered with driverlink, and | 2034 | * called, we are no longer registered with driverlink, and |
1933 | * the net_device's have been removed. */ | 2035 | * the net_device's have been removed. */ |
1934 | flush_workqueue(efx->reset_workqueue); | 2036 | cancel_work_sync(&efx->reset_work); |
1935 | 2037 | ||
1936 | efx_pci_remove_main(efx); | 2038 | efx_pci_remove_main(efx); |
1937 | 2039 | ||
@@ -1992,6 +2094,7 @@ static int efx_pci_probe_main(struct efx_nic *efx) | |||
1992 | efx_fini_port(efx); | 2094 | efx_fini_port(efx); |
1993 | fail5: | 2095 | fail5: |
1994 | fail4: | 2096 | fail4: |
2097 | efx->board_info.fini(efx); | ||
1995 | fail3: | 2098 | fail3: |
1996 | efx_fini_napi(efx); | 2099 | efx_fini_napi(efx); |
1997 | fail2: | 2100 | fail2: |
@@ -2045,14 +2148,23 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, | |||
2045 | * we're in STATE_INIT. */ | 2148 | * we're in STATE_INIT. */ |
2046 | for (i = 0; i < 5; i++) { | 2149 | for (i = 0; i < 5; i++) { |
2047 | rc = efx_pci_probe_main(efx); | 2150 | rc = efx_pci_probe_main(efx); |
2048 | if (rc == 0) | ||
2049 | break; | ||
2050 | 2151 | ||
2051 | /* Serialise against efx_reset(). No more resets will be | 2152 | /* Serialise against efx_reset(). No more resets will be |
2052 | * scheduled since efx_stop_all() has been called, and we | 2153 | * scheduled since efx_stop_all() has been called, and we |
2053 | * have not and never have been registered with either | 2154 | * have not and never have been registered with either |
2054 | * the rtnetlink or driverlink layers. */ | 2155 | * the rtnetlink or driverlink layers. */ |
2055 | flush_workqueue(efx->reset_workqueue); | 2156 | cancel_work_sync(&efx->reset_work); |
2157 | |||
2158 | if (rc == 0) { | ||
2159 | if (efx->reset_pending != RESET_TYPE_NONE) { | ||
2160 | /* If there was a scheduled reset during | ||
2161 | * probe, the NIC is probably hosed anyway */ | ||
2162 | efx_pci_remove_main(efx); | ||
2163 | rc = -EIO; | ||
2164 | } else { | ||
2165 | break; | ||
2166 | } | ||
2167 | } | ||
2056 | 2168 | ||
2057 | /* Retry if a recoverably reset event has been scheduled */ | 2169 | /* Retry if a recoverably reset event has been scheduled */ |
2058 | if ((efx->reset_pending != RESET_TYPE_INVISIBLE) && | 2170 | if ((efx->reset_pending != RESET_TYPE_INVISIBLE) && |
@@ -2070,16 +2182,15 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, | |||
2070 | /* Switch to the running state before we expose the device to | 2182 | /* Switch to the running state before we expose the device to |
2071 | * the OS. This is to ensure that the initial gathering of | 2183 | * the OS. This is to ensure that the initial gathering of |
2072 | * MAC stats succeeds. */ | 2184 | * MAC stats succeeds. */ |
2073 | rtnl_lock(); | ||
2074 | efx->state = STATE_RUNNING; | 2185 | efx->state = STATE_RUNNING; |
2075 | rtnl_unlock(); | 2186 | |
2187 | efx_mtd_probe(efx); /* allowed to fail */ | ||
2076 | 2188 | ||
2077 | rc = efx_register_netdev(efx); | 2189 | rc = efx_register_netdev(efx); |
2078 | if (rc) | 2190 | if (rc) |
2079 | goto fail5; | 2191 | goto fail5; |
2080 | 2192 | ||
2081 | EFX_LOG(efx, "initialisation successful\n"); | 2193 | EFX_LOG(efx, "initialisation successful\n"); |
2082 | |||
2083 | return 0; | 2194 | return 0; |
2084 | 2195 | ||
2085 | fail5: | 2196 | fail5: |
@@ -2127,6 +2238,11 @@ static int __init efx_init_module(void) | |||
2127 | rc = -ENOMEM; | 2238 | rc = -ENOMEM; |
2128 | goto err_refill; | 2239 | goto err_refill; |
2129 | } | 2240 | } |
2241 | reset_workqueue = create_singlethread_workqueue("sfc_reset"); | ||
2242 | if (!reset_workqueue) { | ||
2243 | rc = -ENOMEM; | ||
2244 | goto err_reset; | ||
2245 | } | ||
2130 | 2246 | ||
2131 | rc = pci_register_driver(&efx_pci_driver); | 2247 | rc = pci_register_driver(&efx_pci_driver); |
2132 | if (rc < 0) | 2248 | if (rc < 0) |
@@ -2135,6 +2251,8 @@ static int __init efx_init_module(void) | |||
2135 | return 0; | 2251 | return 0; |
2136 | 2252 | ||
2137 | err_pci: | 2253 | err_pci: |
2254 | destroy_workqueue(reset_workqueue); | ||
2255 | err_reset: | ||
2138 | destroy_workqueue(refill_workqueue); | 2256 | destroy_workqueue(refill_workqueue); |
2139 | err_refill: | 2257 | err_refill: |
2140 | unregister_netdevice_notifier(&efx_netdev_notifier); | 2258 | unregister_netdevice_notifier(&efx_netdev_notifier); |
@@ -2147,6 +2265,7 @@ static void __exit efx_exit_module(void) | |||
2147 | printk(KERN_INFO "Solarflare NET driver unloading\n"); | 2265 | printk(KERN_INFO "Solarflare NET driver unloading\n"); |
2148 | 2266 | ||
2149 | pci_unregister_driver(&efx_pci_driver); | 2267 | pci_unregister_driver(&efx_pci_driver); |
2268 | destroy_workqueue(reset_workqueue); | ||
2150 | destroy_workqueue(refill_workqueue); | 2269 | destroy_workqueue(refill_workqueue); |
2151 | unregister_netdevice_notifier(&efx_netdev_notifier); | 2270 | unregister_netdevice_notifier(&efx_netdev_notifier); |
2152 | 2271 | ||
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index d02937b70eee..55d0f131b0e9 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h | |||
@@ -36,13 +36,16 @@ extern void efx_process_channel_now(struct efx_channel *channel); | |||
36 | extern void efx_flush_queues(struct efx_nic *efx); | 36 | extern void efx_flush_queues(struct efx_nic *efx); |
37 | 37 | ||
38 | /* Ports */ | 38 | /* Ports */ |
39 | extern void efx_stats_disable(struct efx_nic *efx); | ||
40 | extern void efx_stats_enable(struct efx_nic *efx); | ||
39 | extern void efx_reconfigure_port(struct efx_nic *efx); | 41 | extern void efx_reconfigure_port(struct efx_nic *efx); |
40 | extern void __efx_reconfigure_port(struct efx_nic *efx); | 42 | extern void __efx_reconfigure_port(struct efx_nic *efx); |
41 | 43 | ||
42 | /* Reset handling */ | 44 | /* Reset handling */ |
43 | extern void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd); | 45 | extern void efx_reset_down(struct efx_nic *efx, enum reset_type method, |
44 | extern int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, | 46 | struct ethtool_cmd *ecmd); |
45 | bool ok); | 47 | extern int efx_reset_up(struct efx_nic *efx, enum reset_type method, |
48 | struct ethtool_cmd *ecmd, bool ok); | ||
46 | 49 | ||
47 | /* Global */ | 50 | /* Global */ |
48 | extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type); | 51 | extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type); |
@@ -58,6 +61,16 @@ extern int efx_port_dummy_op_int(struct efx_nic *efx); | |||
58 | extern void efx_port_dummy_op_void(struct efx_nic *efx); | 61 | extern void efx_port_dummy_op_void(struct efx_nic *efx); |
59 | extern void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink); | 62 | extern void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink); |
60 | 63 | ||
64 | /* MTD */ | ||
65 | #ifdef CONFIG_SFC_MTD | ||
66 | extern int efx_mtd_probe(struct efx_nic *efx); | ||
67 | extern void efx_mtd_rename(struct efx_nic *efx); | ||
68 | extern void efx_mtd_remove(struct efx_nic *efx); | ||
69 | #else | ||
70 | static inline int efx_mtd_probe(struct efx_nic *efx) { return 0; } | ||
71 | static inline void efx_mtd_rename(struct efx_nic *efx) {} | ||
72 | static inline void efx_mtd_remove(struct efx_nic *efx) {} | ||
73 | #endif | ||
61 | 74 | ||
62 | extern unsigned int efx_monitor_interval; | 75 | extern unsigned int efx_monitor_interval; |
63 | 76 | ||
@@ -67,7 +80,7 @@ static inline void efx_schedule_channel(struct efx_channel *channel) | |||
67 | channel->channel, raw_smp_processor_id()); | 80 | channel->channel, raw_smp_processor_id()); |
68 | channel->work_pending = true; | 81 | channel->work_pending = true; |
69 | 82 | ||
70 | netif_rx_schedule(channel->napi_dev, &channel->napi_str); | 83 | netif_rx_schedule(&channel->napi_str); |
71 | } | 84 | } |
72 | 85 | ||
73 | #endif /* EFX_EFX_H */ | 86 | #endif /* EFX_EFX_H */ |
diff --git a/drivers/net/sfc/enum.h b/drivers/net/sfc/enum.h index cec15dbb88e4..60cbc6e1e66b 100644 --- a/drivers/net/sfc/enum.h +++ b/drivers/net/sfc/enum.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /**************************************************************************** | 1 | /**************************************************************************** |
2 | * Driver for Solarflare Solarstorm network controllers and boards | 2 | * Driver for Solarflare Solarstorm network controllers and boards |
3 | * Copyright 2007 Solarflare Communications Inc. | 3 | * Copyright 2007-2008 Solarflare Communications Inc. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 as published | 6 | * under the terms of the GNU General Public License version 2 as published |
@@ -13,22 +13,24 @@ | |||
13 | /** | 13 | /** |
14 | * enum efx_loopback_mode - loopback modes | 14 | * enum efx_loopback_mode - loopback modes |
15 | * @LOOPBACK_NONE: no loopback | 15 | * @LOOPBACK_NONE: no loopback |
16 | * @LOOPBACK_XGMII: loopback within MAC at XGMII level | 16 | * @LOOPBACK_GMAC: loopback within GMAC at unspecified level |
17 | * @LOOPBACK_XGXS: loopback within MAC at XGXS level | 17 | * @LOOPBACK_XGMII: loopback within XMAC at XGMII level |
18 | * @LOOPBACK_XAUI: loopback within MAC at XAUI level | 18 | * @LOOPBACK_XGXS: loopback within XMAC at XGXS level |
19 | * @LOOPBACK_PHYXS: loopback within PHY at PHYXS level | 19 | * @LOOPBACK_XAUI: loopback within XMAC at XAUI level |
20 | * @LOOPBACK_PCS: loopback within PHY at PCS level | 20 | * @LOOPBACK_GPHY: loopback within 1G PHY at unspecified level |
21 | * @LOOPBACK_PMAPMD: loopback within PHY at PMAPMD level | 21 | * @LOOPBACK_PHYXS: loopback within 10G PHY at PHYXS level |
22 | * @LOOPBACK_PCS: loopback within 10G PHY at PCS level | ||
23 | * @LOOPBACK_PMAPMD: loopback within 10G PHY at PMAPMD level | ||
22 | * @LOOPBACK_NETWORK: reflecting loopback (even further than furthest!) | 24 | * @LOOPBACK_NETWORK: reflecting loopback (even further than furthest!) |
23 | */ | 25 | */ |
24 | /* Please keep in order and up-to-date w.r.t the following two #defines */ | 26 | /* Please keep in order and up-to-date w.r.t the following two #defines */ |
25 | enum efx_loopback_mode { | 27 | enum efx_loopback_mode { |
26 | LOOPBACK_NONE = 0, | 28 | LOOPBACK_NONE = 0, |
27 | LOOPBACK_MAC = 1, | 29 | LOOPBACK_GMAC = 1, |
28 | LOOPBACK_XGMII = 2, | 30 | LOOPBACK_XGMII = 2, |
29 | LOOPBACK_XGXS = 3, | 31 | LOOPBACK_XGXS = 3, |
30 | LOOPBACK_XAUI = 4, | 32 | LOOPBACK_XAUI = 4, |
31 | LOOPBACK_PHY = 5, | 33 | LOOPBACK_GPHY = 5, |
32 | LOOPBACK_PHYXS = 6, | 34 | LOOPBACK_PHYXS = 6, |
33 | LOOPBACK_PCS = 7, | 35 | LOOPBACK_PCS = 7, |
34 | LOOPBACK_PMAPMD = 8, | 36 | LOOPBACK_PMAPMD = 8, |
@@ -45,15 +47,19 @@ extern const char *efx_loopback_mode_names[]; | |||
45 | LOOPBACK_MODE_NAME(efx->loopback_mode) | 47 | LOOPBACK_MODE_NAME(efx->loopback_mode) |
46 | 48 | ||
47 | /* These loopbacks occur within the controller */ | 49 | /* These loopbacks occur within the controller */ |
48 | #define LOOPBACKS_10G_INTERNAL ((1 << LOOPBACK_XGMII)| \ | 50 | #define LOOPBACKS_INTERNAL ((1 << LOOPBACK_GMAC) | \ |
49 | (1 << LOOPBACK_XGXS) | \ | 51 | (1 << LOOPBACK_XGMII)| \ |
50 | (1 << LOOPBACK_XAUI)) | 52 | (1 << LOOPBACK_XGXS) | \ |
53 | (1 << LOOPBACK_XAUI)) | ||
51 | 54 | ||
52 | #define LOOPBACK_MASK(_efx) \ | 55 | #define LOOPBACK_MASK(_efx) \ |
53 | (1 << (_efx)->loopback_mode) | 56 | (1 << (_efx)->loopback_mode) |
54 | 57 | ||
55 | #define LOOPBACK_INTERNAL(_efx) \ | 58 | #define LOOPBACK_INTERNAL(_efx) \ |
56 | (!!(LOOPBACKS_10G_INTERNAL & LOOPBACK_MASK(_efx))) | 59 | (!!(LOOPBACKS_INTERNAL & LOOPBACK_MASK(_efx))) |
60 | |||
61 | #define LOOPBACK_CHANGED(_from, _to, _mask) \ | ||
62 | (!!((LOOPBACK_MASK(_from) ^ LOOPBACK_MASK(_to)) & (_mask))) | ||
57 | 63 | ||
58 | #define LOOPBACK_OUT_OF(_from, _to, _mask) \ | 64 | #define LOOPBACK_OUT_OF(_from, _to, _mask) \ |
59 | ((LOOPBACK_MASK(_from) & (_mask)) && !(LOOPBACK_MASK(_to) & (_mask))) | 65 | ((LOOPBACK_MASK(_from) & (_mask)) && !(LOOPBACK_MASK(_to) & (_mask))) |
@@ -72,7 +78,7 @@ extern const char *efx_loopback_mode_names[]; | |||
72 | * @RESET_TYPE_ALL: reset everything but PCI core blocks | 78 | * @RESET_TYPE_ALL: reset everything but PCI core blocks |
73 | * @RESET_TYPE_WORLD: reset everything, save & restore PCI config | 79 | * @RESET_TYPE_WORLD: reset everything, save & restore PCI config |
74 | * @RESET_TYPE_DISABLE: disable NIC | 80 | * @RESET_TYPE_DISABLE: disable NIC |
75 | * @RESET_TYPE_MONITOR: reset due to hardware monitor | 81 | * @RESET_TYPE_TX_WATCHDOG: reset due to TX watchdog |
76 | * @RESET_TYPE_INT_ERROR: reset due to internal error | 82 | * @RESET_TYPE_INT_ERROR: reset due to internal error |
77 | * @RESET_TYPE_RX_RECOVERY: reset to recover from RX datapath errors | 83 | * @RESET_TYPE_RX_RECOVERY: reset to recover from RX datapath errors |
78 | * @RESET_TYPE_RX_DESC_FETCH: pcie error during rx descriptor fetch | 84 | * @RESET_TYPE_RX_DESC_FETCH: pcie error during rx descriptor fetch |
@@ -86,7 +92,7 @@ enum reset_type { | |||
86 | RESET_TYPE_WORLD = 2, | 92 | RESET_TYPE_WORLD = 2, |
87 | RESET_TYPE_DISABLE = 3, | 93 | RESET_TYPE_DISABLE = 3, |
88 | RESET_TYPE_MAX_METHOD, | 94 | RESET_TYPE_MAX_METHOD, |
89 | RESET_TYPE_MONITOR, | 95 | RESET_TYPE_TX_WATCHDOG, |
90 | RESET_TYPE_INT_ERROR, | 96 | RESET_TYPE_INT_ERROR, |
91 | RESET_TYPE_RX_RECOVERY, | 97 | RESET_TYPE_RX_RECOVERY, |
92 | RESET_TYPE_RX_DESC_FETCH, | 98 | RESET_TYPE_RX_DESC_FETCH, |
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index cd0d0873d978..7b5924c039b3 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
@@ -12,24 +12,24 @@ | |||
12 | #include <linux/ethtool.h> | 12 | #include <linux/ethtool.h> |
13 | #include <linux/rtnetlink.h> | 13 | #include <linux/rtnetlink.h> |
14 | #include "net_driver.h" | 14 | #include "net_driver.h" |
15 | #include "workarounds.h" | ||
15 | #include "selftest.h" | 16 | #include "selftest.h" |
16 | #include "efx.h" | 17 | #include "efx.h" |
17 | #include "ethtool.h" | 18 | #include "ethtool.h" |
18 | #include "falcon.h" | 19 | #include "falcon.h" |
19 | #include "gmii.h" | ||
20 | #include "spi.h" | 20 | #include "spi.h" |
21 | #include "mac.h" | 21 | #include "mdio_10g.h" |
22 | 22 | ||
23 | const char *efx_loopback_mode_names[] = { | 23 | const char *efx_loopback_mode_names[] = { |
24 | [LOOPBACK_NONE] = "NONE", | 24 | [LOOPBACK_NONE] = "NONE", |
25 | [LOOPBACK_MAC] = "MAC", | 25 | [LOOPBACK_GMAC] = "GMAC", |
26 | [LOOPBACK_XGMII] = "XGMII", | 26 | [LOOPBACK_XGMII] = "XGMII", |
27 | [LOOPBACK_XGXS] = "XGXS", | 27 | [LOOPBACK_XGXS] = "XGXS", |
28 | [LOOPBACK_XAUI] = "XAUI", | 28 | [LOOPBACK_XAUI] = "XAUI", |
29 | [LOOPBACK_PHY] = "PHY", | 29 | [LOOPBACK_GPHY] = "GPHY", |
30 | [LOOPBACK_PHYXS] = "PHY(XS)", | 30 | [LOOPBACK_PHYXS] = "PHYXS", |
31 | [LOOPBACK_PCS] = "PHY(PCS)", | 31 | [LOOPBACK_PCS] = "PCS", |
32 | [LOOPBACK_PMAPMD] = "PHY(PMAPMD)", | 32 | [LOOPBACK_PMAPMD] = "PMA/PMD", |
33 | [LOOPBACK_NETWORK] = "NETWORK", | 33 | [LOOPBACK_NETWORK] = "NETWORK", |
34 | }; | 34 | }; |
35 | 35 | ||
@@ -172,10 +172,7 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = { | |||
172 | /* Number of ethtool statistics */ | 172 | /* Number of ethtool statistics */ |
173 | #define EFX_ETHTOOL_NUM_STATS ARRAY_SIZE(efx_ethtool_stats) | 173 | #define EFX_ETHTOOL_NUM_STATS ARRAY_SIZE(efx_ethtool_stats) |
174 | 174 | ||
175 | /* EEPROM range with gPXE configuration */ | ||
176 | #define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB | 175 | #define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB |
177 | #define EFX_ETHTOOL_EEPROM_MIN 0x800U | ||
178 | #define EFX_ETHTOOL_EEPROM_MAX 0x1800U | ||
179 | 176 | ||
180 | /************************************************************************** | 177 | /************************************************************************** |
181 | * | 178 | * |
@@ -185,12 +182,16 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = { | |||
185 | */ | 182 | */ |
186 | 183 | ||
187 | /* Identify device by flashing LEDs */ | 184 | /* Identify device by flashing LEDs */ |
188 | static int efx_ethtool_phys_id(struct net_device *net_dev, u32 seconds) | 185 | static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count) |
189 | { | 186 | { |
190 | struct efx_nic *efx = netdev_priv(net_dev); | 187 | struct efx_nic *efx = netdev_priv(net_dev); |
191 | 188 | ||
192 | efx->board_info.blink(efx, 1); | 189 | efx->board_info.blink(efx, 1); |
193 | schedule_timeout_interruptible(seconds * HZ); | 190 | set_current_state(TASK_INTERRUPTIBLE); |
191 | if (count) | ||
192 | schedule_timeout(count * HZ); | ||
193 | else | ||
194 | schedule(); | ||
194 | efx->board_info.blink(efx, 0); | 195 | efx->board_info.blink(efx, 0); |
195 | return 0; | 196 | return 0; |
196 | } | 197 | } |
@@ -200,13 +201,15 @@ int efx_ethtool_get_settings(struct net_device *net_dev, | |||
200 | struct ethtool_cmd *ecmd) | 201 | struct ethtool_cmd *ecmd) |
201 | { | 202 | { |
202 | struct efx_nic *efx = netdev_priv(net_dev); | 203 | struct efx_nic *efx = netdev_priv(net_dev); |
203 | int rc; | ||
204 | 204 | ||
205 | mutex_lock(&efx->mac_lock); | 205 | mutex_lock(&efx->mac_lock); |
206 | rc = falcon_xmac_get_settings(efx, ecmd); | 206 | efx->phy_op->get_settings(efx, ecmd); |
207 | mutex_unlock(&efx->mac_lock); | 207 | mutex_unlock(&efx->mac_lock); |
208 | 208 | ||
209 | return rc; | 209 | /* Falcon GMAC does not support 1000Mbps HD */ |
210 | ecmd->supported &= ~SUPPORTED_1000baseT_Half; | ||
211 | |||
212 | return 0; | ||
210 | } | 213 | } |
211 | 214 | ||
212 | /* This must be called with rtnl_lock held. */ | 215 | /* This must be called with rtnl_lock held. */ |
@@ -216,8 +219,15 @@ int efx_ethtool_set_settings(struct net_device *net_dev, | |||
216 | struct efx_nic *efx = netdev_priv(net_dev); | 219 | struct efx_nic *efx = netdev_priv(net_dev); |
217 | int rc; | 220 | int rc; |
218 | 221 | ||
222 | /* Falcon GMAC does not support 1000Mbps HD */ | ||
223 | if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { | ||
224 | EFX_LOG(efx, "rejecting unsupported 1000Mbps HD" | ||
225 | " setting\n"); | ||
226 | return -EINVAL; | ||
227 | } | ||
228 | |||
219 | mutex_lock(&efx->mac_lock); | 229 | mutex_lock(&efx->mac_lock); |
220 | rc = falcon_xmac_set_settings(efx, ecmd); | 230 | rc = efx->phy_op->set_settings(efx, ecmd); |
221 | mutex_unlock(&efx->mac_lock); | 231 | mutex_unlock(&efx->mac_lock); |
222 | if (!rc) | 232 | if (!rc) |
223 | efx_reconfigure_port(efx); | 233 | efx_reconfigure_port(efx); |
@@ -241,10 +251,10 @@ static void efx_ethtool_get_drvinfo(struct net_device *net_dev, | |||
241 | * @strings: Ethtool strings, or %NULL | 251 | * @strings: Ethtool strings, or %NULL |
242 | * @data: Ethtool test results, or %NULL | 252 | * @data: Ethtool test results, or %NULL |
243 | * @test: Pointer to test result (used only if data != %NULL) | 253 | * @test: Pointer to test result (used only if data != %NULL) |
244 | * @unit_format: Unit name format (e.g. "channel\%d") | 254 | * @unit_format: Unit name format (e.g. "chan\%d") |
245 | * @unit_id: Unit id (e.g. 0 for "channel0") | 255 | * @unit_id: Unit id (e.g. 0 for "chan0") |
246 | * @test_format: Test name format (e.g. "loopback.\%s.tx.sent") | 256 | * @test_format: Test name format (e.g. "loopback.\%s.tx.sent") |
247 | * @test_id: Test id (e.g. "PHY" for "loopback.PHY.tx_sent") | 257 | * @test_id: Test id (e.g. "PHYXS" for "loopback.PHYXS.tx_sent") |
248 | * | 258 | * |
249 | * Fill in an individual self-test entry. | 259 | * Fill in an individual self-test entry. |
250 | */ | 260 | */ |
@@ -261,18 +271,20 @@ static void efx_fill_test(unsigned int test_index, | |||
261 | 271 | ||
262 | /* Fill string, if applicable */ | 272 | /* Fill string, if applicable */ |
263 | if (strings) { | 273 | if (strings) { |
264 | snprintf(unit_str.name, sizeof(unit_str.name), | 274 | if (strchr(unit_format, '%')) |
265 | unit_format, unit_id); | 275 | snprintf(unit_str.name, sizeof(unit_str.name), |
276 | unit_format, unit_id); | ||
277 | else | ||
278 | strcpy(unit_str.name, unit_format); | ||
266 | snprintf(test_str.name, sizeof(test_str.name), | 279 | snprintf(test_str.name, sizeof(test_str.name), |
267 | test_format, test_id); | 280 | test_format, test_id); |
268 | snprintf(strings[test_index].name, | 281 | snprintf(strings[test_index].name, |
269 | sizeof(strings[test_index].name), | 282 | sizeof(strings[test_index].name), |
270 | "%-9s%-17s", unit_str.name, test_str.name); | 283 | "%-6s %-24s", unit_str.name, test_str.name); |
271 | } | 284 | } |
272 | } | 285 | } |
273 | 286 | ||
274 | #define EFX_PORT_NAME "port%d", 0 | 287 | #define EFX_CHANNEL_NAME(_channel) "chan%d", _channel->channel |
275 | #define EFX_CHANNEL_NAME(_channel) "channel%d", _channel->channel | ||
276 | #define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue | 288 | #define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue |
277 | #define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue | 289 | #define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue |
278 | #define EFX_LOOPBACK_NAME(_mode, _counter) \ | 290 | #define EFX_LOOPBACK_NAME(_mode, _counter) \ |
@@ -307,11 +319,11 @@ static int efx_fill_loopback_test(struct efx_nic *efx, | |||
307 | } | 319 | } |
308 | efx_fill_test(test_index++, strings, data, | 320 | efx_fill_test(test_index++, strings, data, |
309 | &lb_tests->rx_good, | 321 | &lb_tests->rx_good, |
310 | EFX_PORT_NAME, | 322 | "rx", 0, |
311 | EFX_LOOPBACK_NAME(mode, "rx_good")); | 323 | EFX_LOOPBACK_NAME(mode, "rx_good")); |
312 | efx_fill_test(test_index++, strings, data, | 324 | efx_fill_test(test_index++, strings, data, |
313 | &lb_tests->rx_bad, | 325 | &lb_tests->rx_bad, |
314 | EFX_PORT_NAME, | 326 | "rx", 0, |
315 | EFX_LOOPBACK_NAME(mode, "rx_bad")); | 327 | EFX_LOOPBACK_NAME(mode, "rx_bad")); |
316 | 328 | ||
317 | return test_index; | 329 | return test_index; |
@@ -330,7 +342,7 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx, | |||
330 | u64 *data) | 342 | u64 *data) |
331 | { | 343 | { |
332 | struct efx_channel *channel; | 344 | struct efx_channel *channel; |
333 | unsigned int n = 0; | 345 | unsigned int n = 0, i; |
334 | enum efx_loopback_mode mode; | 346 | enum efx_loopback_mode mode; |
335 | 347 | ||
336 | efx_fill_test(n++, strings, data, &tests->mii, | 348 | efx_fill_test(n++, strings, data, &tests->mii, |
@@ -358,14 +370,12 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx, | |||
358 | 370 | ||
359 | efx_fill_test(n++, strings, data, &tests->registers, | 371 | efx_fill_test(n++, strings, data, &tests->registers, |
360 | "core", 0, "registers", NULL); | 372 | "core", 0, "registers", NULL); |
361 | efx_fill_test(n++, strings, data, &tests->phy, | 373 | |
362 | EFX_PORT_NAME, "phy", NULL); | 374 | for (i = 0; i < efx->phy_op->num_tests; i++) |
375 | efx_fill_test(n++, strings, data, &tests->phy[i], | ||
376 | "phy", 0, efx->phy_op->test_names[i], NULL); | ||
363 | 377 | ||
364 | /* Loopback tests */ | 378 | /* Loopback tests */ |
365 | efx_fill_test(n++, strings, data, &tests->loopback_speed, | ||
366 | EFX_PORT_NAME, "loopback.speed", NULL); | ||
367 | efx_fill_test(n++, strings, data, &tests->loopback_full_duplex, | ||
368 | EFX_PORT_NAME, "loopback.full_duplex", NULL); | ||
369 | for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) { | 379 | for (mode = LOOPBACK_NONE; mode <= LOOPBACK_TEST_MAX; mode++) { |
370 | if (!(efx->loopback_modes & (1 << mode))) | 380 | if (!(efx->loopback_modes & (1 << mode))) |
371 | continue; | 381 | continue; |
@@ -429,7 +439,7 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, | |||
429 | EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS); | 439 | EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS); |
430 | 440 | ||
431 | /* Update MAC and NIC statistics */ | 441 | /* Update MAC and NIC statistics */ |
432 | net_dev->get_stats(net_dev); | 442 | dev_get_stats(net_dev); |
433 | 443 | ||
434 | /* Fill detailed statistics buffer */ | 444 | /* Fill detailed statistics buffer */ |
435 | for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) { | 445 | for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) { |
@@ -476,7 +486,7 @@ static void efx_ethtool_self_test(struct net_device *net_dev, | |||
476 | { | 486 | { |
477 | struct efx_nic *efx = netdev_priv(net_dev); | 487 | struct efx_nic *efx = netdev_priv(net_dev); |
478 | struct efx_self_tests efx_tests; | 488 | struct efx_self_tests efx_tests; |
479 | int offline, already_up; | 489 | int already_up; |
480 | int rc; | 490 | int rc; |
481 | 491 | ||
482 | ASSERT_RTNL(); | 492 | ASSERT_RTNL(); |
@@ -496,24 +506,15 @@ static void efx_ethtool_self_test(struct net_device *net_dev, | |||
496 | } | 506 | } |
497 | 507 | ||
498 | memset(&efx_tests, 0, sizeof(efx_tests)); | 508 | memset(&efx_tests, 0, sizeof(efx_tests)); |
499 | offline = (test->flags & ETH_TEST_FL_OFFLINE); | ||
500 | 509 | ||
501 | /* Perform online self tests first */ | 510 | rc = efx_selftest(efx, &efx_tests, test->flags); |
502 | rc = efx_online_test(efx, &efx_tests); | ||
503 | if (rc) | ||
504 | goto out; | ||
505 | |||
506 | /* Perform offline tests only if online tests passed */ | ||
507 | if (offline) | ||
508 | rc = efx_offline_test(efx, &efx_tests, | ||
509 | efx->loopback_modes); | ||
510 | 511 | ||
511 | out: | ||
512 | if (!already_up) | 512 | if (!already_up) |
513 | dev_close(efx->net_dev); | 513 | dev_close(efx->net_dev); |
514 | 514 | ||
515 | EFX_LOG(efx, "%s all %sline self-tests\n", | 515 | EFX_LOG(efx, "%s %sline self-tests\n", |
516 | rc == 0 ? "passed" : "failed", offline ? "off" : "on"); | 516 | rc == 0 ? "passed" : "failed", |
517 | (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); | ||
517 | 518 | ||
518 | fail2: | 519 | fail2: |
519 | fail1: | 520 | fail1: |
@@ -545,8 +546,8 @@ static int efx_ethtool_get_eeprom_len(struct net_device *net_dev) | |||
545 | 546 | ||
546 | if (!spi) | 547 | if (!spi) |
547 | return 0; | 548 | return 0; |
548 | return min(spi->size, EFX_ETHTOOL_EEPROM_MAX) - | 549 | return min(spi->size, EFX_EEPROM_BOOTCONFIG_END) - |
549 | min(spi->size, EFX_ETHTOOL_EEPROM_MIN); | 550 | min(spi->size, EFX_EEPROM_BOOTCONFIG_START); |
550 | } | 551 | } |
551 | 552 | ||
552 | static int efx_ethtool_get_eeprom(struct net_device *net_dev, | 553 | static int efx_ethtool_get_eeprom(struct net_device *net_dev, |
@@ -557,8 +558,13 @@ static int efx_ethtool_get_eeprom(struct net_device *net_dev, | |||
557 | size_t len; | 558 | size_t len; |
558 | int rc; | 559 | int rc; |
559 | 560 | ||
560 | rc = falcon_spi_read(spi, eeprom->offset + EFX_ETHTOOL_EEPROM_MIN, | 561 | rc = mutex_lock_interruptible(&efx->spi_lock); |
562 | if (rc) | ||
563 | return rc; | ||
564 | rc = falcon_spi_read(spi, eeprom->offset + EFX_EEPROM_BOOTCONFIG_START, | ||
561 | eeprom->len, &len, buf); | 565 | eeprom->len, &len, buf); |
566 | mutex_unlock(&efx->spi_lock); | ||
567 | |||
562 | eeprom->magic = EFX_ETHTOOL_EEPROM_MAGIC; | 568 | eeprom->magic = EFX_ETHTOOL_EEPROM_MAGIC; |
563 | eeprom->len = len; | 569 | eeprom->len = len; |
564 | return rc; | 570 | return rc; |
@@ -575,8 +581,13 @@ static int efx_ethtool_set_eeprom(struct net_device *net_dev, | |||
575 | if (eeprom->magic != EFX_ETHTOOL_EEPROM_MAGIC) | 581 | if (eeprom->magic != EFX_ETHTOOL_EEPROM_MAGIC) |
576 | return -EINVAL; | 582 | return -EINVAL; |
577 | 583 | ||
578 | rc = falcon_spi_write(spi, eeprom->offset + EFX_ETHTOOL_EEPROM_MIN, | 584 | rc = mutex_lock_interruptible(&efx->spi_lock); |
585 | if (rc) | ||
586 | return rc; | ||
587 | rc = falcon_spi_write(spi, eeprom->offset + EFX_EEPROM_BOOTCONFIG_START, | ||
579 | eeprom->len, &len, buf); | 588 | eeprom->len, &len, buf); |
589 | mutex_unlock(&efx->spi_lock); | ||
590 | |||
580 | eeprom->len = len; | 591 | eeprom->len = len; |
581 | return rc; | 592 | return rc; |
582 | } | 593 | } |
@@ -666,23 +677,52 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, | |||
666 | struct ethtool_pauseparam *pause) | 677 | struct ethtool_pauseparam *pause) |
667 | { | 678 | { |
668 | struct efx_nic *efx = netdev_priv(net_dev); | 679 | struct efx_nic *efx = netdev_priv(net_dev); |
669 | enum efx_fc_type flow_control = efx->flow_control; | 680 | enum efx_fc_type wanted_fc; |
670 | int rc; | 681 | bool reset; |
671 | 682 | ||
672 | flow_control &= ~(EFX_FC_RX | EFX_FC_TX | EFX_FC_AUTO); | 683 | wanted_fc = ((pause->rx_pause ? EFX_FC_RX : 0) | |
673 | flow_control |= pause->rx_pause ? EFX_FC_RX : 0; | 684 | (pause->tx_pause ? EFX_FC_TX : 0) | |
674 | flow_control |= pause->tx_pause ? EFX_FC_TX : 0; | 685 | (pause->autoneg ? EFX_FC_AUTO : 0)); |
675 | flow_control |= pause->autoneg ? EFX_FC_AUTO : 0; | 686 | |
687 | if ((wanted_fc & EFX_FC_TX) && !(wanted_fc & EFX_FC_RX)) { | ||
688 | EFX_LOG(efx, "Flow control unsupported: tx ON rx OFF\n"); | ||
689 | return -EINVAL; | ||
690 | } | ||
691 | |||
692 | if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) && | ||
693 | (wanted_fc & EFX_FC_AUTO)) { | ||
694 | EFX_LOG(efx, "PHY does not support flow control " | ||
695 | "autonegotiation\n"); | ||
696 | return -EINVAL; | ||
697 | } | ||
698 | |||
699 | /* TX flow control may automatically turn itself off if the | ||
700 | * link partner (intermittently) stops responding to pause | ||
701 | * frames. There isn't any indication that this has happened, | ||
702 | * so the best we do is leave it up to the user to spot this | ||
703 | * and fix it be cycling transmit flow control on this end. */ | ||
704 | reset = (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX); | ||
705 | if (EFX_WORKAROUND_11482(efx) && reset) { | ||
706 | if (falcon_rev(efx) >= FALCON_REV_B0) { | ||
707 | /* Recover by resetting the EM block */ | ||
708 | if (efx->link_up) | ||
709 | falcon_drain_tx_fifo(efx); | ||
710 | } else { | ||
711 | /* Schedule a reset to recover */ | ||
712 | efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); | ||
713 | } | ||
714 | } | ||
676 | 715 | ||
677 | /* Try to push the pause parameters */ | 716 | /* Try to push the pause parameters */ |
678 | mutex_lock(&efx->mac_lock); | 717 | mutex_lock(&efx->mac_lock); |
679 | rc = falcon_xmac_set_pause(efx, flow_control); | ||
680 | mutex_unlock(&efx->mac_lock); | ||
681 | 718 | ||
682 | if (!rc) | 719 | efx->wanted_fc = wanted_fc; |
683 | efx_reconfigure_port(efx); | 720 | mdio_clause45_set_pause(efx); |
721 | __efx_reconfigure_port(efx); | ||
684 | 722 | ||
685 | return rc; | 723 | mutex_unlock(&efx->mac_lock); |
724 | |||
725 | return 0; | ||
686 | } | 726 | } |
687 | 727 | ||
688 | static void efx_ethtool_get_pauseparam(struct net_device *net_dev, | 728 | static void efx_ethtool_get_pauseparam(struct net_device *net_dev, |
@@ -690,9 +730,9 @@ static void efx_ethtool_get_pauseparam(struct net_device *net_dev, | |||
690 | { | 730 | { |
691 | struct efx_nic *efx = netdev_priv(net_dev); | 731 | struct efx_nic *efx = netdev_priv(net_dev); |
692 | 732 | ||
693 | pause->rx_pause = !!(efx->flow_control & EFX_FC_RX); | 733 | pause->rx_pause = !!(efx->wanted_fc & EFX_FC_RX); |
694 | pause->tx_pause = !!(efx->flow_control & EFX_FC_TX); | 734 | pause->tx_pause = !!(efx->wanted_fc & EFX_FC_TX); |
695 | pause->autoneg = !!(efx->flow_control & EFX_FC_AUTO); | 735 | pause->autoneg = !!(efx->wanted_fc & EFX_FC_AUTO); |
696 | } | 736 | } |
697 | 737 | ||
698 | 738 | ||
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 31ed1f49de00..064307c2277e 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c | |||
@@ -15,11 +15,11 @@ | |||
15 | #include <linux/seq_file.h> | 15 | #include <linux/seq_file.h> |
16 | #include <linux/i2c.h> | 16 | #include <linux/i2c.h> |
17 | #include <linux/i2c-algo-bit.h> | 17 | #include <linux/i2c-algo-bit.h> |
18 | #include <linux/mii.h> | ||
18 | #include "net_driver.h" | 19 | #include "net_driver.h" |
19 | #include "bitfield.h" | 20 | #include "bitfield.h" |
20 | #include "efx.h" | 21 | #include "efx.h" |
21 | #include "mac.h" | 22 | #include "mac.h" |
22 | #include "gmii.h" | ||
23 | #include "spi.h" | 23 | #include "spi.h" |
24 | #include "falcon.h" | 24 | #include "falcon.h" |
25 | #include "falcon_hwdefs.h" | 25 | #include "falcon_hwdefs.h" |
@@ -70,6 +70,20 @@ static int disable_dma_stats; | |||
70 | #define RX_DC_ENTRIES_ORDER 2 | 70 | #define RX_DC_ENTRIES_ORDER 2 |
71 | #define RX_DC_BASE 0x100000 | 71 | #define RX_DC_BASE 0x100000 |
72 | 72 | ||
73 | static const unsigned int | ||
74 | /* "Large" EEPROM device: Atmel AT25640 or similar | ||
75 | * 8 KB, 16-bit address, 32 B write block */ | ||
76 | large_eeprom_type = ((13 << SPI_DEV_TYPE_SIZE_LBN) | ||
77 | | (2 << SPI_DEV_TYPE_ADDR_LEN_LBN) | ||
78 | | (5 << SPI_DEV_TYPE_BLOCK_SIZE_LBN)), | ||
79 | /* Default flash device: Atmel AT25F1024 | ||
80 | * 128 KB, 24-bit address, 32 KB erase block, 256 B write block */ | ||
81 | default_flash_type = ((17 << SPI_DEV_TYPE_SIZE_LBN) | ||
82 | | (3 << SPI_DEV_TYPE_ADDR_LEN_LBN) | ||
83 | | (0x52 << SPI_DEV_TYPE_ERASE_CMD_LBN) | ||
84 | | (15 << SPI_DEV_TYPE_ERASE_SIZE_LBN) | ||
85 | | (8 << SPI_DEV_TYPE_BLOCK_SIZE_LBN)); | ||
86 | |||
73 | /* RX FIFO XOFF watermark | 87 | /* RX FIFO XOFF watermark |
74 | * | 88 | * |
75 | * When the amount of the RX FIFO increases used increases past this | 89 | * When the amount of the RX FIFO increases used increases past this |
@@ -324,10 +338,10 @@ static int falcon_alloc_special_buffer(struct efx_nic *efx, | |||
324 | nic_data->next_buffer_table += buffer->entries; | 338 | nic_data->next_buffer_table += buffer->entries; |
325 | 339 | ||
326 | EFX_LOG(efx, "allocating special buffers %d-%d at %llx+%x " | 340 | EFX_LOG(efx, "allocating special buffers %d-%d at %llx+%x " |
327 | "(virt %p phys %lx)\n", buffer->index, | 341 | "(virt %p phys %llx)\n", buffer->index, |
328 | buffer->index + buffer->entries - 1, | 342 | buffer->index + buffer->entries - 1, |
329 | (unsigned long long)buffer->dma_addr, len, | 343 | (u64)buffer->dma_addr, len, |
330 | buffer->addr, virt_to_phys(buffer->addr)); | 344 | buffer->addr, (u64)virt_to_phys(buffer->addr)); |
331 | 345 | ||
332 | return 0; | 346 | return 0; |
333 | } | 347 | } |
@@ -339,10 +353,10 @@ static void falcon_free_special_buffer(struct efx_nic *efx, | |||
339 | return; | 353 | return; |
340 | 354 | ||
341 | EFX_LOG(efx, "deallocating special buffers %d-%d at %llx+%x " | 355 | EFX_LOG(efx, "deallocating special buffers %d-%d at %llx+%x " |
342 | "(virt %p phys %lx)\n", buffer->index, | 356 | "(virt %p phys %llx)\n", buffer->index, |
343 | buffer->index + buffer->entries - 1, | 357 | buffer->index + buffer->entries - 1, |
344 | (unsigned long long)buffer->dma_addr, buffer->len, | 358 | (u64)buffer->dma_addr, buffer->len, |
345 | buffer->addr, virt_to_phys(buffer->addr)); | 359 | buffer->addr, (u64)virt_to_phys(buffer->addr)); |
346 | 360 | ||
347 | pci_free_consistent(efx->pci_dev, buffer->len, buffer->addr, | 361 | pci_free_consistent(efx->pci_dev, buffer->len, buffer->addr, |
348 | buffer->dma_addr); | 362 | buffer->dma_addr); |
@@ -770,15 +784,18 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, | |||
770 | rx_ev_buf_owner_id_err | rx_ev_eth_crc_err | | 784 | rx_ev_buf_owner_id_err | rx_ev_eth_crc_err | |
771 | rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err); | 785 | rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err); |
772 | 786 | ||
773 | /* Count errors that are not in MAC stats. */ | 787 | /* Count errors that are not in MAC stats. Ignore expected |
788 | * checksum errors during self-test. */ | ||
774 | if (rx_ev_frm_trunc) | 789 | if (rx_ev_frm_trunc) |
775 | ++rx_queue->channel->n_rx_frm_trunc; | 790 | ++rx_queue->channel->n_rx_frm_trunc; |
776 | else if (rx_ev_tobe_disc) | 791 | else if (rx_ev_tobe_disc) |
777 | ++rx_queue->channel->n_rx_tobe_disc; | 792 | ++rx_queue->channel->n_rx_tobe_disc; |
778 | else if (rx_ev_ip_hdr_chksum_err) | 793 | else if (!efx->loopback_selftest) { |
779 | ++rx_queue->channel->n_rx_ip_hdr_chksum_err; | 794 | if (rx_ev_ip_hdr_chksum_err) |
780 | else if (rx_ev_tcp_udp_chksum_err) | 795 | ++rx_queue->channel->n_rx_ip_hdr_chksum_err; |
781 | ++rx_queue->channel->n_rx_tcp_udp_chksum_err; | 796 | else if (rx_ev_tcp_udp_chksum_err) |
797 | ++rx_queue->channel->n_rx_tcp_udp_chksum_err; | ||
798 | } | ||
782 | if (rx_ev_ip_frag_err) | 799 | if (rx_ev_ip_frag_err) |
783 | ++rx_queue->channel->n_rx_ip_frag_err; | 800 | ++rx_queue->channel->n_rx_ip_frag_err; |
784 | 801 | ||
@@ -807,10 +824,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, | |||
807 | rx_ev_pause_frm ? " [PAUSE]" : ""); | 824 | rx_ev_pause_frm ? " [PAUSE]" : ""); |
808 | } | 825 | } |
809 | #endif | 826 | #endif |
810 | |||
811 | if (unlikely(rx_ev_eth_crc_err && EFX_WORKAROUND_10750(efx) && | ||
812 | efx->phy_type == PHY_TYPE_10XPRESS)) | ||
813 | tenxpress_crc_err(efx); | ||
814 | } | 827 | } |
815 | 828 | ||
816 | /* Handle receive events that are not in-order. */ | 829 | /* Handle receive events that are not in-order. */ |
@@ -893,22 +906,20 @@ static void falcon_handle_global_event(struct efx_channel *channel, | |||
893 | efx_qword_t *event) | 906 | efx_qword_t *event) |
894 | { | 907 | { |
895 | struct efx_nic *efx = channel->efx; | 908 | struct efx_nic *efx = channel->efx; |
896 | bool is_phy_event = false, handled = false; | 909 | bool handled = false; |
897 | 910 | ||
898 | /* Check for interrupt on either port. Some boards have a | ||
899 | * single PHY wired to the interrupt line for port 1. */ | ||
900 | if (EFX_QWORD_FIELD(*event, G_PHY0_INTR) || | 911 | if (EFX_QWORD_FIELD(*event, G_PHY0_INTR) || |
901 | EFX_QWORD_FIELD(*event, G_PHY1_INTR) || | 912 | EFX_QWORD_FIELD(*event, G_PHY1_INTR) || |
902 | EFX_QWORD_FIELD(*event, XG_PHY_INTR)) | 913 | EFX_QWORD_FIELD(*event, XG_PHY_INTR) || |
903 | is_phy_event = true; | 914 | EFX_QWORD_FIELD(*event, XFP_PHY_INTR)) { |
915 | efx->phy_op->clear_interrupt(efx); | ||
916 | queue_work(efx->workqueue, &efx->phy_work); | ||
917 | handled = true; | ||
918 | } | ||
904 | 919 | ||
905 | if ((falcon_rev(efx) >= FALCON_REV_B0) && | 920 | if ((falcon_rev(efx) >= FALCON_REV_B0) && |
906 | EFX_QWORD_FIELD(*event, XG_MNT_INTR_B0)) | 921 | EFX_QWORD_FIELD(*event, XG_MNT_INTR_B0)) { |
907 | is_phy_event = true; | 922 | queue_work(efx->workqueue, &efx->mac_work); |
908 | |||
909 | if (is_phy_event) { | ||
910 | efx->phy_op->clear_interrupt(efx); | ||
911 | queue_work(efx->workqueue, &efx->reconfigure_work); | ||
912 | handled = true; | 923 | handled = true; |
913 | } | 924 | } |
914 | 925 | ||
@@ -1151,6 +1162,19 @@ void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic) | |||
1151 | falcon_generate_event(channel, &test_event); | 1162 | falcon_generate_event(channel, &test_event); |
1152 | } | 1163 | } |
1153 | 1164 | ||
1165 | void falcon_sim_phy_event(struct efx_nic *efx) | ||
1166 | { | ||
1167 | efx_qword_t phy_event; | ||
1168 | |||
1169 | EFX_POPULATE_QWORD_1(phy_event, EV_CODE, GLOBAL_EV_DECODE); | ||
1170 | if (EFX_IS10G(efx)) | ||
1171 | EFX_SET_OWORD_FIELD(phy_event, XG_PHY_INTR, 1); | ||
1172 | else | ||
1173 | EFX_SET_OWORD_FIELD(phy_event, G_PHY0_INTR, 1); | ||
1174 | |||
1175 | falcon_generate_event(&efx->channel[0], &phy_event); | ||
1176 | } | ||
1177 | |||
1154 | /************************************************************************** | 1178 | /************************************************************************** |
1155 | * | 1179 | * |
1156 | * Flush handling | 1180 | * Flush handling |
@@ -1375,9 +1399,9 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) | |||
1375 | } | 1399 | } |
1376 | 1400 | ||
1377 | /* Disable both devices */ | 1401 | /* Disable both devices */ |
1378 | pci_disable_device(efx->pci_dev); | 1402 | pci_clear_master(efx->pci_dev); |
1379 | if (FALCON_IS_DUAL_FUNC(efx)) | 1403 | if (FALCON_IS_DUAL_FUNC(efx)) |
1380 | pci_disable_device(nic_data->pci_dev2); | 1404 | pci_clear_master(nic_data->pci_dev2); |
1381 | falcon_disable_interrupts(efx); | 1405 | falcon_disable_interrupts(efx); |
1382 | 1406 | ||
1383 | if (++n_int_errors < FALCON_MAX_INT_ERRORS) { | 1407 | if (++n_int_errors < FALCON_MAX_INT_ERRORS) { |
@@ -1560,7 +1584,7 @@ int falcon_init_interrupt(struct efx_nic *efx) | |||
1560 | efx_for_each_channel(channel, efx) { | 1584 | efx_for_each_channel(channel, efx) { |
1561 | rc = request_irq(channel->irq, falcon_msi_interrupt, | 1585 | rc = request_irq(channel->irq, falcon_msi_interrupt, |
1562 | IRQF_PROBE_SHARED, /* Not shared */ | 1586 | IRQF_PROBE_SHARED, /* Not shared */ |
1563 | efx->name, channel); | 1587 | channel->name, channel); |
1564 | if (rc) { | 1588 | if (rc) { |
1565 | EFX_ERR(efx, "failed to hook IRQ %d\n", channel->irq); | 1589 | EFX_ERR(efx, "failed to hook IRQ %d\n", channel->irq); |
1566 | goto fail2; | 1590 | goto fail2; |
@@ -1605,32 +1629,45 @@ void falcon_fini_interrupt(struct efx_nic *efx) | |||
1605 | ************************************************************************** | 1629 | ************************************************************************** |
1606 | */ | 1630 | */ |
1607 | 1631 | ||
1608 | #define FALCON_SPI_MAX_LEN ((unsigned) sizeof(efx_oword_t)) | 1632 | #define FALCON_SPI_MAX_LEN sizeof(efx_oword_t) |
1633 | |||
1634 | static int falcon_spi_poll(struct efx_nic *efx) | ||
1635 | { | ||
1636 | efx_oword_t reg; | ||
1637 | falcon_read(efx, ®, EE_SPI_HCMD_REG_KER); | ||
1638 | return EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN) ? -EBUSY : 0; | ||
1639 | } | ||
1609 | 1640 | ||
1610 | /* Wait for SPI command completion */ | 1641 | /* Wait for SPI command completion */ |
1611 | static int falcon_spi_wait(struct efx_nic *efx) | 1642 | static int falcon_spi_wait(struct efx_nic *efx) |
1612 | { | 1643 | { |
1613 | unsigned long timeout = jiffies + DIV_ROUND_UP(HZ, 10); | 1644 | /* Most commands will finish quickly, so we start polling at |
1614 | efx_oword_t reg; | 1645 | * very short intervals. Sometimes the command may have to |
1615 | bool cmd_en, timer_active; | 1646 | * wait for VPD or expansion ROM access outside of our |
1647 | * control, so we allow up to 100 ms. */ | ||
1648 | unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 10); | ||
1649 | int i; | ||
1650 | |||
1651 | for (i = 0; i < 10; i++) { | ||
1652 | if (!falcon_spi_poll(efx)) | ||
1653 | return 0; | ||
1654 | udelay(10); | ||
1655 | } | ||
1616 | 1656 | ||
1617 | for (;;) { | 1657 | for (;;) { |
1618 | falcon_read(efx, ®, EE_SPI_HCMD_REG_KER); | 1658 | if (!falcon_spi_poll(efx)) |
1619 | cmd_en = EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN); | ||
1620 | timer_active = EFX_OWORD_FIELD(reg, EE_WR_TIMER_ACTIVE); | ||
1621 | if (!cmd_en && !timer_active) | ||
1622 | return 0; | 1659 | return 0; |
1623 | if (time_after_eq(jiffies, timeout)) { | 1660 | if (time_after_eq(jiffies, timeout)) { |
1624 | EFX_ERR(efx, "timed out waiting for SPI\n"); | 1661 | EFX_ERR(efx, "timed out waiting for SPI\n"); |
1625 | return -ETIMEDOUT; | 1662 | return -ETIMEDOUT; |
1626 | } | 1663 | } |
1627 | cpu_relax(); | 1664 | schedule_timeout_uninterruptible(1); |
1628 | } | 1665 | } |
1629 | } | 1666 | } |
1630 | 1667 | ||
1631 | static int falcon_spi_cmd(const struct efx_spi_device *spi, | 1668 | int falcon_spi_cmd(const struct efx_spi_device *spi, |
1632 | unsigned int command, int address, | 1669 | unsigned int command, int address, |
1633 | const void *in, void *out, unsigned int len) | 1670 | const void *in, void *out, size_t len) |
1634 | { | 1671 | { |
1635 | struct efx_nic *efx = spi->efx; | 1672 | struct efx_nic *efx = spi->efx; |
1636 | bool addressed = (address >= 0); | 1673 | bool addressed = (address >= 0); |
@@ -1641,9 +1678,10 @@ static int falcon_spi_cmd(const struct efx_spi_device *spi, | |||
1641 | /* Input validation */ | 1678 | /* Input validation */ |
1642 | if (len > FALCON_SPI_MAX_LEN) | 1679 | if (len > FALCON_SPI_MAX_LEN) |
1643 | return -EINVAL; | 1680 | return -EINVAL; |
1681 | BUG_ON(!mutex_is_locked(&efx->spi_lock)); | ||
1644 | 1682 | ||
1645 | /* Check SPI not currently being accessed */ | 1683 | /* Check that previous command is not still running */ |
1646 | rc = falcon_spi_wait(efx); | 1684 | rc = falcon_spi_poll(efx); |
1647 | if (rc) | 1685 | if (rc) |
1648 | return rc; | 1686 | return rc; |
1649 | 1687 | ||
@@ -1685,8 +1723,8 @@ static int falcon_spi_cmd(const struct efx_spi_device *spi, | |||
1685 | return 0; | 1723 | return 0; |
1686 | } | 1724 | } |
1687 | 1725 | ||
1688 | static unsigned int | 1726 | static size_t |
1689 | falcon_spi_write_limit(const struct efx_spi_device *spi, unsigned int start) | 1727 | falcon_spi_write_limit(const struct efx_spi_device *spi, size_t start) |
1690 | { | 1728 | { |
1691 | return min(FALCON_SPI_MAX_LEN, | 1729 | return min(FALCON_SPI_MAX_LEN, |
1692 | (spi->block_size - (start & (spi->block_size - 1)))); | 1730 | (spi->block_size - (start & (spi->block_size - 1)))); |
@@ -1699,38 +1737,40 @@ efx_spi_munge_command(const struct efx_spi_device *spi, | |||
1699 | return command | (((address >> 8) & spi->munge_address) << 3); | 1737 | return command | (((address >> 8) & spi->munge_address) << 3); |
1700 | } | 1738 | } |
1701 | 1739 | ||
1702 | 1740 | /* Wait up to 10 ms for buffered write completion */ | |
1703 | static int falcon_spi_fast_wait(const struct efx_spi_device *spi) | 1741 | int falcon_spi_wait_write(const struct efx_spi_device *spi) |
1704 | { | 1742 | { |
1743 | struct efx_nic *efx = spi->efx; | ||
1744 | unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 100); | ||
1705 | u8 status; | 1745 | u8 status; |
1706 | int i, rc; | 1746 | int rc; |
1707 | |||
1708 | /* Wait up to 1000us for flash/EEPROM to finish a fast operation. */ | ||
1709 | for (i = 0; i < 50; i++) { | ||
1710 | udelay(20); | ||
1711 | 1747 | ||
1748 | for (;;) { | ||
1712 | rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL, | 1749 | rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL, |
1713 | &status, sizeof(status)); | 1750 | &status, sizeof(status)); |
1714 | if (rc) | 1751 | if (rc) |
1715 | return rc; | 1752 | return rc; |
1716 | if (!(status & SPI_STATUS_NRDY)) | 1753 | if (!(status & SPI_STATUS_NRDY)) |
1717 | return 0; | 1754 | return 0; |
1755 | if (time_after_eq(jiffies, timeout)) { | ||
1756 | EFX_ERR(efx, "SPI write timeout on device %d" | ||
1757 | " last status=0x%02x\n", | ||
1758 | spi->device_id, status); | ||
1759 | return -ETIMEDOUT; | ||
1760 | } | ||
1761 | schedule_timeout_uninterruptible(1); | ||
1718 | } | 1762 | } |
1719 | EFX_ERR(spi->efx, | ||
1720 | "timed out waiting for device %d last status=0x%02x\n", | ||
1721 | spi->device_id, status); | ||
1722 | return -ETIMEDOUT; | ||
1723 | } | 1763 | } |
1724 | 1764 | ||
1725 | int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, | 1765 | int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, |
1726 | size_t len, size_t *retlen, u8 *buffer) | 1766 | size_t len, size_t *retlen, u8 *buffer) |
1727 | { | 1767 | { |
1728 | unsigned int command, block_len, pos = 0; | 1768 | size_t block_len, pos = 0; |
1769 | unsigned int command; | ||
1729 | int rc = 0; | 1770 | int rc = 0; |
1730 | 1771 | ||
1731 | while (pos < len) { | 1772 | while (pos < len) { |
1732 | block_len = min((unsigned int)len - pos, | 1773 | block_len = min(len - pos, FALCON_SPI_MAX_LEN); |
1733 | FALCON_SPI_MAX_LEN); | ||
1734 | 1774 | ||
1735 | command = efx_spi_munge_command(spi, SPI_READ, start + pos); | 1775 | command = efx_spi_munge_command(spi, SPI_READ, start + pos); |
1736 | rc = falcon_spi_cmd(spi, command, start + pos, NULL, | 1776 | rc = falcon_spi_cmd(spi, command, start + pos, NULL, |
@@ -1756,7 +1796,8 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, | |||
1756 | size_t len, size_t *retlen, const u8 *buffer) | 1796 | size_t len, size_t *retlen, const u8 *buffer) |
1757 | { | 1797 | { |
1758 | u8 verify_buffer[FALCON_SPI_MAX_LEN]; | 1798 | u8 verify_buffer[FALCON_SPI_MAX_LEN]; |
1759 | unsigned int command, block_len, pos = 0; | 1799 | size_t block_len, pos = 0; |
1800 | unsigned int command; | ||
1760 | int rc = 0; | 1801 | int rc = 0; |
1761 | 1802 | ||
1762 | while (pos < len) { | 1803 | while (pos < len) { |
@@ -1764,7 +1805,7 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, | |||
1764 | if (rc) | 1805 | if (rc) |
1765 | break; | 1806 | break; |
1766 | 1807 | ||
1767 | block_len = min((unsigned int)len - pos, | 1808 | block_len = min(len - pos, |
1768 | falcon_spi_write_limit(spi, start + pos)); | 1809 | falcon_spi_write_limit(spi, start + pos)); |
1769 | command = efx_spi_munge_command(spi, SPI_WRITE, start + pos); | 1810 | command = efx_spi_munge_command(spi, SPI_WRITE, start + pos); |
1770 | rc = falcon_spi_cmd(spi, command, start + pos, | 1811 | rc = falcon_spi_cmd(spi, command, start + pos, |
@@ -1772,7 +1813,7 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, | |||
1772 | if (rc) | 1813 | if (rc) |
1773 | break; | 1814 | break; |
1774 | 1815 | ||
1775 | rc = falcon_spi_fast_wait(spi); | 1816 | rc = falcon_spi_wait_write(spi); |
1776 | if (rc) | 1817 | if (rc) |
1777 | break; | 1818 | break; |
1778 | 1819 | ||
@@ -1805,40 +1846,61 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, | |||
1805 | * | 1846 | * |
1806 | ************************************************************************** | 1847 | ************************************************************************** |
1807 | */ | 1848 | */ |
1808 | void falcon_drain_tx_fifo(struct efx_nic *efx) | 1849 | |
1850 | static int falcon_reset_macs(struct efx_nic *efx) | ||
1809 | { | 1851 | { |
1810 | efx_oword_t temp; | 1852 | efx_oword_t reg; |
1811 | int count; | 1853 | int count; |
1812 | 1854 | ||
1813 | if ((falcon_rev(efx) < FALCON_REV_B0) || | 1855 | if (falcon_rev(efx) < FALCON_REV_B0) { |
1814 | (efx->loopback_mode != LOOPBACK_NONE)) | 1856 | /* It's not safe to use GLB_CTL_REG to reset the |
1815 | return; | 1857 | * macs, so instead use the internal MAC resets |
1858 | */ | ||
1859 | if (!EFX_IS10G(efx)) { | ||
1860 | EFX_POPULATE_OWORD_1(reg, GM_SW_RST, 1); | ||
1861 | falcon_write(efx, ®, GM_CFG1_REG); | ||
1862 | udelay(1000); | ||
1863 | |||
1864 | EFX_POPULATE_OWORD_1(reg, GM_SW_RST, 0); | ||
1865 | falcon_write(efx, ®, GM_CFG1_REG); | ||
1866 | udelay(1000); | ||
1867 | return 0; | ||
1868 | } else { | ||
1869 | EFX_POPULATE_OWORD_1(reg, XM_CORE_RST, 1); | ||
1870 | falcon_write(efx, ®, XM_GLB_CFG_REG); | ||
1871 | |||
1872 | for (count = 0; count < 10000; count++) { | ||
1873 | falcon_read(efx, ®, XM_GLB_CFG_REG); | ||
1874 | if (EFX_OWORD_FIELD(reg, XM_CORE_RST) == 0) | ||
1875 | return 0; | ||
1876 | udelay(10); | ||
1877 | } | ||
1816 | 1878 | ||
1817 | falcon_read(efx, &temp, MAC0_CTRL_REG_KER); | 1879 | EFX_ERR(efx, "timed out waiting for XMAC core reset\n"); |
1818 | /* There is no point in draining more than once */ | 1880 | return -ETIMEDOUT; |
1819 | if (EFX_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0)) | 1881 | } |
1820 | return; | 1882 | } |
1821 | 1883 | ||
1822 | /* MAC stats will fail whilst the TX fifo is draining. Serialise | 1884 | /* MAC stats will fail whilst the TX fifo is draining. Serialise |
1823 | * the drain sequence with the statistics fetch */ | 1885 | * the drain sequence with the statistics fetch */ |
1824 | spin_lock(&efx->stats_lock); | 1886 | efx_stats_disable(efx); |
1825 | 1887 | ||
1826 | EFX_SET_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0, 1); | 1888 | falcon_read(efx, ®, MAC0_CTRL_REG_KER); |
1827 | falcon_write(efx, &temp, MAC0_CTRL_REG_KER); | 1889 | EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1); |
1890 | falcon_write(efx, ®, MAC0_CTRL_REG_KER); | ||
1828 | 1891 | ||
1829 | /* Reset the MAC and EM block. */ | 1892 | falcon_read(efx, ®, GLB_CTL_REG_KER); |
1830 | falcon_read(efx, &temp, GLB_CTL_REG_KER); | 1893 | EFX_SET_OWORD_FIELD(reg, RST_XGTX, 1); |
1831 | EFX_SET_OWORD_FIELD(temp, RST_XGTX, 1); | 1894 | EFX_SET_OWORD_FIELD(reg, RST_XGRX, 1); |
1832 | EFX_SET_OWORD_FIELD(temp, RST_XGRX, 1); | 1895 | EFX_SET_OWORD_FIELD(reg, RST_EM, 1); |
1833 | EFX_SET_OWORD_FIELD(temp, RST_EM, 1); | 1896 | falcon_write(efx, ®, GLB_CTL_REG_KER); |
1834 | falcon_write(efx, &temp, GLB_CTL_REG_KER); | ||
1835 | 1897 | ||
1836 | count = 0; | 1898 | count = 0; |
1837 | while (1) { | 1899 | while (1) { |
1838 | falcon_read(efx, &temp, GLB_CTL_REG_KER); | 1900 | falcon_read(efx, ®, GLB_CTL_REG_KER); |
1839 | if (!EFX_OWORD_FIELD(temp, RST_XGTX) && | 1901 | if (!EFX_OWORD_FIELD(reg, RST_XGTX) && |
1840 | !EFX_OWORD_FIELD(temp, RST_XGRX) && | 1902 | !EFX_OWORD_FIELD(reg, RST_XGRX) && |
1841 | !EFX_OWORD_FIELD(temp, RST_EM)) { | 1903 | !EFX_OWORD_FIELD(reg, RST_EM)) { |
1842 | EFX_LOG(efx, "Completed MAC reset after %d loops\n", | 1904 | EFX_LOG(efx, "Completed MAC reset after %d loops\n", |
1843 | count); | 1905 | count); |
1844 | break; | 1906 | break; |
@@ -1851,25 +1913,43 @@ void falcon_drain_tx_fifo(struct efx_nic *efx) | |||
1851 | udelay(10); | 1913 | udelay(10); |
1852 | } | 1914 | } |
1853 | 1915 | ||
1854 | spin_unlock(&efx->stats_lock); | 1916 | efx_stats_enable(efx); |
1855 | 1917 | ||
1856 | /* If we've reset the EM block and the link is up, then | 1918 | /* If we've reset the EM block and the link is up, then |
1857 | * we'll have to kick the XAUI link so the PHY can recover */ | 1919 | * we'll have to kick the XAUI link so the PHY can recover */ |
1858 | if (efx->link_up && EFX_WORKAROUND_5147(efx)) | 1920 | if (efx->link_up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx)) |
1859 | falcon_reset_xaui(efx); | 1921 | falcon_reset_xaui(efx); |
1922 | |||
1923 | return 0; | ||
1924 | } | ||
1925 | |||
1926 | void falcon_drain_tx_fifo(struct efx_nic *efx) | ||
1927 | { | ||
1928 | efx_oword_t reg; | ||
1929 | |||
1930 | if ((falcon_rev(efx) < FALCON_REV_B0) || | ||
1931 | (efx->loopback_mode != LOOPBACK_NONE)) | ||
1932 | return; | ||
1933 | |||
1934 | falcon_read(efx, ®, MAC0_CTRL_REG_KER); | ||
1935 | /* There is no point in draining more than once */ | ||
1936 | if (EFX_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0)) | ||
1937 | return; | ||
1938 | |||
1939 | falcon_reset_macs(efx); | ||
1860 | } | 1940 | } |
1861 | 1941 | ||
1862 | void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) | 1942 | void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) |
1863 | { | 1943 | { |
1864 | efx_oword_t temp; | 1944 | efx_oword_t reg; |
1865 | 1945 | ||
1866 | if (falcon_rev(efx) < FALCON_REV_B0) | 1946 | if (falcon_rev(efx) < FALCON_REV_B0) |
1867 | return; | 1947 | return; |
1868 | 1948 | ||
1869 | /* Isolate the MAC -> RX */ | 1949 | /* Isolate the MAC -> RX */ |
1870 | falcon_read(efx, &temp, RX_CFG_REG_KER); | 1950 | falcon_read(efx, ®, RX_CFG_REG_KER); |
1871 | EFX_SET_OWORD_FIELD(temp, RX_INGR_EN_B0, 0); | 1951 | EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 0); |
1872 | falcon_write(efx, &temp, RX_CFG_REG_KER); | 1952 | falcon_write(efx, ®, RX_CFG_REG_KER); |
1873 | 1953 | ||
1874 | if (!efx->link_up) | 1954 | if (!efx->link_up) |
1875 | falcon_drain_tx_fifo(efx); | 1955 | falcon_drain_tx_fifo(efx); |
@@ -1881,14 +1961,12 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) | |||
1881 | int link_speed; | 1961 | int link_speed; |
1882 | bool tx_fc; | 1962 | bool tx_fc; |
1883 | 1963 | ||
1884 | if (efx->link_options & GM_LPA_10000) | 1964 | switch (efx->link_speed) { |
1885 | link_speed = 0x3; | 1965 | case 10000: link_speed = 3; break; |
1886 | else if (efx->link_options & GM_LPA_1000) | 1966 | case 1000: link_speed = 2; break; |
1887 | link_speed = 0x2; | 1967 | case 100: link_speed = 1; break; |
1888 | else if (efx->link_options & GM_LPA_100) | 1968 | default: link_speed = 0; break; |
1889 | link_speed = 0x1; | 1969 | } |
1890 | else | ||
1891 | link_speed = 0x0; | ||
1892 | /* MAC_LINK_STATUS controls MAC backpressure but doesn't work | 1970 | /* MAC_LINK_STATUS controls MAC backpressure but doesn't work |
1893 | * as advertised. Disable to ensure packets are not | 1971 | * as advertised. Disable to ensure packets are not |
1894 | * indefinitely held and TX queue can be flushed at any point | 1972 | * indefinitely held and TX queue can be flushed at any point |
@@ -1914,7 +1992,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) | |||
1914 | /* Transmission of pause frames when RX crosses the threshold is | 1992 | /* Transmission of pause frames when RX crosses the threshold is |
1915 | * covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL. | 1993 | * covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL. |
1916 | * Action on receipt of pause frames is controller by XM_DIS_FCNTL */ | 1994 | * Action on receipt of pause frames is controller by XM_DIS_FCNTL */ |
1917 | tx_fc = !!(efx->flow_control & EFX_FC_TX); | 1995 | tx_fc = !!(efx->link_fc & EFX_FC_TX); |
1918 | falcon_read(efx, ®, RX_CFG_REG_KER); | 1996 | falcon_read(efx, ®, RX_CFG_REG_KER); |
1919 | EFX_SET_OWORD_FIELD_VER(efx, reg, RX_XOFF_MAC_EN, tx_fc); | 1997 | EFX_SET_OWORD_FIELD_VER(efx, reg, RX_XOFF_MAC_EN, tx_fc); |
1920 | 1998 | ||
@@ -1998,7 +2076,8 @@ static int falcon_gmii_wait(struct efx_nic *efx) | |||
1998 | efx_dword_t md_stat; | 2076 | efx_dword_t md_stat; |
1999 | int count; | 2077 | int count; |
2000 | 2078 | ||
2001 | for (count = 0; count < 1000; count++) { /* wait upto 10ms */ | 2079 | /* wait upto 50ms - taken max from datasheet */ |
2080 | for (count = 0; count < 5000; count++) { | ||
2002 | falcon_readl(efx, &md_stat, MD_STAT_REG_KER); | 2081 | falcon_readl(efx, &md_stat, MD_STAT_REG_KER); |
2003 | if (EFX_DWORD_FIELD(md_stat, MD_BSY) == 0) { | 2082 | if (EFX_DWORD_FIELD(md_stat, MD_BSY) == 0) { |
2004 | if (EFX_DWORD_FIELD(md_stat, MD_LNFL) != 0 || | 2083 | if (EFX_DWORD_FIELD(md_stat, MD_LNFL) != 0 || |
@@ -2162,10 +2241,14 @@ static void falcon_init_mdio(struct mii_if_info *gmii) | |||
2162 | static int falcon_probe_phy(struct efx_nic *efx) | 2241 | static int falcon_probe_phy(struct efx_nic *efx) |
2163 | { | 2242 | { |
2164 | switch (efx->phy_type) { | 2243 | switch (efx->phy_type) { |
2165 | case PHY_TYPE_10XPRESS: | 2244 | case PHY_TYPE_SFX7101: |
2166 | efx->phy_op = &falcon_tenxpress_phy_ops; | 2245 | efx->phy_op = &falcon_sfx7101_phy_ops; |
2167 | break; | 2246 | break; |
2168 | case PHY_TYPE_XFP: | 2247 | case PHY_TYPE_SFT9001A: |
2248 | case PHY_TYPE_SFT9001B: | ||
2249 | efx->phy_op = &falcon_sft9001_phy_ops; | ||
2250 | break; | ||
2251 | case PHY_TYPE_QT2022C2: | ||
2169 | efx->phy_op = &falcon_xfp_phy_ops; | 2252 | efx->phy_op = &falcon_xfp_phy_ops; |
2170 | break; | 2253 | break; |
2171 | default: | 2254 | default: |
@@ -2174,10 +2257,67 @@ static int falcon_probe_phy(struct efx_nic *efx) | |||
2174 | return -1; | 2257 | return -1; |
2175 | } | 2258 | } |
2176 | 2259 | ||
2177 | efx->loopback_modes = LOOPBACKS_10G_INTERNAL | efx->phy_op->loopbacks; | 2260 | if (efx->phy_op->macs & EFX_XMAC) |
2261 | efx->loopback_modes |= ((1 << LOOPBACK_XGMII) | | ||
2262 | (1 << LOOPBACK_XGXS) | | ||
2263 | (1 << LOOPBACK_XAUI)); | ||
2264 | if (efx->phy_op->macs & EFX_GMAC) | ||
2265 | efx->loopback_modes |= (1 << LOOPBACK_GMAC); | ||
2266 | efx->loopback_modes |= efx->phy_op->loopbacks; | ||
2267 | |||
2178 | return 0; | 2268 | return 0; |
2179 | } | 2269 | } |
2180 | 2270 | ||
2271 | int falcon_switch_mac(struct efx_nic *efx) | ||
2272 | { | ||
2273 | struct efx_mac_operations *old_mac_op = efx->mac_op; | ||
2274 | efx_oword_t nic_stat; | ||
2275 | unsigned strap_val; | ||
2276 | int rc = 0; | ||
2277 | |||
2278 | /* Don't try to fetch MAC stats while we're switching MACs */ | ||
2279 | efx_stats_disable(efx); | ||
2280 | |||
2281 | /* Internal loopbacks override the phy speed setting */ | ||
2282 | if (efx->loopback_mode == LOOPBACK_GMAC) { | ||
2283 | efx->link_speed = 1000; | ||
2284 | efx->link_fd = true; | ||
2285 | } else if (LOOPBACK_INTERNAL(efx)) { | ||
2286 | efx->link_speed = 10000; | ||
2287 | efx->link_fd = true; | ||
2288 | } | ||
2289 | |||
2290 | WARN_ON(!mutex_is_locked(&efx->mac_lock)); | ||
2291 | efx->mac_op = (EFX_IS10G(efx) ? | ||
2292 | &falcon_xmac_operations : &falcon_gmac_operations); | ||
2293 | |||
2294 | /* Always push the NIC_STAT_REG setting even if the mac hasn't | ||
2295 | * changed, because this function is run post online reset */ | ||
2296 | falcon_read(efx, &nic_stat, NIC_STAT_REG); | ||
2297 | strap_val = EFX_IS10G(efx) ? 5 : 3; | ||
2298 | if (falcon_rev(efx) >= FALCON_REV_B0) { | ||
2299 | EFX_SET_OWORD_FIELD(nic_stat, EE_STRAP_EN, 1); | ||
2300 | EFX_SET_OWORD_FIELD(nic_stat, EE_STRAP_OVR, strap_val); | ||
2301 | falcon_write(efx, &nic_stat, NIC_STAT_REG); | ||
2302 | } else { | ||
2303 | /* Falcon A1 does not support 1G/10G speed switching | ||
2304 | * and must not be used with a PHY that does. */ | ||
2305 | BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val); | ||
2306 | } | ||
2307 | |||
2308 | if (old_mac_op == efx->mac_op) | ||
2309 | goto out; | ||
2310 | |||
2311 | EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G'); | ||
2312 | /* Not all macs support a mac-level link state */ | ||
2313 | efx->mac_up = true; | ||
2314 | |||
2315 | rc = falcon_reset_macs(efx); | ||
2316 | out: | ||
2317 | efx_stats_enable(efx); | ||
2318 | return rc; | ||
2319 | } | ||
2320 | |||
2181 | /* This call is responsible for hooking in the MAC and PHY operations */ | 2321 | /* This call is responsible for hooking in the MAC and PHY operations */ |
2182 | int falcon_probe_port(struct efx_nic *efx) | 2322 | int falcon_probe_port(struct efx_nic *efx) |
2183 | { | 2323 | { |
@@ -2194,19 +2334,19 @@ int falcon_probe_port(struct efx_nic *efx) | |||
2194 | 2334 | ||
2195 | /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ | 2335 | /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ |
2196 | if (falcon_rev(efx) >= FALCON_REV_B0) | 2336 | if (falcon_rev(efx) >= FALCON_REV_B0) |
2197 | efx->flow_control = EFX_FC_RX | EFX_FC_TX; | 2337 | efx->wanted_fc = EFX_FC_RX | EFX_FC_TX; |
2198 | else | 2338 | else |
2199 | efx->flow_control = EFX_FC_RX; | 2339 | efx->wanted_fc = EFX_FC_RX; |
2200 | 2340 | ||
2201 | /* Allocate buffer for stats */ | 2341 | /* Allocate buffer for stats */ |
2202 | rc = falcon_alloc_buffer(efx, &efx->stats_buffer, | 2342 | rc = falcon_alloc_buffer(efx, &efx->stats_buffer, |
2203 | FALCON_MAC_STATS_SIZE); | 2343 | FALCON_MAC_STATS_SIZE); |
2204 | if (rc) | 2344 | if (rc) |
2205 | return rc; | 2345 | return rc; |
2206 | EFX_LOG(efx, "stats buffer at %llx (virt %p phys %lx)\n", | 2346 | EFX_LOG(efx, "stats buffer at %llx (virt %p phys %llx)\n", |
2207 | (unsigned long long)efx->stats_buffer.dma_addr, | 2347 | (u64)efx->stats_buffer.dma_addr, |
2208 | efx->stats_buffer.addr, | 2348 | efx->stats_buffer.addr, |
2209 | virt_to_phys(efx->stats_buffer.addr)); | 2349 | (u64)virt_to_phys(efx->stats_buffer.addr)); |
2210 | 2350 | ||
2211 | return 0; | 2351 | return 0; |
2212 | } | 2352 | } |
@@ -2253,13 +2393,18 @@ int falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out) | |||
2253 | __le16 *word, *limit; | 2393 | __le16 *word, *limit; |
2254 | u32 csum; | 2394 | u32 csum; |
2255 | 2395 | ||
2256 | region = kmalloc(NVCONFIG_END, GFP_KERNEL); | 2396 | spi = efx->spi_flash ? efx->spi_flash : efx->spi_eeprom; |
2397 | if (!spi) | ||
2398 | return -EINVAL; | ||
2399 | |||
2400 | region = kmalloc(FALCON_NVCONFIG_END, GFP_KERNEL); | ||
2257 | if (!region) | 2401 | if (!region) |
2258 | return -ENOMEM; | 2402 | return -ENOMEM; |
2259 | nvconfig = region + NVCONFIG_OFFSET; | 2403 | nvconfig = region + NVCONFIG_OFFSET; |
2260 | 2404 | ||
2261 | spi = efx->spi_flash ? efx->spi_flash : efx->spi_eeprom; | 2405 | mutex_lock(&efx->spi_lock); |
2262 | rc = falcon_spi_read(spi, 0, NVCONFIG_END, NULL, region); | 2406 | rc = falcon_spi_read(spi, 0, FALCON_NVCONFIG_END, NULL, region); |
2407 | mutex_unlock(&efx->spi_lock); | ||
2263 | if (rc) { | 2408 | if (rc) { |
2264 | EFX_ERR(efx, "Failed to read %s\n", | 2409 | EFX_ERR(efx, "Failed to read %s\n", |
2265 | efx->spi_flash ? "flash" : "EEPROM"); | 2410 | efx->spi_flash ? "flash" : "EEPROM"); |
@@ -2283,7 +2428,7 @@ int falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out) | |||
2283 | limit = (__le16 *) (nvconfig + 1); | 2428 | limit = (__le16 *) (nvconfig + 1); |
2284 | } else { | 2429 | } else { |
2285 | word = region; | 2430 | word = region; |
2286 | limit = region + NVCONFIG_END; | 2431 | limit = region + FALCON_NVCONFIG_END; |
2287 | } | 2432 | } |
2288 | for (csum = 0; word < limit; ++word) | 2433 | for (csum = 0; word < limit; ++word) |
2289 | csum += le16_to_cpu(*word); | 2434 | csum += le16_to_cpu(*word); |
@@ -2325,6 +2470,10 @@ static struct { | |||
2325 | EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) }, | 2470 | EFX_OWORD32(0x000003FF, 0x00000000, 0x00000000, 0x00000000) }, |
2326 | { DP_CTRL_REG, | 2471 | { DP_CTRL_REG, |
2327 | EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) }, | 2472 | EFX_OWORD32(0x00000FFF, 0x00000000, 0x00000000, 0x00000000) }, |
2473 | { GM_CFG2_REG, | ||
2474 | EFX_OWORD32(0x00007337, 0x00000000, 0x00000000, 0x00000000) }, | ||
2475 | { GMF_CFG0_REG, | ||
2476 | EFX_OWORD32(0x00001F1F, 0x00000000, 0x00000000, 0x00000000) }, | ||
2328 | { XM_GLB_CFG_REG, | 2477 | { XM_GLB_CFG_REG, |
2329 | EFX_OWORD32(0x00000C68, 0x00000000, 0x00000000, 0x00000000) }, | 2478 | EFX_OWORD32(0x00000C68, 0x00000000, 0x00000000, 0x00000000) }, |
2330 | { XM_TX_CFG_REG, | 2479 | { XM_TX_CFG_REG, |
@@ -2545,7 +2694,7 @@ static int falcon_spi_device_init(struct efx_nic *efx, | |||
2545 | struct efx_spi_device *spi_device; | 2694 | struct efx_spi_device *spi_device; |
2546 | 2695 | ||
2547 | if (device_type != 0) { | 2696 | if (device_type != 0) { |
2548 | spi_device = kmalloc(sizeof(*spi_device), GFP_KERNEL); | 2697 | spi_device = kzalloc(sizeof(*spi_device), GFP_KERNEL); |
2549 | if (!spi_device) | 2698 | if (!spi_device) |
2550 | return -ENOMEM; | 2699 | return -ENOMEM; |
2551 | spi_device->device_id = device_id; | 2700 | spi_device->device_id = device_id; |
@@ -2555,6 +2704,11 @@ static int falcon_spi_device_init(struct efx_nic *efx, | |||
2555 | SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_ADDR_LEN); | 2704 | SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_ADDR_LEN); |
2556 | spi_device->munge_address = (spi_device->size == 1 << 9 && | 2705 | spi_device->munge_address = (spi_device->size == 1 << 9 && |
2557 | spi_device->addr_len == 1); | 2706 | spi_device->addr_len == 1); |
2707 | spi_device->erase_command = | ||
2708 | SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_ERASE_CMD); | ||
2709 | spi_device->erase_size = | ||
2710 | 1 << SPI_DEV_TYPE_FIELD(device_type, | ||
2711 | SPI_DEV_TYPE_ERASE_SIZE); | ||
2558 | spi_device->block_size = | 2712 | spi_device->block_size = |
2559 | 1 << SPI_DEV_TYPE_FIELD(device_type, | 2713 | 1 << SPI_DEV_TYPE_FIELD(device_type, |
2560 | SPI_DEV_TYPE_BLOCK_SIZE); | 2714 | SPI_DEV_TYPE_BLOCK_SIZE); |
@@ -2645,6 +2799,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) | |||
2645 | static int falcon_probe_nic_variant(struct efx_nic *efx) | 2799 | static int falcon_probe_nic_variant(struct efx_nic *efx) |
2646 | { | 2800 | { |
2647 | efx_oword_t altera_build; | 2801 | efx_oword_t altera_build; |
2802 | efx_oword_t nic_stat; | ||
2648 | 2803 | ||
2649 | falcon_read(efx, &altera_build, ALTERA_BUILD_REG_KER); | 2804 | falcon_read(efx, &altera_build, ALTERA_BUILD_REG_KER); |
2650 | if (EFX_OWORD_FIELD(altera_build, VER_ALL)) { | 2805 | if (EFX_OWORD_FIELD(altera_build, VER_ALL)) { |
@@ -2652,27 +2807,20 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) | |||
2652 | return -ENODEV; | 2807 | return -ENODEV; |
2653 | } | 2808 | } |
2654 | 2809 | ||
2810 | falcon_read(efx, &nic_stat, NIC_STAT_REG); | ||
2811 | |||
2655 | switch (falcon_rev(efx)) { | 2812 | switch (falcon_rev(efx)) { |
2656 | case FALCON_REV_A0: | 2813 | case FALCON_REV_A0: |
2657 | case 0xff: | 2814 | case 0xff: |
2658 | EFX_ERR(efx, "Falcon rev A0 not supported\n"); | 2815 | EFX_ERR(efx, "Falcon rev A0 not supported\n"); |
2659 | return -ENODEV; | 2816 | return -ENODEV; |
2660 | 2817 | ||
2661 | case FALCON_REV_A1:{ | 2818 | case FALCON_REV_A1: |
2662 | efx_oword_t nic_stat; | ||
2663 | |||
2664 | falcon_read(efx, &nic_stat, NIC_STAT_REG); | ||
2665 | |||
2666 | if (EFX_OWORD_FIELD(nic_stat, STRAP_PCIE) == 0) { | 2819 | if (EFX_OWORD_FIELD(nic_stat, STRAP_PCIE) == 0) { |
2667 | EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n"); | 2820 | EFX_ERR(efx, "Falcon rev A1 PCI-X not supported\n"); |
2668 | return -ENODEV; | 2821 | return -ENODEV; |
2669 | } | 2822 | } |
2670 | if (!EFX_OWORD_FIELD(nic_stat, STRAP_10G)) { | ||
2671 | EFX_ERR(efx, "1G mode not supported\n"); | ||
2672 | return -ENODEV; | ||
2673 | } | ||
2674 | break; | 2823 | break; |
2675 | } | ||
2676 | 2824 | ||
2677 | case FALCON_REV_B0: | 2825 | case FALCON_REV_B0: |
2678 | break; | 2826 | break; |
@@ -2682,6 +2830,9 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) | |||
2682 | return -ENODEV; | 2830 | return -ENODEV; |
2683 | } | 2831 | } |
2684 | 2832 | ||
2833 | /* Initial assumed speed */ | ||
2834 | efx->link_speed = EFX_OWORD_FIELD(nic_stat, STRAP_10G) ? 10000 : 1000; | ||
2835 | |||
2685 | return 0; | 2836 | return 0; |
2686 | } | 2837 | } |
2687 | 2838 | ||
@@ -2689,80 +2840,37 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) | |||
2689 | static void falcon_probe_spi_devices(struct efx_nic *efx) | 2840 | static void falcon_probe_spi_devices(struct efx_nic *efx) |
2690 | { | 2841 | { |
2691 | efx_oword_t nic_stat, gpio_ctl, ee_vpd_cfg; | 2842 | efx_oword_t nic_stat, gpio_ctl, ee_vpd_cfg; |
2692 | bool has_flash, has_eeprom, boot_is_external; | 2843 | int boot_dev; |
2693 | 2844 | ||
2694 | falcon_read(efx, &gpio_ctl, GPIO_CTL_REG_KER); | 2845 | falcon_read(efx, &gpio_ctl, GPIO_CTL_REG_KER); |
2695 | falcon_read(efx, &nic_stat, NIC_STAT_REG); | 2846 | falcon_read(efx, &nic_stat, NIC_STAT_REG); |
2696 | falcon_read(efx, &ee_vpd_cfg, EE_VPD_CFG_REG_KER); | 2847 | falcon_read(efx, &ee_vpd_cfg, EE_VPD_CFG_REG_KER); |
2697 | 2848 | ||
2698 | has_flash = EFX_OWORD_FIELD(nic_stat, SF_PRST); | 2849 | if (EFX_OWORD_FIELD(gpio_ctl, BOOTED_USING_NVDEVICE)) { |
2699 | has_eeprom = EFX_OWORD_FIELD(nic_stat, EE_PRST); | 2850 | boot_dev = (EFX_OWORD_FIELD(nic_stat, SF_PRST) ? |
2700 | boot_is_external = EFX_OWORD_FIELD(gpio_ctl, BOOTED_USING_NVDEVICE); | 2851 | EE_SPI_FLASH : EE_SPI_EEPROM); |
2701 | 2852 | EFX_LOG(efx, "Booted from %s\n", | |
2702 | if (has_flash) { | 2853 | boot_dev == EE_SPI_FLASH ? "flash" : "EEPROM"); |
2703 | /* Default flash SPI device: Atmel AT25F1024 | 2854 | } else { |
2704 | * 128 KB, 24-bit address, 32 KB erase block, | 2855 | /* Disable VPD and set clock dividers to safe |
2705 | * 256 B write block | 2856 | * values for initial programming. */ |
2706 | */ | 2857 | boot_dev = -1; |
2707 | u32 flash_device_type = | 2858 | EFX_LOG(efx, "Booted from internal ASIC settings;" |
2708 | (17 << SPI_DEV_TYPE_SIZE_LBN) | 2859 | " setting SPI config\n"); |
2709 | | (3 << SPI_DEV_TYPE_ADDR_LEN_LBN) | 2860 | EFX_POPULATE_OWORD_3(ee_vpd_cfg, EE_VPD_EN, 0, |
2710 | | (0x52 << SPI_DEV_TYPE_ERASE_CMD_LBN) | 2861 | /* 125 MHz / 7 ~= 20 MHz */ |
2711 | | (15 << SPI_DEV_TYPE_ERASE_SIZE_LBN) | 2862 | EE_SF_CLOCK_DIV, 7, |
2712 | | (8 << SPI_DEV_TYPE_BLOCK_SIZE_LBN); | 2863 | /* 125 MHz / 63 ~= 2 MHz */ |
2713 | 2864 | EE_EE_CLOCK_DIV, 63); | |
2714 | falcon_spi_device_init(efx, &efx->spi_flash, | 2865 | falcon_write(efx, &ee_vpd_cfg, EE_VPD_CFG_REG_KER); |
2715 | EE_SPI_FLASH, flash_device_type); | 2866 | } |
2716 | 2867 | ||
2717 | if (!boot_is_external) { | 2868 | if (boot_dev == EE_SPI_FLASH) |
2718 | /* Disable VPD and set clock dividers to safe | 2869 | falcon_spi_device_init(efx, &efx->spi_flash, EE_SPI_FLASH, |
2719 | * values for initial programming. | 2870 | default_flash_type); |
2720 | */ | 2871 | if (boot_dev == EE_SPI_EEPROM) |
2721 | EFX_LOG(efx, "Booted from internal ASIC settings;" | 2872 | falcon_spi_device_init(efx, &efx->spi_eeprom, EE_SPI_EEPROM, |
2722 | " setting SPI config\n"); | 2873 | large_eeprom_type); |
2723 | EFX_POPULATE_OWORD_3(ee_vpd_cfg, EE_VPD_EN, 0, | ||
2724 | /* 125 MHz / 7 ~= 20 MHz */ | ||
2725 | EE_SF_CLOCK_DIV, 7, | ||
2726 | /* 125 MHz / 63 ~= 2 MHz */ | ||
2727 | EE_EE_CLOCK_DIV, 63); | ||
2728 | falcon_write(efx, &ee_vpd_cfg, EE_VPD_CFG_REG_KER); | ||
2729 | } | ||
2730 | } | ||
2731 | |||
2732 | if (has_eeprom) { | ||
2733 | u32 eeprom_device_type; | ||
2734 | |||
2735 | /* If it has no flash, it must have a large EEPROM | ||
2736 | * for chip config; otherwise check whether 9-bit | ||
2737 | * addressing is used for VPD configuration | ||
2738 | */ | ||
2739 | if (has_flash && | ||
2740 | (!boot_is_external || | ||
2741 | EFX_OWORD_FIELD(ee_vpd_cfg, EE_VPD_EN_AD9_MODE))) { | ||
2742 | /* Default SPI device: Atmel AT25040 or similar | ||
2743 | * 512 B, 9-bit address, 8 B write block | ||
2744 | */ | ||
2745 | eeprom_device_type = | ||
2746 | (9 << SPI_DEV_TYPE_SIZE_LBN) | ||
2747 | | (1 << SPI_DEV_TYPE_ADDR_LEN_LBN) | ||
2748 | | (3 << SPI_DEV_TYPE_BLOCK_SIZE_LBN); | ||
2749 | } else { | ||
2750 | /* "Large" SPI device: Atmel AT25640 or similar | ||
2751 | * 8 KB, 16-bit address, 32 B write block | ||
2752 | */ | ||
2753 | eeprom_device_type = | ||
2754 | (13 << SPI_DEV_TYPE_SIZE_LBN) | ||
2755 | | (2 << SPI_DEV_TYPE_ADDR_LEN_LBN) | ||
2756 | | (5 << SPI_DEV_TYPE_BLOCK_SIZE_LBN); | ||
2757 | } | ||
2758 | |||
2759 | falcon_spi_device_init(efx, &efx->spi_eeprom, | ||
2760 | EE_SPI_EEPROM, eeprom_device_type); | ||
2761 | } | ||
2762 | |||
2763 | EFX_LOG(efx, "flash is %s, EEPROM is %s\n", | ||
2764 | (has_flash ? "present" : "absent"), | ||
2765 | (has_eeprom ? "present" : "absent")); | ||
2766 | } | 2874 | } |
2767 | 2875 | ||
2768 | int falcon_probe_nic(struct efx_nic *efx) | 2876 | int falcon_probe_nic(struct efx_nic *efx) |
@@ -2813,9 +2921,9 @@ int falcon_probe_nic(struct efx_nic *efx) | |||
2813 | goto fail4; | 2921 | goto fail4; |
2814 | BUG_ON(efx->irq_status.dma_addr & 0x0f); | 2922 | BUG_ON(efx->irq_status.dma_addr & 0x0f); |
2815 | 2923 | ||
2816 | EFX_LOG(efx, "INT_KER at %llx (virt %p phys %lx)\n", | 2924 | EFX_LOG(efx, "INT_KER at %llx (virt %p phys %llx)\n", |
2817 | (unsigned long long)efx->irq_status.dma_addr, | 2925 | (u64)efx->irq_status.dma_addr, |
2818 | efx->irq_status.addr, virt_to_phys(efx->irq_status.addr)); | 2926 | efx->irq_status.addr, (u64)virt_to_phys(efx->irq_status.addr)); |
2819 | 2927 | ||
2820 | falcon_probe_spi_devices(efx); | 2928 | falcon_probe_spi_devices(efx); |
2821 | 2929 | ||
@@ -2825,10 +2933,10 @@ int falcon_probe_nic(struct efx_nic *efx) | |||
2825 | goto fail5; | 2933 | goto fail5; |
2826 | 2934 | ||
2827 | /* Initialise I2C adapter */ | 2935 | /* Initialise I2C adapter */ |
2828 | efx->i2c_adap.owner = THIS_MODULE; | 2936 | efx->i2c_adap.owner = THIS_MODULE; |
2829 | nic_data->i2c_data = falcon_i2c_bit_operations; | 2937 | nic_data->i2c_data = falcon_i2c_bit_operations; |
2830 | nic_data->i2c_data.data = efx; | 2938 | nic_data->i2c_data.data = efx; |
2831 | efx->i2c_adap.algo_data = &nic_data->i2c_data; | 2939 | efx->i2c_adap.algo_data = &nic_data->i2c_data; |
2832 | efx->i2c_adap.dev.parent = &efx->pci_dev->dev; | 2940 | efx->i2c_adap.dev.parent = &efx->pci_dev->dev; |
2833 | strlcpy(efx->i2c_adap.name, "SFC4000 GPIO", sizeof(efx->i2c_adap.name)); | 2941 | strlcpy(efx->i2c_adap.name, "SFC4000 GPIO", sizeof(efx->i2c_adap.name)); |
2834 | rc = i2c_bit_add_bus(&efx->i2c_adap); | 2942 | rc = i2c_bit_add_bus(&efx->i2c_adap); |
@@ -2862,20 +2970,18 @@ int falcon_init_nic(struct efx_nic *efx) | |||
2862 | unsigned thresh; | 2970 | unsigned thresh; |
2863 | int rc; | 2971 | int rc; |
2864 | 2972 | ||
2865 | /* Set up the address region register. This is only needed | ||
2866 | * for the B0 FPGA, but since we are just pushing in the | ||
2867 | * reset defaults this may as well be unconditional. */ | ||
2868 | EFX_POPULATE_OWORD_4(temp, ADR_REGION0, 0, | ||
2869 | ADR_REGION1, (1 << 16), | ||
2870 | ADR_REGION2, (2 << 16), | ||
2871 | ADR_REGION3, (3 << 16)); | ||
2872 | falcon_write(efx, &temp, ADR_REGION_REG_KER); | ||
2873 | |||
2874 | /* Use on-chip SRAM */ | 2973 | /* Use on-chip SRAM */ |
2875 | falcon_read(efx, &temp, NIC_STAT_REG); | 2974 | falcon_read(efx, &temp, NIC_STAT_REG); |
2876 | EFX_SET_OWORD_FIELD(temp, ONCHIP_SRAM, 1); | 2975 | EFX_SET_OWORD_FIELD(temp, ONCHIP_SRAM, 1); |
2877 | falcon_write(efx, &temp, NIC_STAT_REG); | 2976 | falcon_write(efx, &temp, NIC_STAT_REG); |
2878 | 2977 | ||
2978 | /* Set the source of the GMAC clock */ | ||
2979 | if (falcon_rev(efx) == FALCON_REV_B0) { | ||
2980 | falcon_read(efx, &temp, GPIO_CTL_REG_KER); | ||
2981 | EFX_SET_OWORD_FIELD(temp, GPIO_USE_NIC_CLK, true); | ||
2982 | falcon_write(efx, &temp, GPIO_CTL_REG_KER); | ||
2983 | } | ||
2984 | |||
2879 | /* Set buffer table mode */ | 2985 | /* Set buffer table mode */ |
2880 | EFX_POPULATE_OWORD_1(temp, BUF_TBL_MODE, BUF_TBL_MODE_FULL); | 2986 | EFX_POPULATE_OWORD_1(temp, BUF_TBL_MODE, BUF_TBL_MODE_FULL); |
2881 | falcon_write(efx, &temp, BUF_TBL_CFG_REG_KER); | 2987 | falcon_write(efx, &temp, BUF_TBL_CFG_REG_KER); |
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h index be025ba7a6c6..7869c3d74383 100644 --- a/drivers/net/sfc/falcon.h +++ b/drivers/net/sfc/falcon.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #define EFX_FALCON_H | 12 | #define EFX_FALCON_H |
13 | 13 | ||
14 | #include "net_driver.h" | 14 | #include "net_driver.h" |
15 | #include "efx.h" | ||
15 | 16 | ||
16 | /* | 17 | /* |
17 | * Falcon hardware control | 18 | * Falcon hardware control |
@@ -65,6 +66,7 @@ extern int falcon_probe_port(struct efx_nic *efx); | |||
65 | extern void falcon_remove_port(struct efx_nic *efx); | 66 | extern void falcon_remove_port(struct efx_nic *efx); |
66 | 67 | ||
67 | /* MAC/PHY */ | 68 | /* MAC/PHY */ |
69 | extern int falcon_switch_mac(struct efx_nic *efx); | ||
68 | extern bool falcon_xaui_link_ok(struct efx_nic *efx); | 70 | extern bool falcon_xaui_link_ok(struct efx_nic *efx); |
69 | extern int falcon_dma_stats(struct efx_nic *efx, | 71 | extern int falcon_dma_stats(struct efx_nic *efx, |
70 | unsigned int done_offset); | 72 | unsigned int done_offset); |
@@ -77,6 +79,7 @@ extern int falcon_init_interrupt(struct efx_nic *efx); | |||
77 | extern void falcon_enable_interrupts(struct efx_nic *efx); | 79 | extern void falcon_enable_interrupts(struct efx_nic *efx); |
78 | extern void falcon_generate_test_event(struct efx_channel *channel, | 80 | extern void falcon_generate_test_event(struct efx_channel *channel, |
79 | unsigned int magic); | 81 | unsigned int magic); |
82 | extern void falcon_sim_phy_event(struct efx_nic *efx); | ||
80 | extern void falcon_generate_interrupt(struct efx_nic *efx); | 83 | extern void falcon_generate_interrupt(struct efx_nic *efx); |
81 | extern void falcon_set_int_moderation(struct efx_channel *channel); | 84 | extern void falcon_set_int_moderation(struct efx_channel *channel); |
82 | extern void falcon_disable_interrupts(struct efx_nic *efx); | 85 | extern void falcon_disable_interrupts(struct efx_nic *efx); |
diff --git a/drivers/net/sfc/falcon_gmac.c b/drivers/net/sfc/falcon_gmac.c new file mode 100644 index 000000000000..8865eae20ac5 --- /dev/null +++ b/drivers/net/sfc/falcon_gmac.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /**************************************************************************** | ||
2 | * Driver for Solarflare Solarstorm network controllers and boards | ||
3 | * Copyright 2005-2006 Fen Systems Ltd. | ||
4 | * Copyright 2006-2008 Solarflare Communications Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published | ||
8 | * by the Free Software Foundation, incorporated herein by reference. | ||
9 | */ | ||
10 | |||
11 | #include <linux/delay.h> | ||
12 | #include "net_driver.h" | ||
13 | #include "efx.h" | ||
14 | #include "falcon.h" | ||
15 | #include "mac.h" | ||
16 | #include "falcon_hwdefs.h" | ||
17 | #include "falcon_io.h" | ||
18 | #include "gmii.h" | ||
19 | |||
20 | /************************************************************************** | ||
21 | * | ||
22 | * MAC operations | ||
23 | * | ||
24 | *************************************************************************/ | ||
25 | |||
26 | static void falcon_reconfigure_gmac(struct efx_nic *efx) | ||
27 | { | ||
28 | bool loopback, tx_fc, rx_fc, bytemode; | ||
29 | int if_mode; | ||
30 | unsigned int max_frame_len; | ||
31 | efx_oword_t reg; | ||
32 | |||
33 | /* Configuration register 1 */ | ||
34 | tx_fc = (efx->link_fc & EFX_FC_TX) || !efx->link_fd; | ||
35 | rx_fc = !!(efx->link_fc & EFX_FC_RX); | ||
36 | loopback = (efx->loopback_mode == LOOPBACK_GMAC); | ||
37 | bytemode = (efx->link_speed == 1000); | ||
38 | |||
39 | EFX_POPULATE_OWORD_5(reg, | ||
40 | GM_LOOP, loopback, | ||
41 | GM_TX_EN, 1, | ||
42 | GM_TX_FC_EN, tx_fc, | ||
43 | GM_RX_EN, 1, | ||
44 | GM_RX_FC_EN, rx_fc); | ||
45 | falcon_write(efx, ®, GM_CFG1_REG); | ||
46 | udelay(10); | ||
47 | |||
48 | /* Configuration register 2 */ | ||
49 | if_mode = (bytemode) ? 2 : 1; | ||
50 | EFX_POPULATE_OWORD_5(reg, | ||
51 | GM_IF_MODE, if_mode, | ||
52 | GM_PAD_CRC_EN, 1, | ||
53 | GM_LEN_CHK, 1, | ||
54 | GM_FD, efx->link_fd, | ||
55 | GM_PAMBL_LEN, 0x7/*datasheet recommended */); | ||
56 | |||
57 | falcon_write(efx, ®, GM_CFG2_REG); | ||
58 | udelay(10); | ||
59 | |||
60 | /* Max frame len register */ | ||
61 | max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu); | ||
62 | EFX_POPULATE_OWORD_1(reg, GM_MAX_FLEN, max_frame_len); | ||
63 | falcon_write(efx, ®, GM_MAX_FLEN_REG); | ||
64 | udelay(10); | ||
65 | |||
66 | /* FIFO configuration register 0 */ | ||
67 | EFX_POPULATE_OWORD_5(reg, | ||
68 | GMF_FTFENREQ, 1, | ||
69 | GMF_STFENREQ, 1, | ||
70 | GMF_FRFENREQ, 1, | ||
71 | GMF_SRFENREQ, 1, | ||
72 | GMF_WTMENREQ, 1); | ||
73 | falcon_write(efx, ®, GMF_CFG0_REG); | ||
74 | udelay(10); | ||
75 | |||
76 | /* FIFO configuration register 1 */ | ||
77 | EFX_POPULATE_OWORD_2(reg, | ||
78 | GMF_CFGFRTH, 0x12, | ||
79 | GMF_CFGXOFFRTX, 0xffff); | ||
80 | falcon_write(efx, ®, GMF_CFG1_REG); | ||
81 | udelay(10); | ||
82 | |||
83 | /* FIFO configuration register 2 */ | ||
84 | EFX_POPULATE_OWORD_2(reg, | ||
85 | GMF_CFGHWM, 0x3f, | ||
86 | GMF_CFGLWM, 0xa); | ||
87 | falcon_write(efx, ®, GMF_CFG2_REG); | ||
88 | udelay(10); | ||
89 | |||
90 | /* FIFO configuration register 3 */ | ||
91 | EFX_POPULATE_OWORD_2(reg, | ||
92 | GMF_CFGHWMFT, 0x1c, | ||
93 | GMF_CFGFTTH, 0x08); | ||
94 | falcon_write(efx, ®, GMF_CFG3_REG); | ||
95 | udelay(10); | ||
96 | |||
97 | /* FIFO configuration register 4 */ | ||
98 | EFX_POPULATE_OWORD_1(reg, GMF_HSTFLTRFRM_PAUSE, 1); | ||
99 | falcon_write(efx, ®, GMF_CFG4_REG); | ||
100 | udelay(10); | ||
101 | |||
102 | /* FIFO configuration register 5 */ | ||
103 | falcon_read(efx, ®, GMF_CFG5_REG); | ||
104 | EFX_SET_OWORD_FIELD(reg, GMF_CFGBYTMODE, bytemode); | ||
105 | EFX_SET_OWORD_FIELD(reg, GMF_CFGHDPLX, !efx->link_fd); | ||
106 | EFX_SET_OWORD_FIELD(reg, GMF_HSTDRPLT64, !efx->link_fd); | ||
107 | EFX_SET_OWORD_FIELD(reg, GMF_HSTFLTRFRMDC_PAUSE, 0); | ||
108 | falcon_write(efx, ®, GMF_CFG5_REG); | ||
109 | udelay(10); | ||
110 | |||
111 | /* MAC address */ | ||
112 | EFX_POPULATE_OWORD_4(reg, | ||
113 | GM_HWADDR_5, efx->net_dev->dev_addr[5], | ||
114 | GM_HWADDR_4, efx->net_dev->dev_addr[4], | ||
115 | GM_HWADDR_3, efx->net_dev->dev_addr[3], | ||
116 | GM_HWADDR_2, efx->net_dev->dev_addr[2]); | ||
117 | falcon_write(efx, ®, GM_ADR1_REG); | ||
118 | udelay(10); | ||
119 | EFX_POPULATE_OWORD_2(reg, | ||
120 | GM_HWADDR_1, efx->net_dev->dev_addr[1], | ||
121 | GM_HWADDR_0, efx->net_dev->dev_addr[0]); | ||
122 | falcon_write(efx, ®, GM_ADR2_REG); | ||
123 | udelay(10); | ||
124 | |||
125 | falcon_reconfigure_mac_wrapper(efx); | ||
126 | } | ||
127 | |||
128 | static void falcon_update_stats_gmac(struct efx_nic *efx) | ||
129 | { | ||
130 | struct efx_mac_stats *mac_stats = &efx->mac_stats; | ||
131 | unsigned long old_rx_pause, old_tx_pause; | ||
132 | unsigned long new_rx_pause, new_tx_pause; | ||
133 | int rc; | ||
134 | |||
135 | rc = falcon_dma_stats(efx, GDmaDone_offset); | ||
136 | if (rc) | ||
137 | return; | ||
138 | |||
139 | /* Pause frames are erroneously counted as errors (SFC bug 3269) */ | ||
140 | old_rx_pause = mac_stats->rx_pause; | ||
141 | old_tx_pause = mac_stats->tx_pause; | ||
142 | |||
143 | /* Update MAC stats from DMAed values */ | ||
144 | FALCON_STAT(efx, GRxGoodOct, rx_good_bytes); | ||
145 | FALCON_STAT(efx, GRxBadOct, rx_bad_bytes); | ||
146 | FALCON_STAT(efx, GRxMissPkt, rx_missed); | ||
147 | FALCON_STAT(efx, GRxFalseCRS, rx_false_carrier); | ||
148 | FALCON_STAT(efx, GRxPausePkt, rx_pause); | ||
149 | FALCON_STAT(efx, GRxBadPkt, rx_bad); | ||
150 | FALCON_STAT(efx, GRxUcastPkt, rx_unicast); | ||
151 | FALCON_STAT(efx, GRxMcastPkt, rx_multicast); | ||
152 | FALCON_STAT(efx, GRxBcastPkt, rx_broadcast); | ||
153 | FALCON_STAT(efx, GRxGoodLt64Pkt, rx_good_lt64); | ||
154 | FALCON_STAT(efx, GRxBadLt64Pkt, rx_bad_lt64); | ||
155 | FALCON_STAT(efx, GRx64Pkt, rx_64); | ||
156 | FALCON_STAT(efx, GRx65to127Pkt, rx_65_to_127); | ||
157 | FALCON_STAT(efx, GRx128to255Pkt, rx_128_to_255); | ||
158 | FALCON_STAT(efx, GRx256to511Pkt, rx_256_to_511); | ||
159 | FALCON_STAT(efx, GRx512to1023Pkt, rx_512_to_1023); | ||
160 | FALCON_STAT(efx, GRx1024to15xxPkt, rx_1024_to_15xx); | ||
161 | FALCON_STAT(efx, GRx15xxtoJumboPkt, rx_15xx_to_jumbo); | ||
162 | FALCON_STAT(efx, GRxGtJumboPkt, rx_gtjumbo); | ||
163 | FALCON_STAT(efx, GRxFcsErr64to15xxPkt, rx_bad_64_to_15xx); | ||
164 | FALCON_STAT(efx, GRxFcsErr15xxtoJumboPkt, rx_bad_15xx_to_jumbo); | ||
165 | FALCON_STAT(efx, GRxFcsErrGtJumboPkt, rx_bad_gtjumbo); | ||
166 | FALCON_STAT(efx, GTxGoodBadOct, tx_bytes); | ||
167 | FALCON_STAT(efx, GTxGoodOct, tx_good_bytes); | ||
168 | FALCON_STAT(efx, GTxSglColPkt, tx_single_collision); | ||
169 | FALCON_STAT(efx, GTxMultColPkt, tx_multiple_collision); | ||
170 | FALCON_STAT(efx, GTxExColPkt, tx_excessive_collision); | ||
171 | FALCON_STAT(efx, GTxDefPkt, tx_deferred); | ||
172 | FALCON_STAT(efx, GTxLateCol, tx_late_collision); | ||
173 | FALCON_STAT(efx, GTxExDefPkt, tx_excessive_deferred); | ||
174 | FALCON_STAT(efx, GTxPausePkt, tx_pause); | ||
175 | FALCON_STAT(efx, GTxBadPkt, tx_bad); | ||
176 | FALCON_STAT(efx, GTxUcastPkt, tx_unicast); | ||
177 | FALCON_STAT(efx, GTxMcastPkt, tx_multicast); | ||
178 | FALCON_STAT(efx, GTxBcastPkt, tx_broadcast); | ||
179 | FALCON_STAT(efx, GTxLt64Pkt, tx_lt64); | ||
180 | FALCON_STAT(efx, GTx64Pkt, tx_64); | ||
181 | FALCON_STAT(efx, GTx65to127Pkt, tx_65_to_127); | ||
182 | FALCON_STAT(efx, GTx128to255Pkt, tx_128_to_255); | ||
183 | FALCON_STAT(efx, GTx256to511Pkt, tx_256_to_511); | ||
184 | FALCON_STAT(efx, GTx512to1023Pkt, tx_512_to_1023); | ||
185 | FALCON_STAT(efx, GTx1024to15xxPkt, tx_1024_to_15xx); | ||
186 | FALCON_STAT(efx, GTx15xxtoJumboPkt, tx_15xx_to_jumbo); | ||
187 | FALCON_STAT(efx, GTxGtJumboPkt, tx_gtjumbo); | ||
188 | FALCON_STAT(efx, GTxNonTcpUdpPkt, tx_non_tcpudp); | ||
189 | FALCON_STAT(efx, GTxMacSrcErrPkt, tx_mac_src_error); | ||
190 | FALCON_STAT(efx, GTxIpSrcErrPkt, tx_ip_src_error); | ||
191 | |||
192 | /* Pause frames are erroneously counted as errors (SFC bug 3269) */ | ||
193 | new_rx_pause = mac_stats->rx_pause; | ||
194 | new_tx_pause = mac_stats->tx_pause; | ||
195 | mac_stats->rx_bad -= (new_rx_pause - old_rx_pause); | ||
196 | mac_stats->tx_bad -= (new_tx_pause - old_tx_pause); | ||
197 | |||
198 | /* Derive stats that the MAC doesn't provide directly */ | ||
199 | mac_stats->tx_bad_bytes = | ||
200 | mac_stats->tx_bytes - mac_stats->tx_good_bytes; | ||
201 | mac_stats->tx_packets = | ||
202 | mac_stats->tx_lt64 + mac_stats->tx_64 + | ||
203 | mac_stats->tx_65_to_127 + mac_stats->tx_128_to_255 + | ||
204 | mac_stats->tx_256_to_511 + mac_stats->tx_512_to_1023 + | ||
205 | mac_stats->tx_1024_to_15xx + mac_stats->tx_15xx_to_jumbo + | ||
206 | mac_stats->tx_gtjumbo; | ||
207 | mac_stats->tx_collision = | ||
208 | mac_stats->tx_single_collision + | ||
209 | mac_stats->tx_multiple_collision + | ||
210 | mac_stats->tx_excessive_collision + | ||
211 | mac_stats->tx_late_collision; | ||
212 | mac_stats->rx_bytes = | ||
213 | mac_stats->rx_good_bytes + mac_stats->rx_bad_bytes; | ||
214 | mac_stats->rx_packets = | ||
215 | mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64 + | ||
216 | mac_stats->rx_64 + mac_stats->rx_65_to_127 + | ||
217 | mac_stats->rx_128_to_255 + mac_stats->rx_256_to_511 + | ||
218 | mac_stats->rx_512_to_1023 + mac_stats->rx_1024_to_15xx + | ||
219 | mac_stats->rx_15xx_to_jumbo + mac_stats->rx_gtjumbo; | ||
220 | mac_stats->rx_good = mac_stats->rx_packets - mac_stats->rx_bad; | ||
221 | mac_stats->rx_lt64 = mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64; | ||
222 | } | ||
223 | |||
224 | struct efx_mac_operations falcon_gmac_operations = { | ||
225 | .reconfigure = falcon_reconfigure_gmac, | ||
226 | .update_stats = falcon_update_stats_gmac, | ||
227 | .irq = efx_port_dummy_op_void, | ||
228 | .poll = efx_port_dummy_op_void, | ||
229 | }; | ||
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h index 5d584b0dbb51..bda8d5bb72e4 100644 --- a/drivers/net/sfc/falcon_hwdefs.h +++ b/drivers/net/sfc/falcon_hwdefs.h | |||
@@ -111,12 +111,18 @@ | |||
111 | 111 | ||
112 | /* NIC status register */ | 112 | /* NIC status register */ |
113 | #define NIC_STAT_REG 0x0200 | 113 | #define NIC_STAT_REG 0x0200 |
114 | #define EE_STRAP_EN_LBN 31 | ||
115 | #define EE_STRAP_EN_WIDTH 1 | ||
116 | #define EE_STRAP_OVR_LBN 24 | ||
117 | #define EE_STRAP_OVR_WIDTH 4 | ||
114 | #define ONCHIP_SRAM_LBN 16 | 118 | #define ONCHIP_SRAM_LBN 16 |
115 | #define ONCHIP_SRAM_WIDTH 1 | 119 | #define ONCHIP_SRAM_WIDTH 1 |
116 | #define SF_PRST_LBN 9 | 120 | #define SF_PRST_LBN 9 |
117 | #define SF_PRST_WIDTH 1 | 121 | #define SF_PRST_WIDTH 1 |
118 | #define EE_PRST_LBN 8 | 122 | #define EE_PRST_LBN 8 |
119 | #define EE_PRST_WIDTH 1 | 123 | #define EE_PRST_WIDTH 1 |
124 | #define STRAP_PINS_LBN 0 | ||
125 | #define STRAP_PINS_WIDTH 3 | ||
120 | /* These bit definitions are extrapolated from the list of numerical | 126 | /* These bit definitions are extrapolated from the list of numerical |
121 | * values for STRAP_PINS. | 127 | * values for STRAP_PINS. |
122 | */ | 128 | */ |
@@ -130,6 +136,8 @@ | |||
130 | 136 | ||
131 | /* GPIO control register */ | 137 | /* GPIO control register */ |
132 | #define GPIO_CTL_REG_KER 0x0210 | 138 | #define GPIO_CTL_REG_KER 0x0210 |
139 | #define GPIO_USE_NIC_CLK_LBN (30) | ||
140 | #define GPIO_USE_NIC_CLK_WIDTH (1) | ||
133 | #define GPIO_OUTPUTS_LBN (16) | 141 | #define GPIO_OUTPUTS_LBN (16) |
134 | #define GPIO_OUTPUTS_WIDTH (4) | 142 | #define GPIO_OUTPUTS_WIDTH (4) |
135 | #define GPIO_INPUTS_LBN (8) | 143 | #define GPIO_INPUTS_LBN (8) |
@@ -492,6 +500,107 @@ | |||
492 | #define MAC_MCAST_HASH_REG0_KER 0xca0 | 500 | #define MAC_MCAST_HASH_REG0_KER 0xca0 |
493 | #define MAC_MCAST_HASH_REG1_KER 0xcb0 | 501 | #define MAC_MCAST_HASH_REG1_KER 0xcb0 |
494 | 502 | ||
503 | /* GMAC configuration register 1 */ | ||
504 | #define GM_CFG1_REG 0xe00 | ||
505 | #define GM_SW_RST_LBN 31 | ||
506 | #define GM_SW_RST_WIDTH 1 | ||
507 | #define GM_LOOP_LBN 8 | ||
508 | #define GM_LOOP_WIDTH 1 | ||
509 | #define GM_RX_FC_EN_LBN 5 | ||
510 | #define GM_RX_FC_EN_WIDTH 1 | ||
511 | #define GM_TX_FC_EN_LBN 4 | ||
512 | #define GM_TX_FC_EN_WIDTH 1 | ||
513 | #define GM_RX_EN_LBN 2 | ||
514 | #define GM_RX_EN_WIDTH 1 | ||
515 | #define GM_TX_EN_LBN 0 | ||
516 | #define GM_TX_EN_WIDTH 1 | ||
517 | |||
518 | /* GMAC configuration register 2 */ | ||
519 | #define GM_CFG2_REG 0xe10 | ||
520 | #define GM_PAMBL_LEN_LBN 12 | ||
521 | #define GM_PAMBL_LEN_WIDTH 4 | ||
522 | #define GM_IF_MODE_LBN 8 | ||
523 | #define GM_IF_MODE_WIDTH 2 | ||
524 | #define GM_LEN_CHK_LBN 4 | ||
525 | #define GM_LEN_CHK_WIDTH 1 | ||
526 | #define GM_PAD_CRC_EN_LBN 2 | ||
527 | #define GM_PAD_CRC_EN_WIDTH 1 | ||
528 | #define GM_FD_LBN 0 | ||
529 | #define GM_FD_WIDTH 1 | ||
530 | |||
531 | /* GMAC maximum frame length register */ | ||
532 | #define GM_MAX_FLEN_REG 0xe40 | ||
533 | #define GM_MAX_FLEN_LBN 0 | ||
534 | #define GM_MAX_FLEN_WIDTH 16 | ||
535 | |||
536 | /* GMAC station address register 1 */ | ||
537 | #define GM_ADR1_REG 0xf00 | ||
538 | #define GM_HWADDR_5_LBN 24 | ||
539 | #define GM_HWADDR_5_WIDTH 8 | ||
540 | #define GM_HWADDR_4_LBN 16 | ||
541 | #define GM_HWADDR_4_WIDTH 8 | ||
542 | #define GM_HWADDR_3_LBN 8 | ||
543 | #define GM_HWADDR_3_WIDTH 8 | ||
544 | #define GM_HWADDR_2_LBN 0 | ||
545 | #define GM_HWADDR_2_WIDTH 8 | ||
546 | |||
547 | /* GMAC station address register 2 */ | ||
548 | #define GM_ADR2_REG 0xf10 | ||
549 | #define GM_HWADDR_1_LBN 24 | ||
550 | #define GM_HWADDR_1_WIDTH 8 | ||
551 | #define GM_HWADDR_0_LBN 16 | ||
552 | #define GM_HWADDR_0_WIDTH 8 | ||
553 | |||
554 | /* GMAC FIFO configuration register 0 */ | ||
555 | #define GMF_CFG0_REG 0xf20 | ||
556 | #define GMF_FTFENREQ_LBN 12 | ||
557 | #define GMF_FTFENREQ_WIDTH 1 | ||
558 | #define GMF_STFENREQ_LBN 11 | ||
559 | #define GMF_STFENREQ_WIDTH 1 | ||
560 | #define GMF_FRFENREQ_LBN 10 | ||
561 | #define GMF_FRFENREQ_WIDTH 1 | ||
562 | #define GMF_SRFENREQ_LBN 9 | ||
563 | #define GMF_SRFENREQ_WIDTH 1 | ||
564 | #define GMF_WTMENREQ_LBN 8 | ||
565 | #define GMF_WTMENREQ_WIDTH 1 | ||
566 | |||
567 | /* GMAC FIFO configuration register 1 */ | ||
568 | #define GMF_CFG1_REG 0xf30 | ||
569 | #define GMF_CFGFRTH_LBN 16 | ||
570 | #define GMF_CFGFRTH_WIDTH 5 | ||
571 | #define GMF_CFGXOFFRTX_LBN 0 | ||
572 | #define GMF_CFGXOFFRTX_WIDTH 16 | ||
573 | |||
574 | /* GMAC FIFO configuration register 2 */ | ||
575 | #define GMF_CFG2_REG 0xf40 | ||
576 | #define GMF_CFGHWM_LBN 16 | ||
577 | #define GMF_CFGHWM_WIDTH 6 | ||
578 | #define GMF_CFGLWM_LBN 0 | ||
579 | #define GMF_CFGLWM_WIDTH 6 | ||
580 | |||
581 | /* GMAC FIFO configuration register 3 */ | ||
582 | #define GMF_CFG3_REG 0xf50 | ||
583 | #define GMF_CFGHWMFT_LBN 16 | ||
584 | #define GMF_CFGHWMFT_WIDTH 6 | ||
585 | #define GMF_CFGFTTH_LBN 0 | ||
586 | #define GMF_CFGFTTH_WIDTH 6 | ||
587 | |||
588 | /* GMAC FIFO configuration register 4 */ | ||
589 | #define GMF_CFG4_REG 0xf60 | ||
590 | #define GMF_HSTFLTRFRM_PAUSE_LBN 12 | ||
591 | #define GMF_HSTFLTRFRM_PAUSE_WIDTH 12 | ||
592 | |||
593 | /* GMAC FIFO configuration register 5 */ | ||
594 | #define GMF_CFG5_REG 0xf70 | ||
595 | #define GMF_CFGHDPLX_LBN 22 | ||
596 | #define GMF_CFGHDPLX_WIDTH 1 | ||
597 | #define GMF_CFGBYTMODE_LBN 19 | ||
598 | #define GMF_CFGBYTMODE_WIDTH 1 | ||
599 | #define GMF_HSTDRPLT64_LBN 18 | ||
600 | #define GMF_HSTDRPLT64_WIDTH 1 | ||
601 | #define GMF_HSTFLTRFRMDC_PAUSE_LBN 12 | ||
602 | #define GMF_HSTFLTRFRMDC_PAUSE_WIDTH 1 | ||
603 | |||
495 | /* XGMAC address register low */ | 604 | /* XGMAC address register low */ |
496 | #define XM_ADR_LO_REG 0x1200 | 605 | #define XM_ADR_LO_REG 0x1200 |
497 | #define XM_ADR_3_LBN 24 | 606 | #define XM_ADR_3_LBN 24 |
@@ -944,6 +1053,8 @@ | |||
944 | #define XG_MNT_INTR_B0_WIDTH 1 | 1053 | #define XG_MNT_INTR_B0_WIDTH 1 |
945 | #define RX_RECOVERY_A1_LBN 11 | 1054 | #define RX_RECOVERY_A1_LBN 11 |
946 | #define RX_RECOVERY_A1_WIDTH 1 | 1055 | #define RX_RECOVERY_A1_WIDTH 1 |
1056 | #define XFP_PHY_INTR_LBN 10 | ||
1057 | #define XFP_PHY_INTR_WIDTH 1 | ||
947 | #define XG_PHY_INTR_LBN 9 | 1058 | #define XG_PHY_INTR_LBN 9 |
948 | #define XG_PHY_INTR_WIDTH 1 | 1059 | #define XG_PHY_INTR_WIDTH 1 |
949 | #define G_PHY1_INTR_LBN 8 | 1060 | #define G_PHY1_INTR_LBN 8 |
@@ -962,54 +1073,103 @@ | |||
962 | ************************************************************************** | 1073 | ************************************************************************** |
963 | * | 1074 | * |
964 | */ | 1075 | */ |
1076 | |||
965 | #define GRxGoodOct_offset 0x0 | 1077 | #define GRxGoodOct_offset 0x0 |
1078 | #define GRxGoodOct_WIDTH 48 | ||
966 | #define GRxBadOct_offset 0x8 | 1079 | #define GRxBadOct_offset 0x8 |
1080 | #define GRxBadOct_WIDTH 48 | ||
967 | #define GRxMissPkt_offset 0x10 | 1081 | #define GRxMissPkt_offset 0x10 |
1082 | #define GRxMissPkt_WIDTH 32 | ||
968 | #define GRxFalseCRS_offset 0x14 | 1083 | #define GRxFalseCRS_offset 0x14 |
1084 | #define GRxFalseCRS_WIDTH 32 | ||
969 | #define GRxPausePkt_offset 0x18 | 1085 | #define GRxPausePkt_offset 0x18 |
1086 | #define GRxPausePkt_WIDTH 32 | ||
970 | #define GRxBadPkt_offset 0x1C | 1087 | #define GRxBadPkt_offset 0x1C |
1088 | #define GRxBadPkt_WIDTH 32 | ||
971 | #define GRxUcastPkt_offset 0x20 | 1089 | #define GRxUcastPkt_offset 0x20 |
1090 | #define GRxUcastPkt_WIDTH 32 | ||
972 | #define GRxMcastPkt_offset 0x24 | 1091 | #define GRxMcastPkt_offset 0x24 |
1092 | #define GRxMcastPkt_WIDTH 32 | ||
973 | #define GRxBcastPkt_offset 0x28 | 1093 | #define GRxBcastPkt_offset 0x28 |
1094 | #define GRxBcastPkt_WIDTH 32 | ||
974 | #define GRxGoodLt64Pkt_offset 0x2C | 1095 | #define GRxGoodLt64Pkt_offset 0x2C |
1096 | #define GRxGoodLt64Pkt_WIDTH 32 | ||
975 | #define GRxBadLt64Pkt_offset 0x30 | 1097 | #define GRxBadLt64Pkt_offset 0x30 |
1098 | #define GRxBadLt64Pkt_WIDTH 32 | ||
976 | #define GRx64Pkt_offset 0x34 | 1099 | #define GRx64Pkt_offset 0x34 |
1100 | #define GRx64Pkt_WIDTH 32 | ||
977 | #define GRx65to127Pkt_offset 0x38 | 1101 | #define GRx65to127Pkt_offset 0x38 |
1102 | #define GRx65to127Pkt_WIDTH 32 | ||
978 | #define GRx128to255Pkt_offset 0x3C | 1103 | #define GRx128to255Pkt_offset 0x3C |
1104 | #define GRx128to255Pkt_WIDTH 32 | ||
979 | #define GRx256to511Pkt_offset 0x40 | 1105 | #define GRx256to511Pkt_offset 0x40 |
1106 | #define GRx256to511Pkt_WIDTH 32 | ||
980 | #define GRx512to1023Pkt_offset 0x44 | 1107 | #define GRx512to1023Pkt_offset 0x44 |
1108 | #define GRx512to1023Pkt_WIDTH 32 | ||
981 | #define GRx1024to15xxPkt_offset 0x48 | 1109 | #define GRx1024to15xxPkt_offset 0x48 |
1110 | #define GRx1024to15xxPkt_WIDTH 32 | ||
982 | #define GRx15xxtoJumboPkt_offset 0x4C | 1111 | #define GRx15xxtoJumboPkt_offset 0x4C |
1112 | #define GRx15xxtoJumboPkt_WIDTH 32 | ||
983 | #define GRxGtJumboPkt_offset 0x50 | 1113 | #define GRxGtJumboPkt_offset 0x50 |
1114 | #define GRxGtJumboPkt_WIDTH 32 | ||
984 | #define GRxFcsErr64to15xxPkt_offset 0x54 | 1115 | #define GRxFcsErr64to15xxPkt_offset 0x54 |
1116 | #define GRxFcsErr64to15xxPkt_WIDTH 32 | ||
985 | #define GRxFcsErr15xxtoJumboPkt_offset 0x58 | 1117 | #define GRxFcsErr15xxtoJumboPkt_offset 0x58 |
1118 | #define GRxFcsErr15xxtoJumboPkt_WIDTH 32 | ||
986 | #define GRxFcsErrGtJumboPkt_offset 0x5C | 1119 | #define GRxFcsErrGtJumboPkt_offset 0x5C |
1120 | #define GRxFcsErrGtJumboPkt_WIDTH 32 | ||
987 | #define GTxGoodBadOct_offset 0x80 | 1121 | #define GTxGoodBadOct_offset 0x80 |
1122 | #define GTxGoodBadOct_WIDTH 48 | ||
988 | #define GTxGoodOct_offset 0x88 | 1123 | #define GTxGoodOct_offset 0x88 |
1124 | #define GTxGoodOct_WIDTH 48 | ||
989 | #define GTxSglColPkt_offset 0x90 | 1125 | #define GTxSglColPkt_offset 0x90 |
1126 | #define GTxSglColPkt_WIDTH 32 | ||
990 | #define GTxMultColPkt_offset 0x94 | 1127 | #define GTxMultColPkt_offset 0x94 |
1128 | #define GTxMultColPkt_WIDTH 32 | ||
991 | #define GTxExColPkt_offset 0x98 | 1129 | #define GTxExColPkt_offset 0x98 |
1130 | #define GTxExColPkt_WIDTH 32 | ||
992 | #define GTxDefPkt_offset 0x9C | 1131 | #define GTxDefPkt_offset 0x9C |
1132 | #define GTxDefPkt_WIDTH 32 | ||
993 | #define GTxLateCol_offset 0xA0 | 1133 | #define GTxLateCol_offset 0xA0 |
1134 | #define GTxLateCol_WIDTH 32 | ||
994 | #define GTxExDefPkt_offset 0xA4 | 1135 | #define GTxExDefPkt_offset 0xA4 |
1136 | #define GTxExDefPkt_WIDTH 32 | ||
995 | #define GTxPausePkt_offset 0xA8 | 1137 | #define GTxPausePkt_offset 0xA8 |
1138 | #define GTxPausePkt_WIDTH 32 | ||
996 | #define GTxBadPkt_offset 0xAC | 1139 | #define GTxBadPkt_offset 0xAC |
1140 | #define GTxBadPkt_WIDTH 32 | ||
997 | #define GTxUcastPkt_offset 0xB0 | 1141 | #define GTxUcastPkt_offset 0xB0 |
1142 | #define GTxUcastPkt_WIDTH 32 | ||
998 | #define GTxMcastPkt_offset 0xB4 | 1143 | #define GTxMcastPkt_offset 0xB4 |
1144 | #define GTxMcastPkt_WIDTH 32 | ||
999 | #define GTxBcastPkt_offset 0xB8 | 1145 | #define GTxBcastPkt_offset 0xB8 |
1146 | #define GTxBcastPkt_WIDTH 32 | ||
1000 | #define GTxLt64Pkt_offset 0xBC | 1147 | #define GTxLt64Pkt_offset 0xBC |
1148 | #define GTxLt64Pkt_WIDTH 32 | ||
1001 | #define GTx64Pkt_offset 0xC0 | 1149 | #define GTx64Pkt_offset 0xC0 |
1150 | #define GTx64Pkt_WIDTH 32 | ||
1002 | #define GTx65to127Pkt_offset 0xC4 | 1151 | #define GTx65to127Pkt_offset 0xC4 |
1152 | #define GTx65to127Pkt_WIDTH 32 | ||
1003 | #define GTx128to255Pkt_offset 0xC8 | 1153 | #define GTx128to255Pkt_offset 0xC8 |
1154 | #define GTx128to255Pkt_WIDTH 32 | ||
1004 | #define GTx256to511Pkt_offset 0xCC | 1155 | #define GTx256to511Pkt_offset 0xCC |
1156 | #define GTx256to511Pkt_WIDTH 32 | ||
1005 | #define GTx512to1023Pkt_offset 0xD0 | 1157 | #define GTx512to1023Pkt_offset 0xD0 |
1158 | #define GTx512to1023Pkt_WIDTH 32 | ||
1006 | #define GTx1024to15xxPkt_offset 0xD4 | 1159 | #define GTx1024to15xxPkt_offset 0xD4 |
1160 | #define GTx1024to15xxPkt_WIDTH 32 | ||
1007 | #define GTx15xxtoJumboPkt_offset 0xD8 | 1161 | #define GTx15xxtoJumboPkt_offset 0xD8 |
1162 | #define GTx15xxtoJumboPkt_WIDTH 32 | ||
1008 | #define GTxGtJumboPkt_offset 0xDC | 1163 | #define GTxGtJumboPkt_offset 0xDC |
1164 | #define GTxGtJumboPkt_WIDTH 32 | ||
1009 | #define GTxNonTcpUdpPkt_offset 0xE0 | 1165 | #define GTxNonTcpUdpPkt_offset 0xE0 |
1166 | #define GTxNonTcpUdpPkt_WIDTH 16 | ||
1010 | #define GTxMacSrcErrPkt_offset 0xE4 | 1167 | #define GTxMacSrcErrPkt_offset 0xE4 |
1168 | #define GTxMacSrcErrPkt_WIDTH 16 | ||
1011 | #define GTxIpSrcErrPkt_offset 0xE8 | 1169 | #define GTxIpSrcErrPkt_offset 0xE8 |
1170 | #define GTxIpSrcErrPkt_WIDTH 16 | ||
1012 | #define GDmaDone_offset 0xEC | 1171 | #define GDmaDone_offset 0xEC |
1172 | #define GDmaDone_WIDTH 32 | ||
1013 | 1173 | ||
1014 | #define XgRxOctets_offset 0x0 | 1174 | #define XgRxOctets_offset 0x0 |
1015 | #define XgRxOctets_WIDTH 48 | 1175 | #define XgRxOctets_WIDTH 48 |
@@ -1150,7 +1310,6 @@ struct falcon_nvconfig_board_v3 { | |||
1150 | (((type) >> EFX_LOW_BIT(field)) & EFX_MASK32(EFX_WIDTH(field))) | 1310 | (((type) >> EFX_LOW_BIT(field)) & EFX_MASK32(EFX_WIDTH(field))) |
1151 | 1311 | ||
1152 | #define NVCONFIG_OFFSET 0x300 | 1312 | #define NVCONFIG_OFFSET 0x300 |
1153 | #define NVCONFIG_END 0x400 | ||
1154 | 1313 | ||
1155 | #define NVCONFIG_BOARD_MAGIC_NUM 0xFA1C | 1314 | #define NVCONFIG_BOARD_MAGIC_NUM 0xFA1C |
1156 | struct falcon_nvconfig { | 1315 | struct falcon_nvconfig { |
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index d4012314dd01..5a03713685ac 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include "falcon_hwdefs.h" | 15 | #include "falcon_hwdefs.h" |
16 | #include "falcon_io.h" | 16 | #include "falcon_io.h" |
17 | #include "mac.h" | 17 | #include "mac.h" |
18 | #include "gmii.h" | ||
19 | #include "mdio_10g.h" | 18 | #include "mdio_10g.h" |
20 | #include "phy.h" | 19 | #include "phy.h" |
21 | #include "boards.h" | 20 | #include "boards.h" |
@@ -26,24 +25,6 @@ | |||
26 | * MAC operations | 25 | * MAC operations |
27 | * | 26 | * |
28 | *************************************************************************/ | 27 | *************************************************************************/ |
29 | static int falcon_reset_xmac(struct efx_nic *efx) | ||
30 | { | ||
31 | efx_oword_t reg; | ||
32 | int count; | ||
33 | |||
34 | EFX_POPULATE_OWORD_1(reg, XM_CORE_RST, 1); | ||
35 | falcon_write(efx, ®, XM_GLB_CFG_REG); | ||
36 | |||
37 | for (count = 0; count < 10000; count++) { /* wait upto 100ms */ | ||
38 | falcon_read(efx, ®, XM_GLB_CFG_REG); | ||
39 | if (EFX_OWORD_FIELD(reg, XM_CORE_RST) == 0) | ||
40 | return 0; | ||
41 | udelay(10); | ||
42 | } | ||
43 | |||
44 | EFX_ERR(efx, "timed out waiting for XMAC core reset\n"); | ||
45 | return -ETIMEDOUT; | ||
46 | } | ||
47 | 28 | ||
48 | /* Configure the XAUI driver that is an output from Falcon */ | 29 | /* Configure the XAUI driver that is an output from Falcon */ |
49 | static void falcon_setup_xaui(struct efx_nic *efx) | 30 | static void falcon_setup_xaui(struct efx_nic *efx) |
@@ -99,31 +80,20 @@ int falcon_reset_xaui(struct efx_nic *efx) | |||
99 | return -ETIMEDOUT; | 80 | return -ETIMEDOUT; |
100 | } | 81 | } |
101 | 82 | ||
102 | static bool falcon_xgmii_status(struct efx_nic *efx) | 83 | static void falcon_mask_status_intr(struct efx_nic *efx, bool enable) |
103 | { | 84 | { |
104 | efx_oword_t reg; | 85 | efx_oword_t reg; |
105 | 86 | ||
106 | if (falcon_rev(efx) < FALCON_REV_B0) | 87 | if ((falcon_rev(efx) != FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) |
107 | return true; | 88 | return; |
108 | |||
109 | /* The ISR latches, so clear it and re-read */ | ||
110 | falcon_read(efx, ®, XM_MGT_INT_REG_B0); | ||
111 | falcon_read(efx, ®, XM_MGT_INT_REG_B0); | ||
112 | |||
113 | if (EFX_OWORD_FIELD(reg, XM_LCLFLT) || | ||
114 | EFX_OWORD_FIELD(reg, XM_RMTFLT)) { | ||
115 | EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg)); | ||
116 | return false; | ||
117 | } | ||
118 | |||
119 | return true; | ||
120 | } | ||
121 | 89 | ||
122 | static void falcon_mask_status_intr(struct efx_nic *efx, bool enable) | 90 | /* We expect xgmii faults if the wireside link is up */ |
123 | { | 91 | if (!EFX_WORKAROUND_5147(efx) || !efx->link_up) |
124 | efx_oword_t reg; | 92 | return; |
125 | 93 | ||
126 | if ((falcon_rev(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) | 94 | /* We can only use this interrupt to signal the negative edge of |
95 | * xaui_align [we have to poll the positive edge]. */ | ||
96 | if (!efx->mac_up) | ||
127 | return; | 97 | return; |
128 | 98 | ||
129 | /* Flush the ISR */ | 99 | /* Flush the ISR */ |
@@ -136,35 +106,7 @@ static void falcon_mask_status_intr(struct efx_nic *efx, bool enable) | |||
136 | falcon_write(efx, ®, XM_MGT_INT_MSK_REG_B0); | 106 | falcon_write(efx, ®, XM_MGT_INT_MSK_REG_B0); |
137 | } | 107 | } |
138 | 108 | ||
139 | int falcon_init_xmac(struct efx_nic *efx) | 109 | /* Get status of XAUI link */ |
140 | { | ||
141 | int rc; | ||
142 | |||
143 | /* Initialize the PHY first so the clock is around */ | ||
144 | rc = efx->phy_op->init(efx); | ||
145 | if (rc) | ||
146 | goto fail1; | ||
147 | |||
148 | rc = falcon_reset_xaui(efx); | ||
149 | if (rc) | ||
150 | goto fail2; | ||
151 | |||
152 | /* Wait again. Give the PHY and MAC time to come back */ | ||
153 | schedule_timeout_uninterruptible(HZ / 10); | ||
154 | |||
155 | rc = falcon_reset_xmac(efx); | ||
156 | if (rc) | ||
157 | goto fail2; | ||
158 | |||
159 | falcon_mask_status_intr(efx, true); | ||
160 | return 0; | ||
161 | |||
162 | fail2: | ||
163 | efx->phy_op->fini(efx); | ||
164 | fail1: | ||
165 | return rc; | ||
166 | } | ||
167 | |||
168 | bool falcon_xaui_link_ok(struct efx_nic *efx) | 110 | bool falcon_xaui_link_ok(struct efx_nic *efx) |
169 | { | 111 | { |
170 | efx_oword_t reg; | 112 | efx_oword_t reg; |
@@ -188,18 +130,10 @@ bool falcon_xaui_link_ok(struct efx_nic *efx) | |||
188 | EFX_SET_OWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET); | 130 | EFX_SET_OWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET); |
189 | falcon_write(efx, ®, XX_CORE_STAT_REG); | 131 | falcon_write(efx, ®, XX_CORE_STAT_REG); |
190 | 132 | ||
191 | /* If the link is up, then check the phy side of the xaui link | 133 | /* If the link is up, then check the phy side of the xaui link */ |
192 | * (error conditions from the wire side propoagate back through | 134 | if (efx->link_up && link_ok) |
193 | * the phy to the xaui side). */ | ||
194 | if (efx->link_up && link_ok) { | ||
195 | if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS)) | 135 | if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS)) |
196 | link_ok = mdio_clause45_phyxgxs_lane_sync(efx); | 136 | link_ok = mdio_clause45_phyxgxs_lane_sync(efx); |
197 | } | ||
198 | |||
199 | /* If the PHY and XAUI links are up, then check the mac's xgmii | ||
200 | * fault state */ | ||
201 | if (efx->link_up && link_ok) | ||
202 | link_ok = falcon_xgmii_status(efx); | ||
203 | 137 | ||
204 | return link_ok; | 138 | return link_ok; |
205 | } | 139 | } |
@@ -208,7 +142,7 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx) | |||
208 | { | 142 | { |
209 | unsigned int max_frame_len; | 143 | unsigned int max_frame_len; |
210 | efx_oword_t reg; | 144 | efx_oword_t reg; |
211 | bool rx_fc = !!(efx->flow_control & EFX_FC_RX); | 145 | bool rx_fc = !!(efx->link_fc & EFX_FC_RX); |
212 | 146 | ||
213 | /* Configure MAC - cut-thru mode is hard wired on */ | 147 | /* Configure MAC - cut-thru mode is hard wired on */ |
214 | EFX_POPULATE_DWORD_3(reg, | 148 | EFX_POPULATE_DWORD_3(reg, |
@@ -311,70 +245,39 @@ static void falcon_reconfigure_xgxs_core(struct efx_nic *efx) | |||
311 | 245 | ||
312 | /* Try and bring the Falcon side of the Falcon-Phy XAUI link fails | 246 | /* Try and bring the Falcon side of the Falcon-Phy XAUI link fails |
313 | * to come back up. Bash it until it comes back up */ | 247 | * to come back up. Bash it until it comes back up */ |
314 | static bool falcon_check_xaui_link_up(struct efx_nic *efx) | 248 | static void falcon_check_xaui_link_up(struct efx_nic *efx, int tries) |
315 | { | 249 | { |
316 | int max_tries, tries; | 250 | efx->mac_up = falcon_xaui_link_ok(efx); |
317 | tries = EFX_WORKAROUND_5147(efx) ? 5 : 1; | ||
318 | max_tries = tries; | ||
319 | 251 | ||
320 | if ((efx->loopback_mode == LOOPBACK_NETWORK) || | 252 | if ((efx->loopback_mode == LOOPBACK_NETWORK) || |
321 | (efx->phy_type == PHY_TYPE_NONE) || | ||
322 | efx_phy_mode_disabled(efx->phy_mode)) | 253 | efx_phy_mode_disabled(efx->phy_mode)) |
323 | return false; | 254 | /* XAUI link is expected to be down */ |
324 | 255 | return; | |
325 | while (tries) { | ||
326 | if (falcon_xaui_link_ok(efx)) | ||
327 | return true; | ||
328 | 256 | ||
329 | EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n", | 257 | while (!efx->mac_up && tries) { |
330 | __func__, tries); | 258 | EFX_LOG(efx, "bashing xaui\n"); |
331 | falcon_reset_xaui(efx); | 259 | falcon_reset_xaui(efx); |
332 | udelay(200); | 260 | udelay(200); |
333 | tries--; | ||
334 | } | ||
335 | 261 | ||
336 | EFX_LOG(efx, "Failed to bring XAUI link back up in %d tries!\n", | 262 | efx->mac_up = falcon_xaui_link_ok(efx); |
337 | max_tries); | 263 | --tries; |
338 | return false; | 264 | } |
339 | } | 265 | } |
340 | 266 | ||
341 | void falcon_reconfigure_xmac(struct efx_nic *efx) | 267 | static void falcon_reconfigure_xmac(struct efx_nic *efx) |
342 | { | 268 | { |
343 | bool xaui_link_ok; | ||
344 | |||
345 | falcon_mask_status_intr(efx, false); | 269 | falcon_mask_status_intr(efx, false); |
346 | 270 | ||
347 | falcon_deconfigure_mac_wrapper(efx); | ||
348 | |||
349 | /* Reconfigure the PHY, disabling transmit in mac level loopback. */ | ||
350 | if (LOOPBACK_INTERNAL(efx)) | ||
351 | efx->phy_mode |= PHY_MODE_TX_DISABLED; | ||
352 | else | ||
353 | efx->phy_mode &= ~PHY_MODE_TX_DISABLED; | ||
354 | efx->phy_op->reconfigure(efx); | ||
355 | |||
356 | falcon_reconfigure_xgxs_core(efx); | 271 | falcon_reconfigure_xgxs_core(efx); |
357 | falcon_reconfigure_xmac_core(efx); | 272 | falcon_reconfigure_xmac_core(efx); |
358 | 273 | ||
359 | falcon_reconfigure_mac_wrapper(efx); | 274 | falcon_reconfigure_mac_wrapper(efx); |
360 | 275 | ||
361 | /* Ensure XAUI link is up */ | 276 | falcon_check_xaui_link_up(efx, 5); |
362 | xaui_link_ok = falcon_check_xaui_link_up(efx); | 277 | falcon_mask_status_intr(efx, true); |
363 | |||
364 | if (xaui_link_ok && efx->link_up) | ||
365 | falcon_mask_status_intr(efx, true); | ||
366 | } | ||
367 | |||
368 | void falcon_fini_xmac(struct efx_nic *efx) | ||
369 | { | ||
370 | /* Isolate the MAC - PHY */ | ||
371 | falcon_deconfigure_mac_wrapper(efx); | ||
372 | |||
373 | /* Potentially power down the PHY */ | ||
374 | efx->phy_op->fini(efx); | ||
375 | } | 278 | } |
376 | 279 | ||
377 | void falcon_update_stats_xmac(struct efx_nic *efx) | 280 | static void falcon_update_stats_xmac(struct efx_nic *efx) |
378 | { | 281 | { |
379 | struct efx_mac_stats *mac_stats = &efx->mac_stats; | 282 | struct efx_mac_stats *mac_stats = &efx->mac_stats; |
380 | int rc; | 283 | int rc; |
@@ -439,97 +342,35 @@ void falcon_update_stats_xmac(struct efx_nic *efx) | |||
439 | mac_stats->rx_control * 64); | 342 | mac_stats->rx_control * 64); |
440 | } | 343 | } |
441 | 344 | ||
442 | int falcon_check_xmac(struct efx_nic *efx) | 345 | static void falcon_xmac_irq(struct efx_nic *efx) |
443 | { | 346 | { |
444 | bool xaui_link_ok; | 347 | /* The XGMII link has a transient fault, which indicates either: |
445 | int rc; | 348 | * - there's a transient xgmii fault |
446 | 349 | * - falcon's end of the xaui link may need a kick | |
447 | if ((efx->loopback_mode == LOOPBACK_NETWORK) || | 350 | * - the wire-side link may have gone down, but the lasi/poll() |
448 | efx_phy_mode_disabled(efx->phy_mode)) | 351 | * hasn't noticed yet. |
449 | return 0; | 352 | * |
450 | 353 | * We only want to even bother polling XAUI if we're confident it's | |
451 | falcon_mask_status_intr(efx, false); | 354 | * not (1) or (3). In both cases, the only reliable way to spot this |
452 | xaui_link_ok = falcon_xaui_link_ok(efx); | 355 | * is to wait a bit. We do this here by forcing the mac link state |
453 | 356 | * to down, and waiting for the mac poll to come round and check | |
454 | if (EFX_WORKAROUND_5147(efx) && !xaui_link_ok) | 357 | */ |
455 | falcon_reset_xaui(efx); | 358 | efx->mac_up = false; |
456 | |||
457 | /* Call the PHY check_hw routine */ | ||
458 | rc = efx->phy_op->check_hw(efx); | ||
459 | |||
460 | /* Unmask interrupt if everything was (and still is) ok */ | ||
461 | if (xaui_link_ok && efx->link_up) | ||
462 | falcon_mask_status_intr(efx, true); | ||
463 | |||
464 | return rc; | ||
465 | } | ||
466 | |||
467 | /* Simulate a PHY event */ | ||
468 | void falcon_xmac_sim_phy_event(struct efx_nic *efx) | ||
469 | { | ||
470 | efx_qword_t phy_event; | ||
471 | |||
472 | EFX_POPULATE_QWORD_2(phy_event, | ||
473 | EV_CODE, GLOBAL_EV_DECODE, | ||
474 | XG_PHY_INTR, 1); | ||
475 | falcon_generate_event(&efx->channel[0], &phy_event); | ||
476 | } | 359 | } |
477 | 360 | ||
478 | int falcon_xmac_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | 361 | static void falcon_poll_xmac(struct efx_nic *efx) |
479 | { | 362 | { |
480 | mdio_clause45_get_settings(efx, ecmd); | 363 | if (!EFX_WORKAROUND_5147(efx) || !efx->link_up || efx->mac_up) |
481 | ecmd->transceiver = XCVR_INTERNAL; | 364 | return; |
482 | ecmd->phy_address = efx->mii.phy_id; | ||
483 | ecmd->autoneg = AUTONEG_DISABLE; | ||
484 | ecmd->duplex = DUPLEX_FULL; | ||
485 | return 0; | ||
486 | } | ||
487 | 365 | ||
488 | int falcon_xmac_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | 366 | falcon_mask_status_intr(efx, false); |
489 | { | 367 | falcon_check_xaui_link_up(efx, 1); |
490 | if (ecmd->transceiver != XCVR_INTERNAL) | 368 | falcon_mask_status_intr(efx, true); |
491 | return -EINVAL; | ||
492 | if (ecmd->autoneg != AUTONEG_DISABLE) | ||
493 | return -EINVAL; | ||
494 | if (ecmd->duplex != DUPLEX_FULL) | ||
495 | return -EINVAL; | ||
496 | |||
497 | return mdio_clause45_set_settings(efx, ecmd); | ||
498 | } | 369 | } |
499 | 370 | ||
500 | 371 | struct efx_mac_operations falcon_xmac_operations = { | |
501 | int falcon_xmac_set_pause(struct efx_nic *efx, enum efx_fc_type flow_control) | 372 | .reconfigure = falcon_reconfigure_xmac, |
502 | { | 373 | .update_stats = falcon_update_stats_xmac, |
503 | bool reset; | 374 | .irq = falcon_xmac_irq, |
504 | 375 | .poll = falcon_poll_xmac, | |
505 | if (flow_control & EFX_FC_AUTO) { | 376 | }; |
506 | EFX_LOG(efx, "10G does not support flow control " | ||
507 | "autonegotiation\n"); | ||
508 | return -EINVAL; | ||
509 | } | ||
510 | |||
511 | if ((flow_control & EFX_FC_TX) && !(flow_control & EFX_FC_RX)) | ||
512 | return -EINVAL; | ||
513 | |||
514 | /* TX flow control may automatically turn itself off if the | ||
515 | * link partner (intermittently) stops responding to pause | ||
516 | * frames. There isn't any indication that this has happened, | ||
517 | * so the best we do is leave it up to the user to spot this | ||
518 | * and fix it be cycling transmit flow control on this end. */ | ||
519 | reset = ((flow_control & EFX_FC_TX) && | ||
520 | !(efx->flow_control & EFX_FC_TX)); | ||
521 | if (EFX_WORKAROUND_11482(efx) && reset) { | ||
522 | if (falcon_rev(efx) >= FALCON_REV_B0) { | ||
523 | /* Recover by resetting the EM block */ | ||
524 | if (efx->link_up) | ||
525 | falcon_drain_tx_fifo(efx); | ||
526 | } else { | ||
527 | /* Schedule a reset to recover */ | ||
528 | efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); | ||
529 | } | ||
530 | } | ||
531 | |||
532 | efx->flow_control = flow_control; | ||
533 | |||
534 | return 0; | ||
535 | } | ||
diff --git a/drivers/net/sfc/gmii.h b/drivers/net/sfc/gmii.h index d25bbd1297f4..dfccaa7b573e 100644 --- a/drivers/net/sfc/gmii.h +++ b/drivers/net/sfc/gmii.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /**************************************************************************** | 1 | /**************************************************************************** |
2 | * Driver for Solarflare Solarstorm network controllers and boards | 2 | * Driver for Solarflare Solarstorm network controllers and boards |
3 | * Copyright 2005-2006 Fen Systems Ltd. | 3 | * Copyright 2005-2006 Fen Systems Ltd. |
4 | * Copyright 2006 Solarflare Communications Inc. | 4 | * Copyright 2006-2008 Solarflare Communications Inc. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License version 2 as published | 7 | * under the terms of the GNU General Public License version 2 as published |
@@ -57,139 +57,4 @@ | |||
57 | #define ISR_POLARITY_CHG 0x0002 /* Bit 1 - polarity changed */ | 57 | #define ISR_POLARITY_CHG 0x0002 /* Bit 1 - polarity changed */ |
58 | #define ISR_JABBER 0x0001 /* Bit 0 - jabber */ | 58 | #define ISR_JABBER 0x0001 /* Bit 0 - jabber */ |
59 | 59 | ||
60 | /* Logically extended advertisement register */ | ||
61 | #define GM_ADVERTISE_SLCT ADVERTISE_SLCT | ||
62 | #define GM_ADVERTISE_CSMA ADVERTISE_CSMA | ||
63 | #define GM_ADVERTISE_10HALF ADVERTISE_10HALF | ||
64 | #define GM_ADVERTISE_1000XFULL ADVERTISE_1000XFULL | ||
65 | #define GM_ADVERTISE_10FULL ADVERTISE_10FULL | ||
66 | #define GM_ADVERTISE_1000XHALF ADVERTISE_1000XHALF | ||
67 | #define GM_ADVERTISE_100HALF ADVERTISE_100HALF | ||
68 | #define GM_ADVERTISE_1000XPAUSE ADVERTISE_1000XPAUSE | ||
69 | #define GM_ADVERTISE_100FULL ADVERTISE_100FULL | ||
70 | #define GM_ADVERTISE_1000XPSE_ASYM ADVERTISE_1000XPSE_ASYM | ||
71 | #define GM_ADVERTISE_100BASE4 ADVERTISE_100BASE4 | ||
72 | #define GM_ADVERTISE_PAUSE_CAP ADVERTISE_PAUSE_CAP | ||
73 | #define GM_ADVERTISE_PAUSE_ASYM ADVERTISE_PAUSE_ASYM | ||
74 | #define GM_ADVERTISE_RESV ADVERTISE_RESV | ||
75 | #define GM_ADVERTISE_RFAULT ADVERTISE_RFAULT | ||
76 | #define GM_ADVERTISE_LPACK ADVERTISE_LPACK | ||
77 | #define GM_ADVERTISE_NPAGE ADVERTISE_NPAGE | ||
78 | #define GM_ADVERTISE_1000FULL (ADVERTISE_1000FULL << 8) | ||
79 | #define GM_ADVERTISE_1000HALF (ADVERTISE_1000HALF << 8) | ||
80 | #define GM_ADVERTISE_1000 (GM_ADVERTISE_1000FULL | \ | ||
81 | GM_ADVERTISE_1000HALF) | ||
82 | #define GM_ADVERTISE_FULL (GM_ADVERTISE_1000FULL | \ | ||
83 | ADVERTISE_FULL) | ||
84 | #define GM_ADVERTISE_ALL (GM_ADVERTISE_1000FULL | \ | ||
85 | GM_ADVERTISE_1000HALF | \ | ||
86 | ADVERTISE_ALL) | ||
87 | |||
88 | /* Logically extended link partner ability register */ | ||
89 | #define GM_LPA_SLCT LPA_SLCT | ||
90 | #define GM_LPA_10HALF LPA_10HALF | ||
91 | #define GM_LPA_1000XFULL LPA_1000XFULL | ||
92 | #define GM_LPA_10FULL LPA_10FULL | ||
93 | #define GM_LPA_1000XHALF LPA_1000XHALF | ||
94 | #define GM_LPA_100HALF LPA_100HALF | ||
95 | #define GM_LPA_1000XPAUSE LPA_1000XPAUSE | ||
96 | #define GM_LPA_100FULL LPA_100FULL | ||
97 | #define GM_LPA_1000XPAUSE_ASYM LPA_1000XPAUSE_ASYM | ||
98 | #define GM_LPA_100BASE4 LPA_100BASE4 | ||
99 | #define GM_LPA_PAUSE_CAP LPA_PAUSE_CAP | ||
100 | #define GM_LPA_PAUSE_ASYM LPA_PAUSE_ASYM | ||
101 | #define GM_LPA_RESV LPA_RESV | ||
102 | #define GM_LPA_RFAULT LPA_RFAULT | ||
103 | #define GM_LPA_LPACK LPA_LPACK | ||
104 | #define GM_LPA_NPAGE LPA_NPAGE | ||
105 | #define GM_LPA_1000FULL (LPA_1000FULL << 6) | ||
106 | #define GM_LPA_1000HALF (LPA_1000HALF << 6) | ||
107 | #define GM_LPA_10000FULL 0x00040000 | ||
108 | #define GM_LPA_10000HALF 0x00080000 | ||
109 | #define GM_LPA_DUPLEX (GM_LPA_1000FULL | GM_LPA_10000FULL \ | ||
110 | | LPA_DUPLEX) | ||
111 | #define GM_LPA_10 (LPA_10FULL | LPA_10HALF) | ||
112 | #define GM_LPA_100 LPA_100 | ||
113 | #define GM_LPA_1000 (GM_LPA_1000FULL | GM_LPA_1000HALF) | ||
114 | #define GM_LPA_10000 (GM_LPA_10000FULL | GM_LPA_10000HALF) | ||
115 | |||
116 | /* Retrieve GMII autonegotiation advertised abilities | ||
117 | * | ||
118 | * The MII advertisment register (MII_ADVERTISE) is logically extended | ||
119 | * to include advertisement bits ADVERTISE_1000FULL and | ||
120 | * ADVERTISE_1000HALF from MII_CTRL1000. The result can be tested | ||
121 | * against the GM_ADVERTISE_xxx constants. | ||
122 | */ | ||
123 | static inline unsigned int gmii_advertised(struct mii_if_info *gmii) | ||
124 | { | ||
125 | unsigned int advertise; | ||
126 | unsigned int ctrl1000; | ||
127 | |||
128 | advertise = gmii->mdio_read(gmii->dev, gmii->phy_id, MII_ADVERTISE); | ||
129 | ctrl1000 = gmii->mdio_read(gmii->dev, gmii->phy_id, MII_CTRL1000); | ||
130 | return (((ctrl1000 << 8) & GM_ADVERTISE_1000) | advertise); | ||
131 | } | ||
132 | |||
133 | /* Retrieve GMII autonegotiation link partner abilities | ||
134 | * | ||
135 | * The MII link partner ability register (MII_LPA) is logically | ||
136 | * extended by adding bits LPA_1000HALF and LPA_1000FULL from | ||
137 | * MII_STAT1000. The result can be tested against the GM_LPA_xxx | ||
138 | * constants. | ||
139 | */ | ||
140 | static inline unsigned int gmii_lpa(struct mii_if_info *gmii) | ||
141 | { | ||
142 | unsigned int lpa; | ||
143 | unsigned int stat1000; | ||
144 | |||
145 | lpa = gmii->mdio_read(gmii->dev, gmii->phy_id, MII_LPA); | ||
146 | stat1000 = gmii->mdio_read(gmii->dev, gmii->phy_id, MII_STAT1000); | ||
147 | return (((stat1000 << 6) & GM_LPA_1000) | lpa); | ||
148 | } | ||
149 | |||
150 | /* Calculate GMII autonegotiated link technology | ||
151 | * | ||
152 | * "negotiated" should be the result of gmii_advertised() logically | ||
153 | * ANDed with the result of gmii_lpa(). | ||
154 | * | ||
155 | * "tech" will be negotiated with the unused bits masked out. For | ||
156 | * example, if both ends of the link are capable of both | ||
157 | * GM_LPA_1000FULL and GM_LPA_100FULL, GM_LPA_100FULL will be masked | ||
158 | * out. | ||
159 | */ | ||
160 | static inline unsigned int gmii_nway_result(unsigned int negotiated) | ||
161 | { | ||
162 | unsigned int other_bits; | ||
163 | |||
164 | /* Mask out the speed and duplexity bits */ | ||
165 | other_bits = negotiated & ~(GM_LPA_10 | GM_LPA_100 | GM_LPA_1000); | ||
166 | |||
167 | if (negotiated & GM_LPA_1000FULL) | ||
168 | return (other_bits | GM_LPA_1000FULL); | ||
169 | else if (negotiated & GM_LPA_1000HALF) | ||
170 | return (other_bits | GM_LPA_1000HALF); | ||
171 | else | ||
172 | return (other_bits | mii_nway_result(negotiated)); | ||
173 | } | ||
174 | |||
175 | /* Calculate GMII non-autonegotiated link technology | ||
176 | * | ||
177 | * This provides an equivalent to gmii_nway_result for the case when | ||
178 | * autonegotiation is disabled. | ||
179 | */ | ||
180 | static inline unsigned int gmii_forced_result(unsigned int bmcr) | ||
181 | { | ||
182 | unsigned int result; | ||
183 | int full_duplex; | ||
184 | |||
185 | full_duplex = bmcr & BMCR_FULLDPLX; | ||
186 | if (bmcr & BMCR_SPEED1000) | ||
187 | result = full_duplex ? GM_LPA_1000FULL : GM_LPA_1000HALF; | ||
188 | else if (bmcr & BMCR_SPEED100) | ||
189 | result = full_duplex ? GM_LPA_100FULL : GM_LPA_100HALF; | ||
190 | else | ||
191 | result = full_duplex ? GM_LPA_10FULL : GM_LPA_10HALF; | ||
192 | return result; | ||
193 | } | ||
194 | |||
195 | #endif /* EFX_GMII_H */ | 60 | #endif /* EFX_GMII_H */ |
diff --git a/drivers/net/sfc/mac.h b/drivers/net/sfc/mac.h index a31571c69137..4e7074278fe1 100644 --- a/drivers/net/sfc/mac.h +++ b/drivers/net/sfc/mac.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /**************************************************************************** | 1 | /**************************************************************************** |
2 | * Driver for Solarflare Solarstorm network controllers and boards | 2 | * Driver for Solarflare Solarstorm network controllers and boards |
3 | * Copyright 2005-2006 Fen Systems Ltd. | 3 | * Copyright 2005-2006 Fen Systems Ltd. |
4 | * Copyright 2006-2007 Solarflare Communications Inc. | 4 | * Copyright 2006-2008 Solarflare Communications Inc. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License version 2 as published | 7 | * under the terms of the GNU General Public License version 2 as published |
@@ -13,17 +13,7 @@ | |||
13 | 13 | ||
14 | #include "net_driver.h" | 14 | #include "net_driver.h" |
15 | 15 | ||
16 | extern int falcon_init_xmac(struct efx_nic *efx); | 16 | extern struct efx_mac_operations falcon_gmac_operations; |
17 | extern void falcon_reconfigure_xmac(struct efx_nic *efx); | 17 | extern struct efx_mac_operations falcon_xmac_operations; |
18 | extern void falcon_update_stats_xmac(struct efx_nic *efx); | ||
19 | extern void falcon_fini_xmac(struct efx_nic *efx); | ||
20 | extern int falcon_check_xmac(struct efx_nic *efx); | ||
21 | extern void falcon_xmac_sim_phy_event(struct efx_nic *efx); | ||
22 | extern int falcon_xmac_get_settings(struct efx_nic *efx, | ||
23 | struct ethtool_cmd *ecmd); | ||
24 | extern int falcon_xmac_set_settings(struct efx_nic *efx, | ||
25 | struct ethtool_cmd *ecmd); | ||
26 | extern int falcon_xmac_set_pause(struct efx_nic *efx, | ||
27 | enum efx_fc_type pause_params); | ||
28 | 18 | ||
29 | #endif | 19 | #endif |
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index 003e48dcb2f3..f9e2f95c3b48 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "net_driver.h" | 15 | #include "net_driver.h" |
16 | #include "mdio_10g.h" | 16 | #include "mdio_10g.h" |
17 | #include "boards.h" | 17 | #include "boards.h" |
18 | #include "workarounds.h" | ||
18 | 19 | ||
19 | int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd, | 20 | int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd, |
20 | int spins, int spintime) | 21 | int spins, int spintime) |
@@ -47,13 +48,16 @@ static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd, | |||
47 | if (LOOPBACK_INTERNAL(efx)) | 48 | if (LOOPBACK_INTERNAL(efx)) |
48 | return 0; | 49 | return 0; |
49 | 50 | ||
50 | /* Read MMD STATUS2 to check it is responding. */ | 51 | if (mmd != MDIO_MMD_AN) { |
51 | status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT2); | 52 | /* Read MMD STATUS2 to check it is responding. */ |
52 | if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) & | 53 | status = mdio_clause45_read(efx, phy_id, mmd, |
53 | ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) != | 54 | MDIO_MMDREG_STAT2); |
54 | MDIO_MMDREG_STAT2_PRESENT_VAL) { | 55 | if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) & |
55 | EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd); | 56 | ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) != |
56 | return -EIO; | 57 | MDIO_MMDREG_STAT2_PRESENT_VAL) { |
58 | EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd); | ||
59 | return -EIO; | ||
60 | } | ||
57 | } | 61 | } |
58 | 62 | ||
59 | /* Read MMD STATUS 1 to check for fault. */ | 63 | /* Read MMD STATUS 1 to check for fault. */ |
@@ -121,16 +125,18 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx, | |||
121 | int mdio_clause45_check_mmds(struct efx_nic *efx, | 125 | int mdio_clause45_check_mmds(struct efx_nic *efx, |
122 | unsigned int mmd_mask, unsigned int fatal_mask) | 126 | unsigned int mmd_mask, unsigned int fatal_mask) |
123 | { | 127 | { |
124 | int devices, mmd = 0; | 128 | u32 devices; |
125 | int probe_mmd; | 129 | int mmd = 0, probe_mmd; |
126 | 130 | ||
127 | /* Historically we have probed the PHYXS to find out what devices are | 131 | /* Historically we have probed the PHYXS to find out what devices are |
128 | * present,but that doesn't work so well if the PHYXS isn't expected | 132 | * present,but that doesn't work so well if the PHYXS isn't expected |
129 | * to exist, if so just find the first item in the list supplied. */ | 133 | * to exist, if so just find the first item in the list supplied. */ |
130 | probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS0_PHYXS) ? MDIO_MMD_PHYXS : | 134 | probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS : |
131 | __ffs(mmd_mask); | 135 | __ffs(mmd_mask); |
132 | devices = mdio_clause45_read(efx, efx->mii.phy_id, | 136 | devices = (mdio_clause45_read(efx, efx->mii.phy_id, |
133 | probe_mmd, MDIO_MMDREG_DEVS0); | 137 | probe_mmd, MDIO_MMDREG_DEVS0) | |
138 | mdio_clause45_read(efx, efx->mii.phy_id, | ||
139 | probe_mmd, MDIO_MMDREG_DEVS1) << 16); | ||
134 | 140 | ||
135 | /* Check all the expected MMDs are present */ | 141 | /* Check all the expected MMDs are present */ |
136 | if (devices < 0) { | 142 | if (devices < 0) { |
@@ -162,7 +168,7 @@ int mdio_clause45_check_mmds(struct efx_nic *efx, | |||
162 | bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) | 168 | bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) |
163 | { | 169 | { |
164 | int phy_id = efx->mii.phy_id; | 170 | int phy_id = efx->mii.phy_id; |
165 | int status; | 171 | u32 reg; |
166 | bool ok = true; | 172 | bool ok = true; |
167 | int mmd = 0; | 173 | int mmd = 0; |
168 | 174 | ||
@@ -175,25 +181,34 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) | |||
175 | else if (efx_phy_mode_disabled(efx->phy_mode)) | 181 | else if (efx_phy_mode_disabled(efx->phy_mode)) |
176 | return false; | 182 | return false; |
177 | else if (efx->loopback_mode == LOOPBACK_PHYXS) | 183 | else if (efx->loopback_mode == LOOPBACK_PHYXS) |
178 | mmd_mask &= ~(MDIO_MMDREG_DEVS0_PHYXS | | 184 | mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS | |
179 | MDIO_MMDREG_DEVS0_PCS | | 185 | MDIO_MMDREG_DEVS_PCS | |
180 | MDIO_MMDREG_DEVS0_PMAPMD); | 186 | MDIO_MMDREG_DEVS_PMAPMD | |
187 | MDIO_MMDREG_DEVS_AN); | ||
181 | else if (efx->loopback_mode == LOOPBACK_PCS) | 188 | else if (efx->loopback_mode == LOOPBACK_PCS) |
182 | mmd_mask &= ~(MDIO_MMDREG_DEVS0_PCS | | 189 | mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS | |
183 | MDIO_MMDREG_DEVS0_PMAPMD); | 190 | MDIO_MMDREG_DEVS_PMAPMD | |
191 | MDIO_MMDREG_DEVS_AN); | ||
184 | else if (efx->loopback_mode == LOOPBACK_PMAPMD) | 192 | else if (efx->loopback_mode == LOOPBACK_PMAPMD) |
185 | mmd_mask &= ~MDIO_MMDREG_DEVS0_PMAPMD; | 193 | mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD | |
194 | MDIO_MMDREG_DEVS_AN); | ||
195 | |||
196 | if (!mmd_mask) { | ||
197 | /* Use presence of XGMII faults in leui of link state */ | ||
198 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, | ||
199 | MDIO_PHYXS_STATUS2); | ||
200 | return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN)); | ||
201 | } | ||
186 | 202 | ||
187 | while (mmd_mask) { | 203 | while (mmd_mask) { |
188 | if (mmd_mask & 1) { | 204 | if (mmd_mask & 1) { |
189 | /* Double reads because link state is latched, and a | 205 | /* Double reads because link state is latched, and a |
190 | * read moves the current state into the register */ | 206 | * read moves the current state into the register */ |
191 | status = mdio_clause45_read(efx, phy_id, | 207 | reg = mdio_clause45_read(efx, phy_id, |
192 | mmd, MDIO_MMDREG_STAT1); | 208 | mmd, MDIO_MMDREG_STAT1); |
193 | status = mdio_clause45_read(efx, phy_id, | 209 | reg = mdio_clause45_read(efx, phy_id, |
194 | mmd, MDIO_MMDREG_STAT1); | 210 | mmd, MDIO_MMDREG_STAT1); |
195 | 211 | ok = ok && (reg & (1 << MDIO_MMDREG_STAT1_LINK_LBN)); | |
196 | ok = ok && (status & (1 << MDIO_MMDREG_STAT1_LINK_LBN)); | ||
197 | } | 212 | } |
198 | mmd_mask = (mmd_mask >> 1); | 213 | mmd_mask = (mmd_mask >> 1); |
199 | mmd++; | 214 | mmd++; |
@@ -203,61 +218,70 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) | |||
203 | 218 | ||
204 | void mdio_clause45_transmit_disable(struct efx_nic *efx) | 219 | void mdio_clause45_transmit_disable(struct efx_nic *efx) |
205 | { | 220 | { |
206 | int phy_id = efx->mii.phy_id; | 221 | mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, |
207 | int ctrl1, ctrl2; | 222 | MDIO_MMDREG_TXDIS, MDIO_MMDREG_TXDIS_GLOBAL_LBN, |
208 | 223 | efx->phy_mode & PHY_MODE_TX_DISABLED); | |
209 | ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
210 | MDIO_MMDREG_TXDIS); | ||
211 | if (efx->phy_mode & PHY_MODE_TX_DISABLED) | ||
212 | ctrl2 |= (1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN); | ||
213 | else | ||
214 | ctrl1 &= ~(1 << MDIO_MMDREG_TXDIS_GLOBAL_LBN); | ||
215 | if (ctrl1 != ctrl2) | ||
216 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | ||
217 | MDIO_MMDREG_TXDIS, ctrl2); | ||
218 | } | 224 | } |
219 | 225 | ||
220 | void mdio_clause45_phy_reconfigure(struct efx_nic *efx) | 226 | void mdio_clause45_phy_reconfigure(struct efx_nic *efx) |
221 | { | 227 | { |
222 | int phy_id = efx->mii.phy_id; | 228 | int phy_id = efx->mii.phy_id; |
223 | int ctrl1, ctrl2; | ||
224 | |||
225 | /* Handle (with debouncing) PMA/PMD loopback */ | ||
226 | ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
227 | MDIO_MMDREG_CTRL1); | ||
228 | 229 | ||
229 | if (efx->loopback_mode == LOOPBACK_PMAPMD) | 230 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD, |
230 | ctrl2 |= (1 << MDIO_PMAPMD_CTRL1_LBACK_LBN); | 231 | MDIO_MMDREG_CTRL1, MDIO_PMAPMD_CTRL1_LBACK_LBN, |
231 | else | 232 | efx->loopback_mode == LOOPBACK_PMAPMD); |
232 | ctrl2 &= ~(1 << MDIO_PMAPMD_CTRL1_LBACK_LBN); | 233 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PCS, |
234 | MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN, | ||
235 | efx->loopback_mode == LOOPBACK_PCS); | ||
236 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS, | ||
237 | MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN, | ||
238 | efx->loopback_mode == LOOPBACK_NETWORK); | ||
239 | } | ||
233 | 240 | ||
234 | if (ctrl1 != ctrl2) | 241 | static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx, |
235 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | 242 | int lpower, int mmd) |
236 | MDIO_MMDREG_CTRL1, ctrl2); | 243 | { |
244 | int phy = efx->mii.phy_id; | ||
245 | int stat = mdio_clause45_read(efx, phy, mmd, MDIO_MMDREG_STAT1); | ||
237 | 246 | ||
238 | /* Handle (with debouncing) PCS loopback */ | 247 | EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n", |
239 | ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS, | 248 | mmd, lpower); |
240 | MDIO_MMDREG_CTRL1); | ||
241 | if (efx->loopback_mode == LOOPBACK_PCS) | ||
242 | ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN); | ||
243 | else | ||
244 | ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN); | ||
245 | 249 | ||
246 | if (ctrl1 != ctrl2) | 250 | if (stat & (1 << MDIO_MMDREG_STAT1_LPABLE_LBN)) { |
247 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PCS, | 251 | mdio_clause45_set_flag(efx, phy, mmd, MDIO_MMDREG_CTRL1, |
248 | MDIO_MMDREG_CTRL1, ctrl2); | 252 | MDIO_MMDREG_CTRL1_LPOWER_LBN, lpower); |
253 | } | ||
254 | } | ||
249 | 255 | ||
250 | /* Handle (with debouncing) PHYXS network loopback */ | 256 | void mdio_clause45_set_mmds_lpower(struct efx_nic *efx, |
251 | ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, | 257 | int low_power, unsigned int mmd_mask) |
252 | MDIO_MMDREG_CTRL1); | 258 | { |
253 | if (efx->loopback_mode == LOOPBACK_NETWORK) | 259 | int mmd = 0; |
254 | ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LBACK_LBN); | 260 | mmd_mask &= ~MDIO_MMDREG_DEVS_AN; |
255 | else | 261 | while (mmd_mask) { |
256 | ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LBACK_LBN); | 262 | if (mmd_mask & 1) |
263 | mdio_clause45_set_mmd_lpower(efx, low_power, mmd); | ||
264 | mmd_mask = (mmd_mask >> 1); | ||
265 | mmd++; | ||
266 | } | ||
267 | } | ||
257 | 268 | ||
258 | if (ctrl1 != ctrl2) | 269 | static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr) |
259 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS, | 270 | { |
260 | MDIO_MMDREG_CTRL1, ctrl2); | 271 | int phy_id = efx->mii.phy_id; |
272 | u32 result = 0; | ||
273 | int reg; | ||
274 | |||
275 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, addr); | ||
276 | if (reg & ADVERTISE_10HALF) | ||
277 | result |= ADVERTISED_10baseT_Half; | ||
278 | if (reg & ADVERTISE_10FULL) | ||
279 | result |= ADVERTISED_10baseT_Full; | ||
280 | if (reg & ADVERTISE_100HALF) | ||
281 | result |= ADVERTISED_100baseT_Half; | ||
282 | if (reg & ADVERTISE_100FULL) | ||
283 | result |= ADVERTISED_100baseT_Full; | ||
284 | return result; | ||
261 | } | 285 | } |
262 | 286 | ||
263 | /** | 287 | /** |
@@ -266,95 +290,277 @@ void mdio_clause45_phy_reconfigure(struct efx_nic *efx) | |||
266 | * @ecmd: Buffer for settings | 290 | * @ecmd: Buffer for settings |
267 | * | 291 | * |
268 | * On return the 'port', 'speed', 'supported' and 'advertising' fields of | 292 | * On return the 'port', 'speed', 'supported' and 'advertising' fields of |
269 | * ecmd have been filled out based on the PMA type. | 293 | * ecmd have been filled out. |
270 | */ | 294 | */ |
271 | void mdio_clause45_get_settings(struct efx_nic *efx, | 295 | void mdio_clause45_get_settings(struct efx_nic *efx, |
272 | struct ethtool_cmd *ecmd) | 296 | struct ethtool_cmd *ecmd) |
273 | { | 297 | { |
274 | int pma_type; | 298 | mdio_clause45_get_settings_ext(efx, ecmd, 0, 0); |
299 | } | ||
275 | 300 | ||
276 | /* If no PMA is present we are presumably talking something XAUI-ish | 301 | /** |
277 | * like CX4. Which we report as FIBRE (see below) */ | 302 | * mdio_clause45_get_settings_ext - Read (some of) the PHY settings over MDIO. |
278 | if ((efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)) == 0) { | 303 | * @efx: Efx NIC |
279 | ecmd->speed = SPEED_10000; | 304 | * @ecmd: Buffer for settings |
280 | ecmd->port = PORT_FIBRE; | 305 | * @xnp: Advertised Extended Next Page state |
281 | ecmd->supported = SUPPORTED_FIBRE; | 306 | * @xnp_lpa: Link Partner's advertised XNP state |
282 | ecmd->advertising = ADVERTISED_FIBRE; | 307 | * |
283 | return; | 308 | * On return the 'port', 'speed', 'supported' and 'advertising' fields of |
284 | } | 309 | * ecmd have been filled out. |
310 | */ | ||
311 | void mdio_clause45_get_settings_ext(struct efx_nic *efx, | ||
312 | struct ethtool_cmd *ecmd, | ||
313 | u32 npage_adv, u32 npage_lpa) | ||
314 | { | ||
315 | int phy_id = efx->mii.phy_id; | ||
316 | int reg; | ||
285 | 317 | ||
286 | pma_type = mdio_clause45_read(efx, efx->mii.phy_id, | 318 | ecmd->transceiver = XCVR_INTERNAL; |
287 | MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL2); | 319 | ecmd->phy_address = phy_id; |
288 | pma_type &= MDIO_PMAPMD_CTRL2_TYPE_MASK; | ||
289 | 320 | ||
290 | switch (pma_type) { | 321 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, |
291 | /* We represent CX4 as fibre in the absence of anything | 322 | MDIO_MMDREG_CTRL2); |
292 | better. */ | 323 | switch (reg & MDIO_PMAPMD_CTRL2_TYPE_MASK) { |
293 | case MDIO_PMAPMD_CTRL2_10G_CX4: | ||
294 | ecmd->speed = SPEED_10000; | ||
295 | ecmd->port = PORT_FIBRE; | ||
296 | ecmd->supported = SUPPORTED_FIBRE; | ||
297 | ecmd->advertising = ADVERTISED_FIBRE; | ||
298 | break; | ||
299 | /* 10G Base-T */ | ||
300 | case MDIO_PMAPMD_CTRL2_10G_BT: | 324 | case MDIO_PMAPMD_CTRL2_10G_BT: |
301 | ecmd->speed = SPEED_10000; | ||
302 | ecmd->port = PORT_TP; | ||
303 | ecmd->supported = SUPPORTED_TP | SUPPORTED_10000baseT_Full; | ||
304 | ecmd->advertising = (ADVERTISED_FIBRE | ||
305 | | ADVERTISED_10000baseT_Full); | ||
306 | break; | ||
307 | case MDIO_PMAPMD_CTRL2_1G_BT: | 325 | case MDIO_PMAPMD_CTRL2_1G_BT: |
308 | ecmd->speed = SPEED_1000; | ||
309 | ecmd->port = PORT_TP; | ||
310 | ecmd->supported = SUPPORTED_TP | SUPPORTED_1000baseT_Full; | ||
311 | ecmd->advertising = (ADVERTISED_FIBRE | ||
312 | | ADVERTISED_1000baseT_Full); | ||
313 | break; | ||
314 | case MDIO_PMAPMD_CTRL2_100_BT: | 326 | case MDIO_PMAPMD_CTRL2_100_BT: |
315 | ecmd->speed = SPEED_100; | ||
316 | ecmd->port = PORT_TP; | ||
317 | ecmd->supported = SUPPORTED_TP | SUPPORTED_100baseT_Full; | ||
318 | ecmd->advertising = (ADVERTISED_FIBRE | ||
319 | | ADVERTISED_100baseT_Full); | ||
320 | break; | ||
321 | case MDIO_PMAPMD_CTRL2_10_BT: | 327 | case MDIO_PMAPMD_CTRL2_10_BT: |
322 | ecmd->speed = SPEED_10; | ||
323 | ecmd->port = PORT_TP; | 328 | ecmd->port = PORT_TP; |
324 | ecmd->supported = SUPPORTED_TP | SUPPORTED_10baseT_Full; | 329 | ecmd->supported = SUPPORTED_TP; |
325 | ecmd->advertising = ADVERTISED_FIBRE | ADVERTISED_10baseT_Full; | 330 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, |
331 | MDIO_MMDREG_SPEED); | ||
332 | if (reg & (1 << MDIO_MMDREG_SPEED_10G_LBN)) | ||
333 | ecmd->supported |= SUPPORTED_10000baseT_Full; | ||
334 | if (reg & (1 << MDIO_MMDREG_SPEED_1000M_LBN)) | ||
335 | ecmd->supported |= (SUPPORTED_1000baseT_Full | | ||
336 | SUPPORTED_1000baseT_Half); | ||
337 | if (reg & (1 << MDIO_MMDREG_SPEED_100M_LBN)) | ||
338 | ecmd->supported |= (SUPPORTED_100baseT_Full | | ||
339 | SUPPORTED_100baseT_Half); | ||
340 | if (reg & (1 << MDIO_MMDREG_SPEED_10M_LBN)) | ||
341 | ecmd->supported |= (SUPPORTED_10baseT_Full | | ||
342 | SUPPORTED_10baseT_Half); | ||
343 | ecmd->advertising = ADVERTISED_TP; | ||
326 | break; | 344 | break; |
327 | /* All the other defined modes are flavours of | 345 | |
328 | * 10G optical */ | 346 | /* We represent CX4 as fibre in the absence of anything better */ |
347 | case MDIO_PMAPMD_CTRL2_10G_CX4: | ||
348 | /* All the other defined modes are flavours of optical */ | ||
329 | default: | 349 | default: |
330 | ecmd->speed = SPEED_10000; | ||
331 | ecmd->port = PORT_FIBRE; | 350 | ecmd->port = PORT_FIBRE; |
332 | ecmd->supported = SUPPORTED_FIBRE; | 351 | ecmd->supported = SUPPORTED_FIBRE; |
333 | ecmd->advertising = ADVERTISED_FIBRE; | 352 | ecmd->advertising = ADVERTISED_FIBRE; |
334 | break; | 353 | break; |
335 | } | 354 | } |
355 | |||
356 | if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) { | ||
357 | ecmd->supported |= SUPPORTED_Autoneg; | ||
358 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | ||
359 | MDIO_MMDREG_CTRL1); | ||
360 | if (reg & BMCR_ANENABLE) { | ||
361 | ecmd->autoneg = AUTONEG_ENABLE; | ||
362 | ecmd->advertising |= | ||
363 | ADVERTISED_Autoneg | | ||
364 | mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) | | ||
365 | npage_adv; | ||
366 | } else | ||
367 | ecmd->autoneg = AUTONEG_DISABLE; | ||
368 | } else | ||
369 | ecmd->autoneg = AUTONEG_DISABLE; | ||
370 | |||
371 | if (ecmd->autoneg) { | ||
372 | /* If AN is complete, report best common mode, | ||
373 | * otherwise report best advertised mode. */ | ||
374 | u32 modes = 0; | ||
375 | if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | ||
376 | MDIO_MMDREG_STAT1) & | ||
377 | (1 << MDIO_AN_STATUS_AN_DONE_LBN)) | ||
378 | modes = (ecmd->advertising & | ||
379 | (mdio_clause45_get_an(efx, MDIO_AN_LPA) | | ||
380 | npage_lpa)); | ||
381 | if (modes == 0) | ||
382 | modes = ecmd->advertising; | ||
383 | |||
384 | if (modes & ADVERTISED_10000baseT_Full) { | ||
385 | ecmd->speed = SPEED_10000; | ||
386 | ecmd->duplex = DUPLEX_FULL; | ||
387 | } else if (modes & (ADVERTISED_1000baseT_Full | | ||
388 | ADVERTISED_1000baseT_Half)) { | ||
389 | ecmd->speed = SPEED_1000; | ||
390 | ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full); | ||
391 | } else if (modes & (ADVERTISED_100baseT_Full | | ||
392 | ADVERTISED_100baseT_Half)) { | ||
393 | ecmd->speed = SPEED_100; | ||
394 | ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full); | ||
395 | } else { | ||
396 | ecmd->speed = SPEED_10; | ||
397 | ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full); | ||
398 | } | ||
399 | } else { | ||
400 | /* Report forced settings */ | ||
401 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
402 | MDIO_MMDREG_CTRL1); | ||
403 | ecmd->speed = (((reg & BMCR_SPEED1000) ? 100 : 1) * | ||
404 | ((reg & BMCR_SPEED100) ? 100 : 10)); | ||
405 | ecmd->duplex = (reg & BMCR_FULLDPLX || | ||
406 | ecmd->speed == SPEED_10000); | ||
407 | } | ||
336 | } | 408 | } |
337 | 409 | ||
338 | /** | 410 | /** |
339 | * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO. | 411 | * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO. |
340 | * @efx: Efx NIC | 412 | * @efx: Efx NIC |
341 | * @ecmd: New settings | 413 | * @ecmd: New settings |
342 | * | ||
343 | * Currently this just enforces that we are _not_ changing the | ||
344 | * 'port', 'speed', 'supported' or 'advertising' settings as these | ||
345 | * cannot be changed on any currently supported PHY. | ||
346 | */ | 414 | */ |
347 | int mdio_clause45_set_settings(struct efx_nic *efx, | 415 | int mdio_clause45_set_settings(struct efx_nic *efx, |
348 | struct ethtool_cmd *ecmd) | 416 | struct ethtool_cmd *ecmd) |
349 | { | 417 | { |
350 | struct ethtool_cmd tmpcmd; | 418 | int phy_id = efx->mii.phy_id; |
351 | mdio_clause45_get_settings(efx, &tmpcmd); | 419 | struct ethtool_cmd prev; |
352 | /* None of the current PHYs support more than one mode | 420 | u32 required; |
353 | * of operation (and only 10GBT ever will), so keep things | 421 | int reg; |
354 | * simple for now */ | 422 | |
355 | if ((ecmd->speed == tmpcmd.speed) && (ecmd->port == tmpcmd.port) && | 423 | efx->phy_op->get_settings(efx, &prev); |
356 | (ecmd->supported == tmpcmd.supported) && | 424 | |
357 | (ecmd->advertising == tmpcmd.advertising)) | 425 | if (ecmd->advertising == prev.advertising && |
426 | ecmd->speed == prev.speed && | ||
427 | ecmd->duplex == prev.duplex && | ||
428 | ecmd->port == prev.port && | ||
429 | ecmd->autoneg == prev.autoneg) | ||
358 | return 0; | 430 | return 0; |
359 | return -EOPNOTSUPP; | 431 | |
432 | /* We can only change these settings for -T PHYs */ | ||
433 | if (prev.port != PORT_TP || ecmd->port != PORT_TP) | ||
434 | return -EINVAL; | ||
435 | |||
436 | /* Check that PHY supports these settings */ | ||
437 | if (ecmd->autoneg) { | ||
438 | required = SUPPORTED_Autoneg; | ||
439 | } else if (ecmd->duplex) { | ||
440 | switch (ecmd->speed) { | ||
441 | case SPEED_10: required = SUPPORTED_10baseT_Full; break; | ||
442 | case SPEED_100: required = SUPPORTED_100baseT_Full; break; | ||
443 | default: return -EINVAL; | ||
444 | } | ||
445 | } else { | ||
446 | switch (ecmd->speed) { | ||
447 | case SPEED_10: required = SUPPORTED_10baseT_Half; break; | ||
448 | case SPEED_100: required = SUPPORTED_100baseT_Half; break; | ||
449 | default: return -EINVAL; | ||
450 | } | ||
451 | } | ||
452 | required |= ecmd->advertising; | ||
453 | if (required & ~prev.supported) | ||
454 | return -EINVAL; | ||
455 | |||
456 | if (ecmd->autoneg) { | ||
457 | bool xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full | ||
458 | || EFX_WORKAROUND_13204(efx)); | ||
459 | |||
460 | /* Set up the base page */ | ||
461 | reg = ADVERTISE_CSMA; | ||
462 | if (ecmd->advertising & ADVERTISED_10baseT_Half) | ||
463 | reg |= ADVERTISE_10HALF; | ||
464 | if (ecmd->advertising & ADVERTISED_10baseT_Full) | ||
465 | reg |= ADVERTISE_10FULL; | ||
466 | if (ecmd->advertising & ADVERTISED_100baseT_Half) | ||
467 | reg |= ADVERTISE_100HALF; | ||
468 | if (ecmd->advertising & ADVERTISED_100baseT_Full) | ||
469 | reg |= ADVERTISE_100FULL; | ||
470 | if (xnp) | ||
471 | reg |= ADVERTISE_RESV; | ||
472 | else if (ecmd->advertising & (ADVERTISED_1000baseT_Half | | ||
473 | ADVERTISED_1000baseT_Full)) | ||
474 | reg |= ADVERTISE_NPAGE; | ||
475 | reg |= efx_fc_advertise(efx->wanted_fc); | ||
476 | mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, | ||
477 | MDIO_AN_ADVERTISE, reg); | ||
478 | |||
479 | /* Set up the (extended) next page if necessary */ | ||
480 | if (efx->phy_op->set_npage_adv) | ||
481 | efx->phy_op->set_npage_adv(efx, ecmd->advertising); | ||
482 | |||
483 | /* Enable and restart AN */ | ||
484 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | ||
485 | MDIO_MMDREG_CTRL1); | ||
486 | reg |= BMCR_ANENABLE; | ||
487 | if (!(EFX_WORKAROUND_15195(efx) && | ||
488 | LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)) | ||
489 | reg |= BMCR_ANRESTART; | ||
490 | if (xnp) | ||
491 | reg |= 1 << MDIO_AN_CTRL_XNP_LBN; | ||
492 | else | ||
493 | reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN); | ||
494 | mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, | ||
495 | MDIO_MMDREG_CTRL1, reg); | ||
496 | } else { | ||
497 | /* Disable AN */ | ||
498 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, | ||
499 | MDIO_MMDREG_CTRL1, | ||
500 | __ffs(BMCR_ANENABLE), false); | ||
501 | |||
502 | /* Set the basic control bits */ | ||
503 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
504 | MDIO_MMDREG_CTRL1); | ||
505 | reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | | ||
506 | 0x003c); | ||
507 | if (ecmd->speed == SPEED_100) | ||
508 | reg |= BMCR_SPEED100; | ||
509 | if (ecmd->duplex) | ||
510 | reg |= BMCR_FULLDPLX; | ||
511 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | ||
512 | MDIO_MMDREG_CTRL1, reg); | ||
513 | } | ||
514 | |||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | void mdio_clause45_set_pause(struct efx_nic *efx) | ||
519 | { | ||
520 | int phy_id = efx->mii.phy_id; | ||
521 | int reg; | ||
522 | |||
523 | if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) { | ||
524 | /* Set pause capability advertising */ | ||
525 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | ||
526 | MDIO_AN_ADVERTISE); | ||
527 | reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); | ||
528 | reg |= efx_fc_advertise(efx->wanted_fc); | ||
529 | mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, | ||
530 | MDIO_AN_ADVERTISE, reg); | ||
531 | |||
532 | /* Restart auto-negotiation */ | ||
533 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | ||
534 | MDIO_MMDREG_CTRL1); | ||
535 | if (reg & BMCR_ANENABLE) { | ||
536 | reg |= BMCR_ANRESTART; | ||
537 | mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, | ||
538 | MDIO_MMDREG_CTRL1, reg); | ||
539 | } | ||
540 | } | ||
541 | } | ||
542 | |||
543 | enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx) | ||
544 | { | ||
545 | int phy_id = efx->mii.phy_id; | ||
546 | int lpa; | ||
547 | |||
548 | if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN))) | ||
549 | return efx->wanted_fc; | ||
550 | lpa = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_AN_LPA); | ||
551 | return efx_fc_resolve(efx->wanted_fc, lpa); | ||
552 | } | ||
553 | |||
554 | void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev, | ||
555 | u16 addr, int bit, bool sense) | ||
556 | { | ||
557 | int old_val = mdio_clause45_read(efx, prt, dev, addr); | ||
558 | int new_val; | ||
559 | |||
560 | if (sense) | ||
561 | new_val = old_val | (1 << bit); | ||
562 | else | ||
563 | new_val = old_val & ~(1 << bit); | ||
564 | if (old_val != new_val) | ||
565 | mdio_clause45_write(efx, prt, dev, addr, new_val); | ||
360 | } | 566 | } |
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h index 19c42eaf7fb4..8ba49773ce7e 100644 --- a/drivers/net/sfc/mdio_10g.h +++ b/drivers/net/sfc/mdio_10g.h | |||
@@ -33,6 +33,8 @@ | |||
33 | #define MDIO_MMD_TC (6) | 33 | #define MDIO_MMD_TC (6) |
34 | /* Auto negotiation */ | 34 | /* Auto negotiation */ |
35 | #define MDIO_MMD_AN (7) | 35 | #define MDIO_MMD_AN (7) |
36 | /* Clause 22 extension */ | ||
37 | #define MDIO_MMD_C22EXT 29 | ||
36 | 38 | ||
37 | /* Generic register locations */ | 39 | /* Generic register locations */ |
38 | #define MDIO_MMDREG_CTRL1 (0) | 40 | #define MDIO_MMDREG_CTRL1 (0) |
@@ -54,6 +56,9 @@ | |||
54 | /* Loopback bit for WIS, PCS, PHYSX and DTEXS */ | 56 | /* Loopback bit for WIS, PCS, PHYSX and DTEXS */ |
55 | #define MDIO_MMDREG_CTRL1_LBACK_LBN (14) | 57 | #define MDIO_MMDREG_CTRL1_LBACK_LBN (14) |
56 | #define MDIO_MMDREG_CTRL1_LBACK_WIDTH (1) | 58 | #define MDIO_MMDREG_CTRL1_LBACK_WIDTH (1) |
59 | /* Low power */ | ||
60 | #define MDIO_MMDREG_CTRL1_LPOWER_LBN (11) | ||
61 | #define MDIO_MMDREG_CTRL1_LPOWER_WIDTH (1) | ||
57 | 62 | ||
58 | /* Bits in MMDREG_STAT1 */ | 63 | /* Bits in MMDREG_STAT1 */ |
59 | #define MDIO_MMDREG_STAT1_FAULT_LBN (7) | 64 | #define MDIO_MMDREG_STAT1_FAULT_LBN (7) |
@@ -70,14 +75,26 @@ | |||
70 | #define MDIO_ID_MODEL(_id32) ((_id32 >> 4) & 0x3f) | 75 | #define MDIO_ID_MODEL(_id32) ((_id32 >> 4) & 0x3f) |
71 | #define MDIO_ID_OUI(_id32) (_id32 >> 10) | 76 | #define MDIO_ID_OUI(_id32) (_id32 >> 10) |
72 | 77 | ||
73 | /* Bits in MMDREG_DEVS0. Someone thoughtfully layed things out | 78 | /* Bits in MMDREG_DEVS0/1. Someone thoughtfully layed things out |
74 | * so the 'bit present' bit number of an MMD is the number of | 79 | * so the 'bit present' bit number of an MMD is the number of |
75 | * that MMD */ | 80 | * that MMD */ |
76 | #define DEV_PRESENT_BIT(_b) (1 << _b) | 81 | #define DEV_PRESENT_BIT(_b) (1 << _b) |
77 | 82 | ||
78 | #define MDIO_MMDREG_DEVS0_PHYXS DEV_PRESENT_BIT(MDIO_MMD_PHYXS) | 83 | #define MDIO_MMDREG_DEVS_PHYXS DEV_PRESENT_BIT(MDIO_MMD_PHYXS) |
79 | #define MDIO_MMDREG_DEVS0_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS) | 84 | #define MDIO_MMDREG_DEVS_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS) |
80 | #define MDIO_MMDREG_DEVS0_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD) | 85 | #define MDIO_MMDREG_DEVS_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD) |
86 | #define MDIO_MMDREG_DEVS_AN DEV_PRESENT_BIT(MDIO_MMD_AN) | ||
87 | #define MDIO_MMDREG_DEVS_C22EXT DEV_PRESENT_BIT(MDIO_MMD_C22EXT) | ||
88 | |||
89 | /* Bits in MMDREG_SPEED */ | ||
90 | #define MDIO_MMDREG_SPEED_10G_LBN 0 | ||
91 | #define MDIO_MMDREG_SPEED_10G_WIDTH 1 | ||
92 | #define MDIO_MMDREG_SPEED_1000M_LBN 4 | ||
93 | #define MDIO_MMDREG_SPEED_1000M_WIDTH 1 | ||
94 | #define MDIO_MMDREG_SPEED_100M_LBN 5 | ||
95 | #define MDIO_MMDREG_SPEED_100M_WIDTH 1 | ||
96 | #define MDIO_MMDREG_SPEED_10M_LBN 6 | ||
97 | #define MDIO_MMDREG_SPEED_10M_WIDTH 1 | ||
81 | 98 | ||
82 | /* Bits in MMDREG_STAT2 */ | 99 | /* Bits in MMDREG_STAT2 */ |
83 | #define MDIO_MMDREG_STAT2_PRESENT_VAL (2) | 100 | #define MDIO_MMDREG_STAT2_PRESENT_VAL (2) |
@@ -111,17 +128,35 @@ | |||
111 | #define MDIO_PMAPMD_CTRL2_10_BT (0xf) | 128 | #define MDIO_PMAPMD_CTRL2_10_BT (0xf) |
112 | #define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf) | 129 | #define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf) |
113 | 130 | ||
131 | /* PMA 10GBT registers */ | ||
132 | #define MDIO_PMAPMD_10GBT_TXPWR (131) | ||
133 | #define MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN (0) | ||
134 | #define MDIO_PMAPMD_10GBT_TXPWR_SHORT_WIDTH (1) | ||
135 | |||
136 | /* PHY XGXS Status 2 */ | ||
137 | #define MDIO_PHYXS_STATUS2 (8) | ||
138 | #define MDIO_PHYXS_STATUS2_RX_FAULT_LBN 10 | ||
139 | |||
114 | /* PHY XGXS lane state */ | 140 | /* PHY XGXS lane state */ |
115 | #define MDIO_PHYXS_LANE_STATE (0x18) | 141 | #define MDIO_PHYXS_LANE_STATE (0x18) |
116 | #define MDIO_PHYXS_LANE_ALIGNED_LBN (12) | 142 | #define MDIO_PHYXS_LANE_ALIGNED_LBN (12) |
117 | 143 | ||
118 | /* AN registers */ | 144 | /* AN registers */ |
145 | #define MDIO_AN_CTRL_XNP_LBN 13 | ||
119 | #define MDIO_AN_STATUS (1) | 146 | #define MDIO_AN_STATUS (1) |
120 | #define MDIO_AN_STATUS_XNP_LBN (7) | 147 | #define MDIO_AN_STATUS_XNP_LBN (7) |
121 | #define MDIO_AN_STATUS_PAGE_LBN (6) | 148 | #define MDIO_AN_STATUS_PAGE_LBN (6) |
122 | #define MDIO_AN_STATUS_AN_DONE_LBN (5) | 149 | #define MDIO_AN_STATUS_AN_DONE_LBN (5) |
123 | #define MDIO_AN_STATUS_LP_AN_CAP_LBN (0) | 150 | #define MDIO_AN_STATUS_LP_AN_CAP_LBN (0) |
124 | 151 | ||
152 | #define MDIO_AN_ADVERTISE 16 | ||
153 | #define MDIO_AN_ADVERTISE_XNP_LBN 12 | ||
154 | #define MDIO_AN_LPA 19 | ||
155 | #define MDIO_AN_XNP 22 | ||
156 | #define MDIO_AN_LPA_XNP 25 | ||
157 | |||
158 | #define MDIO_AN_10GBT_CTRL 32 | ||
159 | #define MDIO_AN_10GBT_CTRL_ADV_10G_LBN 12 | ||
125 | #define MDIO_AN_10GBT_STATUS (33) | 160 | #define MDIO_AN_10GBT_STATUS (33) |
126 | #define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */ | 161 | #define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */ |
127 | #define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */ | 162 | #define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */ |
@@ -240,16 +275,37 @@ extern void mdio_clause45_transmit_disable(struct efx_nic *efx); | |||
240 | /* Generic part of reconfigure: set/clear loopback bits */ | 275 | /* Generic part of reconfigure: set/clear loopback bits */ |
241 | extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx); | 276 | extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx); |
242 | 277 | ||
278 | /* Set the power state of the specified MMDs */ | ||
279 | extern void mdio_clause45_set_mmds_lpower(struct efx_nic *efx, | ||
280 | int low_power, unsigned int mmd_mask); | ||
281 | |||
243 | /* Read (some of) the PHY settings over MDIO */ | 282 | /* Read (some of) the PHY settings over MDIO */ |
244 | extern void mdio_clause45_get_settings(struct efx_nic *efx, | 283 | extern void mdio_clause45_get_settings(struct efx_nic *efx, |
245 | struct ethtool_cmd *ecmd); | 284 | struct ethtool_cmd *ecmd); |
246 | 285 | ||
286 | /* Read (some of) the PHY settings over MDIO */ | ||
287 | extern void | ||
288 | mdio_clause45_get_settings_ext(struct efx_nic *efx, struct ethtool_cmd *ecmd, | ||
289 | u32 xnp, u32 xnp_lpa); | ||
290 | |||
247 | /* Set (some of) the PHY settings over MDIO */ | 291 | /* Set (some of) the PHY settings over MDIO */ |
248 | extern int mdio_clause45_set_settings(struct efx_nic *efx, | 292 | extern int mdio_clause45_set_settings(struct efx_nic *efx, |
249 | struct ethtool_cmd *ecmd); | 293 | struct ethtool_cmd *ecmd); |
250 | 294 | ||
295 | /* Set pause parameters to be advertised through AN (if available) */ | ||
296 | extern void mdio_clause45_set_pause(struct efx_nic *efx); | ||
297 | |||
298 | /* Get pause parameters from AN if available (otherwise return | ||
299 | * requested pause parameters) | ||
300 | */ | ||
301 | enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx); | ||
302 | |||
251 | /* Wait for specified MMDs to exit reset within a timeout */ | 303 | /* Wait for specified MMDs to exit reset within a timeout */ |
252 | extern int mdio_clause45_wait_reset_mmds(struct efx_nic *efx, | 304 | extern int mdio_clause45_wait_reset_mmds(struct efx_nic *efx, |
253 | unsigned int mmd_mask); | 305 | unsigned int mmd_mask); |
254 | 306 | ||
307 | /* Set or clear flag, debouncing */ | ||
308 | extern void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev, | ||
309 | u16 addr, int bit, bool sense); | ||
310 | |||
255 | #endif /* EFX_MDIO_10G_H */ | 311 | #endif /* EFX_MDIO_10G_H */ |
diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c new file mode 100644 index 000000000000..665cafb88d6a --- /dev/null +++ b/drivers/net/sfc/mtd.c | |||
@@ -0,0 +1,268 @@ | |||
1 | /**************************************************************************** | ||
2 | * Driver for Solarflare Solarstorm network controllers and boards | ||
3 | * Copyright 2005-2006 Fen Systems Ltd. | ||
4 | * Copyright 2006-2008 Solarflare Communications Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published | ||
8 | * by the Free Software Foundation, incorporated herein by reference. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/mtd/mtd.h> | ||
13 | #include <linux/delay.h> | ||
14 | |||
15 | #define EFX_DRIVER_NAME "sfc_mtd" | ||
16 | #include "net_driver.h" | ||
17 | #include "spi.h" | ||
18 | |||
19 | #define EFX_SPI_VERIFY_BUF_LEN 16 | ||
20 | |||
21 | struct efx_mtd { | ||
22 | const struct efx_spi_device *spi; | ||
23 | struct mtd_info mtd; | ||
24 | char name[IFNAMSIZ + 20]; | ||
25 | }; | ||
26 | |||
27 | /* SPI utilities */ | ||
28 | |||
29 | static int efx_spi_slow_wait(struct efx_mtd *efx_mtd, bool uninterruptible) | ||
30 | { | ||
31 | const struct efx_spi_device *spi = efx_mtd->spi; | ||
32 | struct efx_nic *efx = spi->efx; | ||
33 | u8 status; | ||
34 | int rc, i; | ||
35 | |||
36 | /* Wait up to 4s for flash/EEPROM to finish a slow operation. */ | ||
37 | for (i = 0; i < 40; i++) { | ||
38 | __set_current_state(uninterruptible ? | ||
39 | TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE); | ||
40 | schedule_timeout(HZ / 10); | ||
41 | rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL, | ||
42 | &status, sizeof(status)); | ||
43 | if (rc) | ||
44 | return rc; | ||
45 | if (!(status & SPI_STATUS_NRDY)) | ||
46 | return 0; | ||
47 | if (signal_pending(current)) | ||
48 | return -EINTR; | ||
49 | } | ||
50 | EFX_ERR(efx, "timed out waiting for %s\n", efx_mtd->name); | ||
51 | return -ETIMEDOUT; | ||
52 | } | ||
53 | |||
54 | static int efx_spi_unlock(const struct efx_spi_device *spi) | ||
55 | { | ||
56 | const u8 unlock_mask = (SPI_STATUS_BP2 | SPI_STATUS_BP1 | | ||
57 | SPI_STATUS_BP0); | ||
58 | u8 status; | ||
59 | int rc; | ||
60 | |||
61 | rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL, &status, sizeof(status)); | ||
62 | if (rc) | ||
63 | return rc; | ||
64 | |||
65 | if (!(status & unlock_mask)) | ||
66 | return 0; /* already unlocked */ | ||
67 | |||
68 | rc = falcon_spi_cmd(spi, SPI_WREN, -1, NULL, NULL, 0); | ||
69 | if (rc) | ||
70 | return rc; | ||
71 | rc = falcon_spi_cmd(spi, SPI_SST_EWSR, -1, NULL, NULL, 0); | ||
72 | if (rc) | ||
73 | return rc; | ||
74 | |||
75 | status &= ~unlock_mask; | ||
76 | rc = falcon_spi_cmd(spi, SPI_WRSR, -1, &status, NULL, sizeof(status)); | ||
77 | if (rc) | ||
78 | return rc; | ||
79 | rc = falcon_spi_wait_write(spi); | ||
80 | if (rc) | ||
81 | return rc; | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static int efx_spi_erase(struct efx_mtd *efx_mtd, loff_t start, size_t len) | ||
87 | { | ||
88 | const struct efx_spi_device *spi = efx_mtd->spi; | ||
89 | unsigned pos, block_len; | ||
90 | u8 empty[EFX_SPI_VERIFY_BUF_LEN]; | ||
91 | u8 buffer[EFX_SPI_VERIFY_BUF_LEN]; | ||
92 | int rc; | ||
93 | |||
94 | if (len != spi->erase_size) | ||
95 | return -EINVAL; | ||
96 | |||
97 | if (spi->erase_command == 0) | ||
98 | return -EOPNOTSUPP; | ||
99 | |||
100 | rc = efx_spi_unlock(spi); | ||
101 | if (rc) | ||
102 | return rc; | ||
103 | rc = falcon_spi_cmd(spi, SPI_WREN, -1, NULL, NULL, 0); | ||
104 | if (rc) | ||
105 | return rc; | ||
106 | rc = falcon_spi_cmd(spi, spi->erase_command, start, NULL, NULL, 0); | ||
107 | if (rc) | ||
108 | return rc; | ||
109 | rc = efx_spi_slow_wait(efx_mtd, false); | ||
110 | |||
111 | /* Verify the entire region has been wiped */ | ||
112 | memset(empty, 0xff, sizeof(empty)); | ||
113 | for (pos = 0; pos < len; pos += block_len) { | ||
114 | block_len = min(len - pos, sizeof(buffer)); | ||
115 | rc = falcon_spi_read(spi, start + pos, block_len, NULL, buffer); | ||
116 | if (rc) | ||
117 | return rc; | ||
118 | if (memcmp(empty, buffer, block_len)) | ||
119 | return -EIO; | ||
120 | |||
121 | /* Avoid locking up the system */ | ||
122 | cond_resched(); | ||
123 | if (signal_pending(current)) | ||
124 | return -EINTR; | ||
125 | } | ||
126 | |||
127 | return rc; | ||
128 | } | ||
129 | |||
130 | /* MTD interface */ | ||
131 | |||
132 | static int efx_mtd_read(struct mtd_info *mtd, loff_t start, size_t len, | ||
133 | size_t *retlen, u8 *buffer) | ||
134 | { | ||
135 | struct efx_mtd *efx_mtd = mtd->priv; | ||
136 | const struct efx_spi_device *spi = efx_mtd->spi; | ||
137 | struct efx_nic *efx = spi->efx; | ||
138 | int rc; | ||
139 | |||
140 | rc = mutex_lock_interruptible(&efx->spi_lock); | ||
141 | if (rc) | ||
142 | return rc; | ||
143 | rc = falcon_spi_read(spi, FALCON_FLASH_BOOTCODE_START + start, | ||
144 | len, retlen, buffer); | ||
145 | mutex_unlock(&efx->spi_lock); | ||
146 | return rc; | ||
147 | } | ||
148 | |||
149 | static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase) | ||
150 | { | ||
151 | struct efx_mtd *efx_mtd = mtd->priv; | ||
152 | struct efx_nic *efx = efx_mtd->spi->efx; | ||
153 | int rc; | ||
154 | |||
155 | rc = mutex_lock_interruptible(&efx->spi_lock); | ||
156 | if (rc) | ||
157 | return rc; | ||
158 | rc = efx_spi_erase(efx_mtd, FALCON_FLASH_BOOTCODE_START + erase->addr, | ||
159 | erase->len); | ||
160 | mutex_unlock(&efx->spi_lock); | ||
161 | |||
162 | if (rc == 0) { | ||
163 | erase->state = MTD_ERASE_DONE; | ||
164 | } else { | ||
165 | erase->state = MTD_ERASE_FAILED; | ||
166 | erase->fail_addr = 0xffffffff; | ||
167 | } | ||
168 | mtd_erase_callback(erase); | ||
169 | return rc; | ||
170 | } | ||
171 | |||
172 | static int efx_mtd_write(struct mtd_info *mtd, loff_t start, | ||
173 | size_t len, size_t *retlen, const u8 *buffer) | ||
174 | { | ||
175 | struct efx_mtd *efx_mtd = mtd->priv; | ||
176 | const struct efx_spi_device *spi = efx_mtd->spi; | ||
177 | struct efx_nic *efx = spi->efx; | ||
178 | int rc; | ||
179 | |||
180 | rc = mutex_lock_interruptible(&efx->spi_lock); | ||
181 | if (rc) | ||
182 | return rc; | ||
183 | rc = falcon_spi_write(spi, FALCON_FLASH_BOOTCODE_START + start, | ||
184 | len, retlen, buffer); | ||
185 | mutex_unlock(&efx->spi_lock); | ||
186 | return rc; | ||
187 | } | ||
188 | |||
189 | static void efx_mtd_sync(struct mtd_info *mtd) | ||
190 | { | ||
191 | struct efx_mtd *efx_mtd = mtd->priv; | ||
192 | struct efx_nic *efx = efx_mtd->spi->efx; | ||
193 | int rc; | ||
194 | |||
195 | mutex_lock(&efx->spi_lock); | ||
196 | rc = efx_spi_slow_wait(efx_mtd, true); | ||
197 | mutex_unlock(&efx->spi_lock); | ||
198 | |||
199 | if (rc) | ||
200 | EFX_ERR(efx, "%s sync failed (%d)\n", efx_mtd->name, rc); | ||
201 | return; | ||
202 | } | ||
203 | |||
204 | void efx_mtd_remove(struct efx_nic *efx) | ||
205 | { | ||
206 | if (efx->spi_flash && efx->spi_flash->mtd) { | ||
207 | struct efx_mtd *efx_mtd = efx->spi_flash->mtd; | ||
208 | int rc; | ||
209 | |||
210 | for (;;) { | ||
211 | rc = del_mtd_device(&efx_mtd->mtd); | ||
212 | if (rc != -EBUSY) | ||
213 | break; | ||
214 | ssleep(1); | ||
215 | } | ||
216 | WARN_ON(rc); | ||
217 | kfree(efx_mtd); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | void efx_mtd_rename(struct efx_nic *efx) | ||
222 | { | ||
223 | if (efx->spi_flash && efx->spi_flash->mtd) { | ||
224 | struct efx_mtd *efx_mtd = efx->spi_flash->mtd; | ||
225 | snprintf(efx_mtd->name, sizeof(efx_mtd->name), | ||
226 | "%s sfc_flash_bootrom", efx->name); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | int efx_mtd_probe(struct efx_nic *efx) | ||
231 | { | ||
232 | struct efx_spi_device *spi = efx->spi_flash; | ||
233 | struct efx_mtd *efx_mtd; | ||
234 | |||
235 | if (!spi || spi->size <= FALCON_FLASH_BOOTCODE_START) | ||
236 | return -ENODEV; | ||
237 | |||
238 | efx_mtd = kzalloc(sizeof(*efx_mtd), GFP_KERNEL); | ||
239 | if (!efx_mtd) | ||
240 | return -ENOMEM; | ||
241 | |||
242 | efx_mtd->spi = spi; | ||
243 | spi->mtd = efx_mtd; | ||
244 | |||
245 | efx_mtd->mtd.type = MTD_NORFLASH; | ||
246 | efx_mtd->mtd.flags = MTD_CAP_NORFLASH; | ||
247 | efx_mtd->mtd.size = spi->size - FALCON_FLASH_BOOTCODE_START; | ||
248 | efx_mtd->mtd.erasesize = spi->erase_size; | ||
249 | efx_mtd->mtd.writesize = 1; | ||
250 | efx_mtd_rename(efx); | ||
251 | |||
252 | efx_mtd->mtd.owner = THIS_MODULE; | ||
253 | efx_mtd->mtd.priv = efx_mtd; | ||
254 | efx_mtd->mtd.name = efx_mtd->name; | ||
255 | efx_mtd->mtd.erase = efx_mtd_erase; | ||
256 | efx_mtd->mtd.read = efx_mtd_read; | ||
257 | efx_mtd->mtd.write = efx_mtd_write; | ||
258 | efx_mtd->mtd.sync = efx_mtd_sync; | ||
259 | |||
260 | if (add_mtd_device(&efx_mtd->mtd)) { | ||
261 | kfree(efx_mtd); | ||
262 | spi->mtd = NULL; | ||
263 | /* add_mtd_device() returns 1 if the MTD table is full */ | ||
264 | return -ENOMEM; | ||
265 | } | ||
266 | |||
267 | return 0; | ||
268 | } | ||
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index cdb11fad6050..e019ad1fb9a0 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -42,7 +42,7 @@ | |||
42 | #ifndef EFX_DRIVER_NAME | 42 | #ifndef EFX_DRIVER_NAME |
43 | #define EFX_DRIVER_NAME "sfc" | 43 | #define EFX_DRIVER_NAME "sfc" |
44 | #endif | 44 | #endif |
45 | #define EFX_DRIVER_VERSION "2.2" | 45 | #define EFX_DRIVER_VERSION "2.3" |
46 | 46 | ||
47 | #ifdef EFX_ENABLE_DEBUG | 47 | #ifdef EFX_ENABLE_DEBUG |
48 | #define EFX_BUG_ON_PARANOID(x) BUG_ON(x) | 48 | #define EFX_BUG_ON_PARANOID(x) BUG_ON(x) |
@@ -327,6 +327,7 @@ enum efx_rx_alloc_method { | |||
327 | * | 327 | * |
328 | * @efx: Associated Efx NIC | 328 | * @efx: Associated Efx NIC |
329 | * @channel: Channel instance number | 329 | * @channel: Channel instance number |
330 | * @name: Name for channel and IRQ | ||
330 | * @used_flags: Channel is used by net driver | 331 | * @used_flags: Channel is used by net driver |
331 | * @enabled: Channel enabled indicator | 332 | * @enabled: Channel enabled indicator |
332 | * @irq: IRQ number (MSI and MSI-X only) | 333 | * @irq: IRQ number (MSI and MSI-X only) |
@@ -357,6 +358,7 @@ enum efx_rx_alloc_method { | |||
357 | struct efx_channel { | 358 | struct efx_channel { |
358 | struct efx_nic *efx; | 359 | struct efx_nic *efx; |
359 | int channel; | 360 | int channel; |
361 | char name[IFNAMSIZ + 6]; | ||
360 | int used_flags; | 362 | int used_flags; |
361 | bool enabled; | 363 | bool enabled; |
362 | int irq; | 364 | int irq; |
@@ -414,6 +416,7 @@ struct efx_blinker { | |||
414 | * @init_leds: Sets up board LEDs | 416 | * @init_leds: Sets up board LEDs |
415 | * @set_fault_led: Turns the fault LED on or off | 417 | * @set_fault_led: Turns the fault LED on or off |
416 | * @blink: Starts/stops blinking | 418 | * @blink: Starts/stops blinking |
419 | * @monitor: Board-specific health check function | ||
417 | * @fini: Cleanup function | 420 | * @fini: Cleanup function |
418 | * @blinker: used to blink LEDs in software | 421 | * @blinker: used to blink LEDs in software |
419 | * @hwmon_client: I2C client for hardware monitor | 422 | * @hwmon_client: I2C client for hardware monitor |
@@ -428,6 +431,7 @@ struct efx_board { | |||
428 | * have a separate init callback that happens later than | 431 | * have a separate init callback that happens later than |
429 | * board init. */ | 432 | * board init. */ |
430 | int (*init_leds)(struct efx_nic *efx); | 433 | int (*init_leds)(struct efx_nic *efx); |
434 | int (*monitor) (struct efx_nic *nic); | ||
431 | void (*set_fault_led) (struct efx_nic *efx, bool state); | 435 | void (*set_fault_led) (struct efx_nic *efx, bool state); |
432 | void (*blink) (struct efx_nic *efx, bool start); | 436 | void (*blink) (struct efx_nic *efx, bool start); |
433 | void (*fini) (struct efx_nic *nic); | 437 | void (*fini) (struct efx_nic *nic); |
@@ -449,16 +453,20 @@ enum efx_int_mode { | |||
449 | 453 | ||
450 | enum phy_type { | 454 | enum phy_type { |
451 | PHY_TYPE_NONE = 0, | 455 | PHY_TYPE_NONE = 0, |
452 | PHY_TYPE_CX4_RTMR = 1, | 456 | PHY_TYPE_TXC43128 = 1, |
453 | PHY_TYPE_1G_ALASKA = 2, | 457 | PHY_TYPE_88E1111 = 2, |
454 | PHY_TYPE_10XPRESS = 3, | 458 | PHY_TYPE_SFX7101 = 3, |
455 | PHY_TYPE_XFP = 4, | 459 | PHY_TYPE_QT2022C2 = 4, |
456 | PHY_TYPE_PM8358 = 6, | 460 | PHY_TYPE_PM8358 = 6, |
461 | PHY_TYPE_SFT9001A = 8, | ||
462 | PHY_TYPE_SFT9001B = 10, | ||
457 | PHY_TYPE_MAX /* Insert any new items before this */ | 463 | PHY_TYPE_MAX /* Insert any new items before this */ |
458 | }; | 464 | }; |
459 | 465 | ||
460 | #define PHY_ADDR_INVALID 0xff | 466 | #define PHY_ADDR_INVALID 0xff |
461 | 467 | ||
468 | #define EFX_IS10G(efx) ((efx)->link_speed == 10000) | ||
469 | |||
462 | enum nic_state { | 470 | enum nic_state { |
463 | STATE_INIT = 0, | 471 | STATE_INIT = 0, |
464 | STATE_RUNNING = 1, | 472 | STATE_RUNNING = 1, |
@@ -499,6 +507,55 @@ enum efx_fc_type { | |||
499 | EFX_FC_AUTO = 4, | 507 | EFX_FC_AUTO = 4, |
500 | }; | 508 | }; |
501 | 509 | ||
510 | /* Supported MAC bit-mask */ | ||
511 | enum efx_mac_type { | ||
512 | EFX_GMAC = 1, | ||
513 | EFX_XMAC = 2, | ||
514 | }; | ||
515 | |||
516 | static inline unsigned int efx_fc_advertise(enum efx_fc_type wanted_fc) | ||
517 | { | ||
518 | unsigned int adv = 0; | ||
519 | if (wanted_fc & EFX_FC_RX) | ||
520 | adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; | ||
521 | if (wanted_fc & EFX_FC_TX) | ||
522 | adv ^= ADVERTISE_PAUSE_ASYM; | ||
523 | return adv; | ||
524 | } | ||
525 | |||
526 | static inline enum efx_fc_type efx_fc_resolve(enum efx_fc_type wanted_fc, | ||
527 | unsigned int lpa) | ||
528 | { | ||
529 | unsigned int adv = efx_fc_advertise(wanted_fc); | ||
530 | |||
531 | if (!(wanted_fc & EFX_FC_AUTO)) | ||
532 | return wanted_fc; | ||
533 | |||
534 | if (adv & lpa & ADVERTISE_PAUSE_CAP) | ||
535 | return EFX_FC_RX | EFX_FC_TX; | ||
536 | if (adv & lpa & ADVERTISE_PAUSE_ASYM) { | ||
537 | if (adv & ADVERTISE_PAUSE_CAP) | ||
538 | return EFX_FC_RX; | ||
539 | if (lpa & ADVERTISE_PAUSE_CAP) | ||
540 | return EFX_FC_TX; | ||
541 | } | ||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | /** | ||
546 | * struct efx_mac_operations - Efx MAC operations table | ||
547 | * @reconfigure: Reconfigure MAC. Serialised by the mac_lock | ||
548 | * @update_stats: Update statistics | ||
549 | * @irq: Hardware MAC event callback. Serialised by the mac_lock | ||
550 | * @poll: Poll for hardware state. Serialised by the mac_lock | ||
551 | */ | ||
552 | struct efx_mac_operations { | ||
553 | void (*reconfigure) (struct efx_nic *efx); | ||
554 | void (*update_stats) (struct efx_nic *efx); | ||
555 | void (*irq) (struct efx_nic *efx); | ||
556 | void (*poll) (struct efx_nic *efx); | ||
557 | }; | ||
558 | |||
502 | /** | 559 | /** |
503 | * struct efx_phy_operations - Efx PHY operations table | 560 | * struct efx_phy_operations - Efx PHY operations table |
504 | * @init: Initialise PHY | 561 | * @init: Initialise PHY |
@@ -506,17 +563,33 @@ enum efx_fc_type { | |||
506 | * @reconfigure: Reconfigure PHY (e.g. for new link parameters) | 563 | * @reconfigure: Reconfigure PHY (e.g. for new link parameters) |
507 | * @clear_interrupt: Clear down interrupt | 564 | * @clear_interrupt: Clear down interrupt |
508 | * @blink: Blink LEDs | 565 | * @blink: Blink LEDs |
509 | * @check_hw: Check hardware | 566 | * @poll: Poll for hardware state. Serialised by the mac_lock. |
567 | * @get_settings: Get ethtool settings. Serialised by the mac_lock. | ||
568 | * @set_settings: Set ethtool settings. Serialised by the mac_lock. | ||
569 | * @set_npage_adv: Set abilities advertised in (Extended) Next Page | ||
570 | * (only needed where AN bit is set in mmds) | ||
571 | * @num_tests: Number of PHY-specific tests/results | ||
572 | * @test_names: Names of the tests/results | ||
573 | * @run_tests: Run tests and record results as appropriate. | ||
574 | * Flags are the ethtool tests flags. | ||
510 | * @mmds: MMD presence mask | 575 | * @mmds: MMD presence mask |
511 | * @loopbacks: Supported loopback modes mask | 576 | * @loopbacks: Supported loopback modes mask |
512 | */ | 577 | */ |
513 | struct efx_phy_operations { | 578 | struct efx_phy_operations { |
579 | enum efx_mac_type macs; | ||
514 | int (*init) (struct efx_nic *efx); | 580 | int (*init) (struct efx_nic *efx); |
515 | void (*fini) (struct efx_nic *efx); | 581 | void (*fini) (struct efx_nic *efx); |
516 | void (*reconfigure) (struct efx_nic *efx); | 582 | void (*reconfigure) (struct efx_nic *efx); |
517 | void (*clear_interrupt) (struct efx_nic *efx); | 583 | void (*clear_interrupt) (struct efx_nic *efx); |
518 | int (*check_hw) (struct efx_nic *efx); | 584 | void (*poll) (struct efx_nic *efx); |
519 | int (*test) (struct efx_nic *efx); | 585 | void (*get_settings) (struct efx_nic *efx, |
586 | struct ethtool_cmd *ecmd); | ||
587 | int (*set_settings) (struct efx_nic *efx, | ||
588 | struct ethtool_cmd *ecmd); | ||
589 | void (*set_npage_adv) (struct efx_nic *efx, u32); | ||
590 | u32 num_tests; | ||
591 | const char *const *test_names; | ||
592 | int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags); | ||
520 | int mmds; | 593 | int mmds; |
521 | unsigned loopbacks; | 594 | unsigned loopbacks; |
522 | }; | 595 | }; |
@@ -525,11 +598,15 @@ struct efx_phy_operations { | |||
525 | * @enum efx_phy_mode - PHY operating mode flags | 598 | * @enum efx_phy_mode - PHY operating mode flags |
526 | * @PHY_MODE_NORMAL: on and should pass traffic | 599 | * @PHY_MODE_NORMAL: on and should pass traffic |
527 | * @PHY_MODE_TX_DISABLED: on with TX disabled | 600 | * @PHY_MODE_TX_DISABLED: on with TX disabled |
601 | * @PHY_MODE_LOW_POWER: set to low power through MDIO | ||
602 | * @PHY_MODE_OFF: switched off through external control | ||
528 | * @PHY_MODE_SPECIAL: on but will not pass traffic | 603 | * @PHY_MODE_SPECIAL: on but will not pass traffic |
529 | */ | 604 | */ |
530 | enum efx_phy_mode { | 605 | enum efx_phy_mode { |
531 | PHY_MODE_NORMAL = 0, | 606 | PHY_MODE_NORMAL = 0, |
532 | PHY_MODE_TX_DISABLED = 1, | 607 | PHY_MODE_TX_DISABLED = 1, |
608 | PHY_MODE_LOW_POWER = 2, | ||
609 | PHY_MODE_OFF = 4, | ||
533 | PHY_MODE_SPECIAL = 8, | 610 | PHY_MODE_SPECIAL = 8, |
534 | }; | 611 | }; |
535 | 612 | ||
@@ -629,7 +706,7 @@ union efx_multicast_hash { | |||
629 | * @legacy_irq: IRQ number | 706 | * @legacy_irq: IRQ number |
630 | * @workqueue: Workqueue for port reconfigures and the HW monitor. | 707 | * @workqueue: Workqueue for port reconfigures and the HW monitor. |
631 | * Work items do not hold and must not acquire RTNL. | 708 | * Work items do not hold and must not acquire RTNL. |
632 | * @reset_workqueue: Workqueue for resets. Work item will acquire RTNL. | 709 | * @workqueue_name: Name of workqueue |
633 | * @reset_work: Scheduled reset workitem | 710 | * @reset_work: Scheduled reset workitem |
634 | * @monitor_work: Hardware monitor workitem | 711 | * @monitor_work: Hardware monitor workitem |
635 | * @membase_phys: Memory BAR value as physical address | 712 | * @membase_phys: Memory BAR value as physical address |
@@ -644,6 +721,7 @@ union efx_multicast_hash { | |||
644 | * @rx_queue: RX DMA queues | 721 | * @rx_queue: RX DMA queues |
645 | * @channel: Channels | 722 | * @channel: Channels |
646 | * @n_rx_queues: Number of RX queues | 723 | * @n_rx_queues: Number of RX queues |
724 | * @n_channels: Number of channels in use | ||
647 | * @rx_buffer_len: RX buffer length | 725 | * @rx_buffer_len: RX buffer length |
648 | * @rx_buffer_order: Order (log2) of number of pages for each RX buffer | 726 | * @rx_buffer_order: Order (log2) of number of pages for each RX buffer |
649 | * @irq_status: Interrupt status buffer | 727 | * @irq_status: Interrupt status buffer |
@@ -655,15 +733,16 @@ union efx_multicast_hash { | |||
655 | * This field will be %NULL if no flash device is present. | 733 | * This field will be %NULL if no flash device is present. |
656 | * @spi_eeprom: SPI EEPROM device | 734 | * @spi_eeprom: SPI EEPROM device |
657 | * This field will be %NULL if no EEPROM device is present. | 735 | * This field will be %NULL if no EEPROM device is present. |
736 | * @spi_lock: SPI bus lock | ||
658 | * @n_rx_nodesc_drop_cnt: RX no descriptor drop count | 737 | * @n_rx_nodesc_drop_cnt: RX no descriptor drop count |
659 | * @nic_data: Hardware dependant state | 738 | * @nic_data: Hardware dependant state |
660 | * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode, | 739 | * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode, |
661 | * @port_inhibited, efx_monitor() and efx_reconfigure_port() | 740 | * @port_inhibited, efx_monitor() and efx_reconfigure_port() |
662 | * @port_enabled: Port enabled indicator. | 741 | * @port_enabled: Port enabled indicator. |
663 | * Serialises efx_stop_all(), efx_start_all() and efx_monitor() and | 742 | * Serialises efx_stop_all(), efx_start_all(), efx_monitor(), |
664 | * efx_reconfigure_work with kernel interfaces. Safe to read under any | 743 | * efx_phy_work(), and efx_mac_work() with kernel interfaces. Safe to read |
665 | * one of the rtnl_lock, mac_lock, or netif_tx_lock, but all three must | 744 | * under any one of the rtnl_lock, mac_lock, or netif_tx_lock, but all |
666 | * be held to modify it. | 745 | * three must be held to modify it. |
667 | * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock | 746 | * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock |
668 | * @port_initialized: Port initialized? | 747 | * @port_initialized: Port initialized? |
669 | * @net_dev: Operating system network device. Consider holding the rtnl lock | 748 | * @net_dev: Operating system network device. Consider holding the rtnl lock |
@@ -675,8 +754,8 @@ union efx_multicast_hash { | |||
675 | * &struct net_device_stats. | 754 | * &struct net_device_stats. |
676 | * @stats_buffer: DMA buffer for statistics | 755 | * @stats_buffer: DMA buffer for statistics |
677 | * @stats_lock: Statistics update lock. Serialises statistics fetches | 756 | * @stats_lock: Statistics update lock. Serialises statistics fetches |
678 | * @stats_enabled: Temporarily disable statistics fetches. | 757 | * @stats_disable_count: Nest count for disabling statistics fetches |
679 | * Serialised by @stats_lock | 758 | * @mac_op: MAC interface |
680 | * @mac_address: Permanent MAC address | 759 | * @mac_address: Permanent MAC address |
681 | * @phy_type: PHY type | 760 | * @phy_type: PHY type |
682 | * @phy_lock: PHY access lock | 761 | * @phy_lock: PHY access lock |
@@ -684,13 +763,17 @@ union efx_multicast_hash { | |||
684 | * @phy_data: PHY private data (including PHY-specific stats) | 763 | * @phy_data: PHY private data (including PHY-specific stats) |
685 | * @mii: PHY interface | 764 | * @mii: PHY interface |
686 | * @phy_mode: PHY operating mode. Serialised by @mac_lock. | 765 | * @phy_mode: PHY operating mode. Serialised by @mac_lock. |
766 | * @mac_up: MAC link state | ||
687 | * @link_up: Link status | 767 | * @link_up: Link status |
688 | * @link_options: Link options (MII/GMII format) | 768 | * @link_fd: Link is full duplex |
769 | * @link_fc: Actualy flow control flags | ||
770 | * @link_speed: Link speed (Mbps) | ||
689 | * @n_link_state_changes: Number of times the link has changed state | 771 | * @n_link_state_changes: Number of times the link has changed state |
690 | * @promiscuous: Promiscuous flag. Protected by netif_tx_lock. | 772 | * @promiscuous: Promiscuous flag. Protected by netif_tx_lock. |
691 | * @multicast_hash: Multicast hash table | 773 | * @multicast_hash: Multicast hash table |
692 | * @flow_control: Flow control flags - separate RX/TX so can't use link_options | 774 | * @wanted_fc: Wanted flow control flags |
693 | * @reconfigure_work: work item for dealing with PHY events | 775 | * @phy_work: work item for dealing with PHY events |
776 | * @mac_work: work item for dealing with MAC events | ||
694 | * @loopback_mode: Loopback status | 777 | * @loopback_mode: Loopback status |
695 | * @loopback_modes: Supported loopback mode bitmask | 778 | * @loopback_modes: Supported loopback mode bitmask |
696 | * @loopback_selftest: Offline self-test private state | 779 | * @loopback_selftest: Offline self-test private state |
@@ -704,7 +787,7 @@ struct efx_nic { | |||
704 | const struct efx_nic_type *type; | 787 | const struct efx_nic_type *type; |
705 | int legacy_irq; | 788 | int legacy_irq; |
706 | struct workqueue_struct *workqueue; | 789 | struct workqueue_struct *workqueue; |
707 | struct workqueue_struct *reset_workqueue; | 790 | char workqueue_name[16]; |
708 | struct work_struct reset_work; | 791 | struct work_struct reset_work; |
709 | struct delayed_work monitor_work; | 792 | struct delayed_work monitor_work; |
710 | resource_size_t membase_phys; | 793 | resource_size_t membase_phys; |
@@ -723,6 +806,7 @@ struct efx_nic { | |||
723 | struct efx_channel channel[EFX_MAX_CHANNELS]; | 806 | struct efx_channel channel[EFX_MAX_CHANNELS]; |
724 | 807 | ||
725 | int n_rx_queues; | 808 | int n_rx_queues; |
809 | int n_channels; | ||
726 | unsigned int rx_buffer_len; | 810 | unsigned int rx_buffer_len; |
727 | unsigned int rx_buffer_order; | 811 | unsigned int rx_buffer_order; |
728 | 812 | ||
@@ -731,12 +815,14 @@ struct efx_nic { | |||
731 | 815 | ||
732 | struct efx_spi_device *spi_flash; | 816 | struct efx_spi_device *spi_flash; |
733 | struct efx_spi_device *spi_eeprom; | 817 | struct efx_spi_device *spi_eeprom; |
818 | struct mutex spi_lock; | ||
734 | 819 | ||
735 | unsigned n_rx_nodesc_drop_cnt; | 820 | unsigned n_rx_nodesc_drop_cnt; |
736 | 821 | ||
737 | struct falcon_nic_data *nic_data; | 822 | struct falcon_nic_data *nic_data; |
738 | 823 | ||
739 | struct mutex mac_lock; | 824 | struct mutex mac_lock; |
825 | struct work_struct mac_work; | ||
740 | bool port_enabled; | 826 | bool port_enabled; |
741 | bool port_inhibited; | 827 | bool port_inhibited; |
742 | 828 | ||
@@ -750,25 +836,29 @@ struct efx_nic { | |||
750 | struct efx_mac_stats mac_stats; | 836 | struct efx_mac_stats mac_stats; |
751 | struct efx_buffer stats_buffer; | 837 | struct efx_buffer stats_buffer; |
752 | spinlock_t stats_lock; | 838 | spinlock_t stats_lock; |
753 | bool stats_enabled; | 839 | unsigned int stats_disable_count; |
754 | 840 | ||
841 | struct efx_mac_operations *mac_op; | ||
755 | unsigned char mac_address[ETH_ALEN]; | 842 | unsigned char mac_address[ETH_ALEN]; |
756 | 843 | ||
757 | enum phy_type phy_type; | 844 | enum phy_type phy_type; |
758 | spinlock_t phy_lock; | 845 | spinlock_t phy_lock; |
846 | struct work_struct phy_work; | ||
759 | struct efx_phy_operations *phy_op; | 847 | struct efx_phy_operations *phy_op; |
760 | void *phy_data; | 848 | void *phy_data; |
761 | struct mii_if_info mii; | 849 | struct mii_if_info mii; |
762 | enum efx_phy_mode phy_mode; | 850 | enum efx_phy_mode phy_mode; |
763 | 851 | ||
852 | bool mac_up; | ||
764 | bool link_up; | 853 | bool link_up; |
765 | unsigned int link_options; | 854 | bool link_fd; |
855 | enum efx_fc_type link_fc; | ||
856 | unsigned int link_speed; | ||
766 | unsigned int n_link_state_changes; | 857 | unsigned int n_link_state_changes; |
767 | 858 | ||
768 | bool promiscuous; | 859 | bool promiscuous; |
769 | union efx_multicast_hash multicast_hash; | 860 | union efx_multicast_hash multicast_hash; |
770 | enum efx_fc_type flow_control; | 861 | enum efx_fc_type wanted_fc; |
771 | struct work_struct reconfigure_work; | ||
772 | 862 | ||
773 | atomic_t rx_reset; | 863 | atomic_t rx_reset; |
774 | enum efx_loopback_mode loopback_mode; | 864 | enum efx_loopback_mode loopback_mode; |
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h index f746536f4ffa..07e855c148bc 100644 --- a/drivers/net/sfc/phy.h +++ b/drivers/net/sfc/phy.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /**************************************************************************** | 1 | /**************************************************************************** |
2 | * Driver for Solarflare Solarstorm network controllers and boards | 2 | * Driver for Solarflare Solarstorm network controllers and boards |
3 | * Copyright 2007 Solarflare Communications Inc. | 3 | * Copyright 2007-2008 Solarflare Communications Inc. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 as published | 6 | * under the terms of the GNU General Public License version 2 as published |
@@ -11,12 +11,12 @@ | |||
11 | #define EFX_PHY_H | 11 | #define EFX_PHY_H |
12 | 12 | ||
13 | /**************************************************************************** | 13 | /**************************************************************************** |
14 | * 10Xpress (SFX7101) PHY | 14 | * 10Xpress (SFX7101 and SFT9001) PHYs |
15 | */ | 15 | */ |
16 | extern struct efx_phy_operations falcon_tenxpress_phy_ops; | 16 | extern struct efx_phy_operations falcon_sfx7101_phy_ops; |
17 | extern struct efx_phy_operations falcon_sft9001_phy_ops; | ||
17 | 18 | ||
18 | extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); | 19 | extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); |
19 | extern void tenxpress_crc_err(struct efx_nic *efx); | ||
20 | 20 | ||
21 | /**************************************************************************** | 21 | /**************************************************************************** |
22 | * Exported functions from the driver for XFP optical PHYs | 22 | * Exported functions from the driver for XFP optical PHYs |
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 0f805da4ce55..b8ba4bbad889 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c | |||
@@ -752,7 +752,7 @@ void __efx_rx_packet(struct efx_channel *channel, | |||
752 | channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; | 752 | channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; |
753 | 753 | ||
754 | done: | 754 | done: |
755 | efx->net_dev->last_rx = jiffies; | 755 | ; |
756 | } | 756 | } |
757 | 757 | ||
758 | void efx_rx_strategy(struct efx_channel *channel) | 758 | void efx_rx_strategy(struct efx_channel *channel) |
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index 362956e3fe17..0a598084c513 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include "selftest.h" | 26 | #include "selftest.h" |
27 | #include "boards.h" | 27 | #include "boards.h" |
28 | #include "workarounds.h" | 28 | #include "workarounds.h" |
29 | #include "mac.h" | ||
30 | #include "spi.h" | 29 | #include "spi.h" |
31 | #include "falcon_io.h" | 30 | #include "falcon_io.h" |
32 | #include "mdio_10g.h" | 31 | #include "mdio_10g.h" |
@@ -105,9 +104,11 @@ static int efx_test_mii(struct efx_nic *efx, struct efx_self_tests *tests) | |||
105 | goto out; | 104 | goto out; |
106 | } | 105 | } |
107 | 106 | ||
108 | rc = mdio_clause45_check_mmds(efx, efx->phy_op->mmds, 0); | 107 | if (EFX_IS10G(efx)) { |
109 | if (rc) | 108 | rc = mdio_clause45_check_mmds(efx, efx->phy_op->mmds, 0); |
110 | goto out; | 109 | if (rc) |
110 | goto out; | ||
111 | } | ||
111 | 112 | ||
112 | out: | 113 | out: |
113 | mutex_unlock(&efx->mac_lock); | 114 | mutex_unlock(&efx->mac_lock); |
@@ -246,17 +247,20 @@ static int efx_test_eventq_irq(struct efx_channel *channel, | |||
246 | return 0; | 247 | return 0; |
247 | } | 248 | } |
248 | 249 | ||
249 | static int efx_test_phy(struct efx_nic *efx, struct efx_self_tests *tests) | 250 | static int efx_test_phy(struct efx_nic *efx, struct efx_self_tests *tests, |
251 | unsigned flags) | ||
250 | { | 252 | { |
251 | int rc; | 253 | int rc; |
252 | 254 | ||
253 | if (!efx->phy_op->test) | 255 | if (!efx->phy_op->run_tests) |
254 | return 0; | 256 | return 0; |
255 | 257 | ||
258 | EFX_BUG_ON_PARANOID(efx->phy_op->num_tests == 0 || | ||
259 | efx->phy_op->num_tests > EFX_MAX_PHY_TESTS); | ||
260 | |||
256 | mutex_lock(&efx->mac_lock); | 261 | mutex_lock(&efx->mac_lock); |
257 | rc = efx->phy_op->test(efx); | 262 | rc = efx->phy_op->run_tests(efx, tests->phy, flags); |
258 | mutex_unlock(&efx->mac_lock); | 263 | mutex_unlock(&efx->mac_lock); |
259 | tests->phy = rc ? -1 : 1; | ||
260 | return rc; | 264 | return rc; |
261 | } | 265 | } |
262 | 266 | ||
@@ -563,8 +567,7 @@ efx_test_loopback(struct efx_tx_queue *tx_queue, | |||
563 | return 0; | 567 | return 0; |
564 | } | 568 | } |
565 | 569 | ||
566 | static int efx_test_loopbacks(struct efx_nic *efx, struct ethtool_cmd ecmd, | 570 | static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests, |
567 | struct efx_self_tests *tests, | ||
568 | unsigned int loopback_modes) | 571 | unsigned int loopback_modes) |
569 | { | 572 | { |
570 | enum efx_loopback_mode mode; | 573 | enum efx_loopback_mode mode; |
@@ -593,12 +596,14 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct ethtool_cmd ecmd, | |||
593 | efx->loopback_mode = mode; | 596 | efx->loopback_mode = mode; |
594 | efx_reconfigure_port(efx); | 597 | efx_reconfigure_port(efx); |
595 | 598 | ||
596 | /* Wait for the PHY to signal the link is up */ | 599 | /* Wait for the PHY to signal the link is up. Interrupts |
600 | * are enabled for PHY's using LASI, otherwise we poll() | ||
601 | * quickly */ | ||
597 | count = 0; | 602 | count = 0; |
598 | do { | 603 | do { |
599 | struct efx_channel *channel = &efx->channel[0]; | 604 | struct efx_channel *channel = &efx->channel[0]; |
600 | 605 | ||
601 | falcon_check_xmac(efx); | 606 | efx->phy_op->poll(efx); |
602 | schedule_timeout_uninterruptible(HZ / 10); | 607 | schedule_timeout_uninterruptible(HZ / 10); |
603 | if (channel->work_pending) | 608 | if (channel->work_pending) |
604 | efx_process_channel_now(channel); | 609 | efx_process_channel_now(channel); |
@@ -606,13 +611,12 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct ethtool_cmd ecmd, | |||
606 | flush_workqueue(efx->workqueue); | 611 | flush_workqueue(efx->workqueue); |
607 | rmb(); | 612 | rmb(); |
608 | 613 | ||
609 | /* efx->link_up can be 1 even if the XAUI link is down, | 614 | /* We need both the phy and xaui links to be ok. |
610 | * (bug5762). Usually, it's not worth bothering with the | 615 | * rather than relying on the falcon_xmac irq/poll |
611 | * difference, but for selftests, we need that extra | 616 | * regime, just poll xaui directly */ |
612 | * guarantee that the link is really, really, up. | ||
613 | */ | ||
614 | link_up = efx->link_up; | 617 | link_up = efx->link_up; |
615 | if (!falcon_xaui_link_ok(efx)) | 618 | if (link_up && EFX_IS10G(efx) && |
619 | !falcon_xaui_link_ok(efx)) | ||
616 | link_up = false; | 620 | link_up = false; |
617 | 621 | ||
618 | } while ((++count < 20) && !link_up); | 622 | } while ((++count < 20) && !link_up); |
@@ -652,47 +656,49 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct ethtool_cmd ecmd, | |||
652 | 656 | ||
653 | /************************************************************************** | 657 | /************************************************************************** |
654 | * | 658 | * |
655 | * Entry points | 659 | * Entry point |
656 | * | 660 | * |
657 | *************************************************************************/ | 661 | *************************************************************************/ |
658 | 662 | ||
659 | /* Online (i.e. non-disruptive) testing | 663 | int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests, |
660 | * This checks interrupt generation, event delivery and PHY presence. */ | 664 | unsigned flags) |
661 | int efx_online_test(struct efx_nic *efx, struct efx_self_tests *tests) | ||
662 | { | 665 | { |
666 | enum efx_loopback_mode loopback_mode = efx->loopback_mode; | ||
667 | int phy_mode = efx->phy_mode; | ||
668 | enum reset_type reset_method = RESET_TYPE_INVISIBLE; | ||
669 | struct ethtool_cmd ecmd; | ||
663 | struct efx_channel *channel; | 670 | struct efx_channel *channel; |
664 | int rc, rc2 = 0; | 671 | int rc_test = 0, rc_reset = 0, rc; |
672 | |||
673 | /* Online (i.e. non-disruptive) testing | ||
674 | * This checks interrupt generation, event delivery and PHY presence. */ | ||
665 | 675 | ||
666 | rc = efx_test_mii(efx, tests); | 676 | rc = efx_test_mii(efx, tests); |
667 | if (rc && !rc2) | 677 | if (rc && !rc_test) |
668 | rc2 = rc; | 678 | rc_test = rc; |
669 | 679 | ||
670 | rc = efx_test_nvram(efx, tests); | 680 | rc = efx_test_nvram(efx, tests); |
671 | if (rc && !rc2) | 681 | if (rc && !rc_test) |
672 | rc2 = rc; | 682 | rc_test = rc; |
673 | 683 | ||
674 | rc = efx_test_interrupts(efx, tests); | 684 | rc = efx_test_interrupts(efx, tests); |
675 | if (rc && !rc2) | 685 | if (rc && !rc_test) |
676 | rc2 = rc; | 686 | rc_test = rc; |
677 | 687 | ||
678 | efx_for_each_channel(channel, efx) { | 688 | efx_for_each_channel(channel, efx) { |
679 | rc = efx_test_eventq_irq(channel, tests); | 689 | rc = efx_test_eventq_irq(channel, tests); |
680 | if (rc && !rc2) | 690 | if (rc && !rc_test) |
681 | rc2 = rc; | 691 | rc_test = rc; |
682 | } | 692 | } |
683 | 693 | ||
684 | return rc2; | 694 | if (rc_test) |
685 | } | 695 | return rc_test; |
686 | 696 | ||
687 | /* Offline (i.e. disruptive) testing | 697 | if (!(flags & ETH_TEST_FL_OFFLINE)) |
688 | * This checks MAC and PHY loopback on the specified port. */ | 698 | return efx_test_phy(efx, tests, flags); |
689 | int efx_offline_test(struct efx_nic *efx, | 699 | |
690 | struct efx_self_tests *tests, unsigned int loopback_modes) | 700 | /* Offline (i.e. disruptive) testing |
691 | { | 701 | * This checks MAC and PHY loopback on the specified port. */ |
692 | enum efx_loopback_mode loopback_mode = efx->loopback_mode; | ||
693 | int phy_mode = efx->phy_mode; | ||
694 | struct ethtool_cmd ecmd, ecmd_test; | ||
695 | int rc, rc2 = 0; | ||
696 | 702 | ||
697 | /* force the carrier state off so the kernel doesn't transmit during | 703 | /* force the carrier state off so the kernel doesn't transmit during |
698 | * the loopback test, and the watchdog timeout doesn't fire. Also put | 704 | * the loopback test, and the watchdog timeout doesn't fire. Also put |
@@ -700,48 +706,50 @@ int efx_offline_test(struct efx_nic *efx, | |||
700 | */ | 706 | */ |
701 | mutex_lock(&efx->mac_lock); | 707 | mutex_lock(&efx->mac_lock); |
702 | efx->port_inhibited = true; | 708 | efx->port_inhibited = true; |
703 | if (efx->loopback_modes) | 709 | if (efx->loopback_modes) { |
704 | efx->loopback_mode = __ffs(efx->loopback_modes); | 710 | /* We need the 312 clock from the PHY to test the XMAC |
711 | * registers, so move into XGMII loopback if available */ | ||
712 | if (efx->loopback_modes & (1 << LOOPBACK_XGMII)) | ||
713 | efx->loopback_mode = LOOPBACK_XGMII; | ||
714 | else | ||
715 | efx->loopback_mode = __ffs(efx->loopback_modes); | ||
716 | } | ||
717 | |||
705 | __efx_reconfigure_port(efx); | 718 | __efx_reconfigure_port(efx); |
706 | mutex_unlock(&efx->mac_lock); | 719 | mutex_unlock(&efx->mac_lock); |
707 | 720 | ||
708 | /* free up all consumers of SRAM (including all the queues) */ | 721 | /* free up all consumers of SRAM (including all the queues) */ |
709 | efx_reset_down(efx, &ecmd); | 722 | efx_reset_down(efx, reset_method, &ecmd); |
710 | 723 | ||
711 | rc = efx_test_chip(efx, tests); | 724 | rc = efx_test_chip(efx, tests); |
712 | if (rc && !rc2) | 725 | if (rc && !rc_test) |
713 | rc2 = rc; | 726 | rc_test = rc; |
714 | 727 | ||
715 | /* reset the chip to recover from the register test */ | 728 | /* reset the chip to recover from the register test */ |
716 | rc = falcon_reset_hw(efx, RESET_TYPE_ALL); | 729 | rc_reset = falcon_reset_hw(efx, reset_method); |
717 | 730 | ||
718 | /* Modify the saved ecmd so that when efx_reset_up() restores the phy | 731 | /* Ensure that the phy is powered and out of loopback |
719 | * state, AN is disabled, and the phy is powered, and out of loopback */ | 732 | * for the bist and loopback tests */ |
720 | memcpy(&ecmd_test, &ecmd, sizeof(ecmd_test)); | 733 | efx->phy_mode &= ~PHY_MODE_LOW_POWER; |
721 | if (ecmd_test.autoneg == AUTONEG_ENABLE) { | ||
722 | ecmd_test.autoneg = AUTONEG_DISABLE; | ||
723 | ecmd_test.duplex = DUPLEX_FULL; | ||
724 | ecmd_test.speed = SPEED_10000; | ||
725 | } | ||
726 | efx->loopback_mode = LOOPBACK_NONE; | 734 | efx->loopback_mode = LOOPBACK_NONE; |
727 | 735 | ||
728 | rc = efx_reset_up(efx, &ecmd_test, rc == 0); | 736 | rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0); |
729 | if (rc) { | 737 | if (rc && !rc_reset) |
738 | rc_reset = rc; | ||
739 | |||
740 | if (rc_reset) { | ||
730 | EFX_ERR(efx, "Unable to recover from chip test\n"); | 741 | EFX_ERR(efx, "Unable to recover from chip test\n"); |
731 | efx_schedule_reset(efx, RESET_TYPE_DISABLE); | 742 | efx_schedule_reset(efx, RESET_TYPE_DISABLE); |
732 | return rc; | 743 | return rc_reset; |
733 | } | 744 | } |
734 | 745 | ||
735 | tests->loopback_speed = ecmd_test.speed; | 746 | rc = efx_test_phy(efx, tests, flags); |
736 | tests->loopback_full_duplex = ecmd_test.duplex; | 747 | if (rc && !rc_test) |
737 | 748 | rc_test = rc; | |
738 | rc = efx_test_phy(efx, tests); | ||
739 | if (rc && !rc2) | ||
740 | rc2 = rc; | ||
741 | 749 | ||
742 | rc = efx_test_loopbacks(efx, ecmd_test, tests, loopback_modes); | 750 | rc = efx_test_loopbacks(efx, tests, efx->loopback_modes); |
743 | if (rc && !rc2) | 751 | if (rc && !rc_test) |
744 | rc2 = rc; | 752 | rc_test = rc; |
745 | 753 | ||
746 | /* restore the PHY to the previous state */ | 754 | /* restore the PHY to the previous state */ |
747 | efx->loopback_mode = loopback_mode; | 755 | efx->loopback_mode = loopback_mode; |
@@ -749,6 +757,6 @@ int efx_offline_test(struct efx_nic *efx, | |||
749 | efx->port_inhibited = false; | 757 | efx->port_inhibited = false; |
750 | efx_ethtool_set_settings(efx->net_dev, &ecmd); | 758 | efx_ethtool_set_settings(efx->net_dev, &ecmd); |
751 | 759 | ||
752 | return rc2; | 760 | return rc_test; |
753 | } | 761 | } |
754 | 762 | ||
diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h index fc15df15d766..39451cf938cf 100644 --- a/drivers/net/sfc/selftest.h +++ b/drivers/net/sfc/selftest.h | |||
@@ -24,6 +24,8 @@ struct efx_loopback_self_tests { | |||
24 | int rx_bad; | 24 | int rx_bad; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | #define EFX_MAX_PHY_TESTS 20 | ||
28 | |||
27 | /* Efx self test results | 29 | /* Efx self test results |
28 | * For fields which are not counters, 1 indicates success and -1 | 30 | * For fields which are not counters, 1 indicates success and -1 |
29 | * indicates failure. | 31 | * indicates failure. |
@@ -38,18 +40,14 @@ struct efx_self_tests { | |||
38 | int eventq_poll[EFX_MAX_CHANNELS]; | 40 | int eventq_poll[EFX_MAX_CHANNELS]; |
39 | /* offline tests */ | 41 | /* offline tests */ |
40 | int registers; | 42 | int registers; |
41 | int phy; | 43 | int phy[EFX_MAX_PHY_TESTS]; |
42 | int loopback_speed; | ||
43 | int loopback_full_duplex; | ||
44 | struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1]; | 44 | struct efx_loopback_self_tests loopback[LOOPBACK_TEST_MAX + 1]; |
45 | }; | 45 | }; |
46 | 46 | ||
47 | extern void efx_loopback_rx_packet(struct efx_nic *efx, | 47 | extern void efx_loopback_rx_packet(struct efx_nic *efx, |
48 | const char *buf_ptr, int pkt_len); | 48 | const char *buf_ptr, int pkt_len); |
49 | extern int efx_online_test(struct efx_nic *efx, | 49 | extern int efx_selftest(struct efx_nic *efx, |
50 | struct efx_self_tests *tests); | 50 | struct efx_self_tests *tests, |
51 | extern int efx_offline_test(struct efx_nic *efx, | 51 | unsigned flags); |
52 | struct efx_self_tests *tests, | ||
53 | unsigned int loopback_modes); | ||
54 | 52 | ||
55 | #endif /* EFX_SELFTEST_H */ | 53 | #endif /* EFX_SELFTEST_H */ |
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index fe4e3fd22330..cb25ae5b257a 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /**************************************************************************** | 1 | /**************************************************************************** |
2 | * Driver for Solarflare Solarstorm network controllers and boards | 2 | * Driver for Solarflare Solarstorm network controllers and boards |
3 | * Copyright 2007 Solarflare Communications Inc. | 3 | * Copyright 2007-2008 Solarflare Communications Inc. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 as published | 6 | * under the terms of the GNU General Public License version 2 as published |
@@ -8,10 +8,21 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | /***************************************************************************** | 10 | /***************************************************************************** |
11 | * Support for the SFE4001 NIC: driver code for the PCA9539 I/O expander that | 11 | * Support for the SFE4001 and SFN4111T NICs. |
12 | * controls the PHY power rails, and for the MAX6647 temp. sensor used to check | 12 | * |
13 | * the PHY | 13 | * The SFE4001 does not power-up fully at reset due to its high power |
14 | * consumption. We control its power via a PCA9539 I/O expander. | ||
15 | * Both boards have a MAX6647 temperature monitor which we expose to | ||
16 | * the lm90 driver. | ||
17 | * | ||
18 | * This also provides minimal support for reflashing the PHY, which is | ||
19 | * initiated by resetting it with the FLASH_CFG_1 pin pulled down. | ||
20 | * On SFE4001 rev A2 and later this is connected to the 3V3X output of | ||
21 | * the IO-expander; on the SFN4111T it is connected to Falcon's GPIO3. | ||
22 | * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually | ||
23 | * exclusive with the network device being open. | ||
14 | */ | 24 | */ |
25 | |||
15 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
16 | #include "net_driver.h" | 27 | #include "net_driver.h" |
17 | #include "efx.h" | 28 | #include "efx.h" |
@@ -21,6 +32,7 @@ | |||
21 | #include "falcon_hwdefs.h" | 32 | #include "falcon_hwdefs.h" |
22 | #include "falcon_io.h" | 33 | #include "falcon_io.h" |
23 | #include "mac.h" | 34 | #include "mac.h" |
35 | #include "workarounds.h" | ||
24 | 36 | ||
25 | /************************************************************************** | 37 | /************************************************************************** |
26 | * | 38 | * |
@@ -65,48 +77,9 @@ | |||
65 | #define P1_SPARE_LBN 4 | 77 | #define P1_SPARE_LBN 4 |
66 | #define P1_SPARE_WIDTH 4 | 78 | #define P1_SPARE_WIDTH 4 |
67 | 79 | ||
68 | 80 | /* Temperature Sensor */ | |
69 | /************************************************************************** | 81 | #define MAX664X_REG_RSL 0x02 |
70 | * | 82 | #define MAX664X_REG_WLHO 0x0B |
71 | * Temperature Sensor | ||
72 | * | ||
73 | **************************************************************************/ | ||
74 | #define MAX6647 0x4e | ||
75 | |||
76 | #define RLTS 0x00 | ||
77 | #define RLTE 0x01 | ||
78 | #define RSL 0x02 | ||
79 | #define RCL 0x03 | ||
80 | #define RCRA 0x04 | ||
81 | #define RLHN 0x05 | ||
82 | #define RLLI 0x06 | ||
83 | #define RRHI 0x07 | ||
84 | #define RRLS 0x08 | ||
85 | #define WCRW 0x0a | ||
86 | #define WLHO 0x0b | ||
87 | #define WRHA 0x0c | ||
88 | #define WRLN 0x0e | ||
89 | #define OSHT 0x0f | ||
90 | #define REET 0x10 | ||
91 | #define RIET 0x11 | ||
92 | #define RWOE 0x19 | ||
93 | #define RWOI 0x20 | ||
94 | #define HYS 0x21 | ||
95 | #define QUEUE 0x22 | ||
96 | #define MFID 0xfe | ||
97 | #define REVID 0xff | ||
98 | |||
99 | /* Status bits */ | ||
100 | #define MAX6647_BUSY (1 << 7) /* ADC is converting */ | ||
101 | #define MAX6647_LHIGH (1 << 6) /* Local high temp. alarm */ | ||
102 | #define MAX6647_LLOW (1 << 5) /* Local low temp. alarm */ | ||
103 | #define MAX6647_RHIGH (1 << 4) /* Remote high temp. alarm */ | ||
104 | #define MAX6647_RLOW (1 << 3) /* Remote low temp. alarm */ | ||
105 | #define MAX6647_FAULT (1 << 2) /* DXN/DXP short/open circuit */ | ||
106 | #define MAX6647_EOT (1 << 1) /* Remote junction overtemp. */ | ||
107 | #define MAX6647_IOT (1 << 0) /* Local junction overtemp. */ | ||
108 | |||
109 | static const u8 xgphy_max_temperature = 90; | ||
110 | 83 | ||
111 | static void sfe4001_poweroff(struct efx_nic *efx) | 84 | static void sfe4001_poweroff(struct efx_nic *efx) |
112 | { | 85 | { |
@@ -119,7 +92,7 @@ static void sfe4001_poweroff(struct efx_nic *efx) | |||
119 | i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff); | 92 | i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff); |
120 | 93 | ||
121 | /* Clear any over-temperature alert */ | 94 | /* Clear any over-temperature alert */ |
122 | i2c_smbus_read_byte_data(hwmon_client, RSL); | 95 | i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL); |
123 | } | 96 | } |
124 | 97 | ||
125 | static int sfe4001_poweron(struct efx_nic *efx) | 98 | static int sfe4001_poweron(struct efx_nic *efx) |
@@ -131,7 +104,7 @@ static int sfe4001_poweron(struct efx_nic *efx) | |||
131 | u8 out; | 104 | u8 out; |
132 | 105 | ||
133 | /* Clear any previous over-temperature alert */ | 106 | /* Clear any previous over-temperature alert */ |
134 | rc = i2c_smbus_read_byte_data(hwmon_client, RSL); | 107 | rc = i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL); |
135 | if (rc < 0) | 108 | if (rc < 0) |
136 | return rc; | 109 | return rc; |
137 | 110 | ||
@@ -209,10 +182,32 @@ fail_on: | |||
209 | return rc; | 182 | return rc; |
210 | } | 183 | } |
211 | 184 | ||
212 | /* On SFE4001 rev A2 and later, we can control the FLASH_CFG_1 pin | 185 | static int sfn4111t_reset(struct efx_nic *efx) |
213 | * using the 3V3X output of the IO-expander. Allow the user to set | 186 | { |
214 | * this when the device is stopped, and keep it stopped then. | 187 | efx_oword_t reg; |
215 | */ | 188 | |
189 | /* GPIO 3 and the GPIO register are shared with I2C, so block that */ | ||
190 | mutex_lock(&efx->i2c_adap.bus_lock); | ||
191 | |||
192 | /* Pull RST_N (GPIO 2) low then let it up again, setting the | ||
193 | * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the | ||
194 | * output enables; the output levels should always be 0 (low) | ||
195 | * and we rely on external pull-ups. */ | ||
196 | falcon_read(efx, ®, GPIO_CTL_REG_KER); | ||
197 | EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true); | ||
198 | falcon_write(efx, ®, GPIO_CTL_REG_KER); | ||
199 | msleep(1000); | ||
200 | EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, false); | ||
201 | EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, | ||
202 | !!(efx->phy_mode & PHY_MODE_SPECIAL)); | ||
203 | falcon_write(efx, ®, GPIO_CTL_REG_KER); | ||
204 | msleep(1); | ||
205 | |||
206 | mutex_unlock(&efx->i2c_adap.bus_lock); | ||
207 | |||
208 | ssleep(1); | ||
209 | return 0; | ||
210 | } | ||
216 | 211 | ||
217 | static ssize_t show_phy_flash_cfg(struct device *dev, | 212 | static ssize_t show_phy_flash_cfg(struct device *dev, |
218 | struct device_attribute *attr, char *buf) | 213 | struct device_attribute *attr, char *buf) |
@@ -240,9 +235,18 @@ static ssize_t set_phy_flash_cfg(struct device *dev, | |||
240 | } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) { | 235 | } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) { |
241 | err = -EBUSY; | 236 | err = -EBUSY; |
242 | } else { | 237 | } else { |
238 | /* Reset the PHY, reconfigure the MAC and enable/disable | ||
239 | * MAC stats accordingly. */ | ||
243 | efx->phy_mode = new_mode; | 240 | efx->phy_mode = new_mode; |
244 | err = sfe4001_poweron(efx); | 241 | if (new_mode & PHY_MODE_SPECIAL) |
242 | efx_stats_disable(efx); | ||
243 | if (efx->board_info.type == EFX_BOARD_SFE4001) | ||
244 | err = sfe4001_poweron(efx); | ||
245 | else | ||
246 | err = sfn4111t_reset(efx); | ||
245 | efx_reconfigure_port(efx); | 247 | efx_reconfigure_port(efx); |
248 | if (!(new_mode & PHY_MODE_SPECIAL)) | ||
249 | efx_stats_enable(efx); | ||
246 | } | 250 | } |
247 | rtnl_unlock(); | 251 | rtnl_unlock(); |
248 | 252 | ||
@@ -261,35 +265,62 @@ static void sfe4001_fini(struct efx_nic *efx) | |||
261 | i2c_unregister_device(efx->board_info.hwmon_client); | 265 | i2c_unregister_device(efx->board_info.hwmon_client); |
262 | } | 266 | } |
263 | 267 | ||
268 | static int sfe4001_check_hw(struct efx_nic *efx) | ||
269 | { | ||
270 | s32 status; | ||
271 | |||
272 | /* If XAUI link is up then do not monitor */ | ||
273 | if (EFX_WORKAROUND_7884(efx) && efx->mac_up) | ||
274 | return 0; | ||
275 | |||
276 | /* Check the powered status of the PHY. Lack of power implies that | ||
277 | * the MAX6647 has shut down power to it, probably due to a temp. | ||
278 | * alarm. Reading the power status rather than the MAX6647 status | ||
279 | * directly because the later is read-to-clear and would thus | ||
280 | * start to power up the PHY again when polled, causing us to blip | ||
281 | * the power undesirably. | ||
282 | * We know we can read from the IO expander because we did | ||
283 | * it during power-on. Assume failure now is bad news. */ | ||
284 | status = i2c_smbus_read_byte_data(efx->board_info.ioexp_client, P1_IN); | ||
285 | if (status >= 0 && | ||
286 | (status & ((1 << P1_AFE_PWD_LBN) | (1 << P1_DSP_PWD25_LBN))) != 0) | ||
287 | return 0; | ||
288 | |||
289 | /* Use board power control, not PHY power control */ | ||
290 | sfe4001_poweroff(efx); | ||
291 | efx->phy_mode = PHY_MODE_OFF; | ||
292 | |||
293 | return (status < 0) ? -EIO : -ERANGE; | ||
294 | } | ||
295 | |||
296 | static struct i2c_board_info sfe4001_hwmon_info = { | ||
297 | I2C_BOARD_INFO("max6647", 0x4e), | ||
298 | .irq = -1, | ||
299 | }; | ||
300 | |||
264 | /* This board uses an I2C expander to provider power to the PHY, which needs to | 301 | /* This board uses an I2C expander to provider power to the PHY, which needs to |
265 | * be turned on before the PHY can be used. | 302 | * be turned on before the PHY can be used. |
266 | * Context: Process context, rtnl lock held | 303 | * Context: Process context, rtnl lock held |
267 | */ | 304 | */ |
268 | int sfe4001_init(struct efx_nic *efx) | 305 | int sfe4001_init(struct efx_nic *efx) |
269 | { | 306 | { |
270 | struct i2c_client *hwmon_client; | ||
271 | int rc; | 307 | int rc; |
272 | 308 | ||
273 | hwmon_client = i2c_new_dummy(&efx->i2c_adap, MAX6647); | 309 | #if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE) |
274 | if (!hwmon_client) | 310 | efx->board_info.hwmon_client = |
311 | i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info); | ||
312 | #else | ||
313 | efx->board_info.hwmon_client = | ||
314 | i2c_new_dummy(&efx->i2c_adap, sfe4001_hwmon_info.addr); | ||
315 | #endif | ||
316 | if (!efx->board_info.hwmon_client) | ||
275 | return -EIO; | 317 | return -EIO; |
276 | efx->board_info.hwmon_client = hwmon_client; | ||
277 | 318 | ||
278 | /* Set DSP over-temperature alert threshold */ | 319 | /* Raise board/PHY high limit from 85 to 90 degrees Celsius */ |
279 | EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature); | 320 | rc = i2c_smbus_write_byte_data(efx->board_info.hwmon_client, |
280 | rc = i2c_smbus_write_byte_data(hwmon_client, WLHO, | 321 | MAX664X_REG_WLHO, 90); |
281 | xgphy_max_temperature); | ||
282 | if (rc) | 322 | if (rc) |
283 | goto fail_ioexp; | 323 | goto fail_hwmon; |
284 | |||
285 | /* Read it back and verify */ | ||
286 | rc = i2c_smbus_read_byte_data(hwmon_client, RLHN); | ||
287 | if (rc < 0) | ||
288 | goto fail_ioexp; | ||
289 | if (rc != xgphy_max_temperature) { | ||
290 | rc = -EFAULT; | ||
291 | goto fail_ioexp; | ||
292 | } | ||
293 | 324 | ||
294 | efx->board_info.ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539); | 325 | efx->board_info.ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539); |
295 | if (!efx->board_info.ioexp_client) { | 326 | if (!efx->board_info.ioexp_client) { |
@@ -301,8 +332,14 @@ int sfe4001_init(struct efx_nic *efx) | |||
301 | * blink code. */ | 332 | * blink code. */ |
302 | efx->board_info.blink = tenxpress_phy_blink; | 333 | efx->board_info.blink = tenxpress_phy_blink; |
303 | 334 | ||
335 | efx->board_info.monitor = sfe4001_check_hw; | ||
304 | efx->board_info.fini = sfe4001_fini; | 336 | efx->board_info.fini = sfe4001_fini; |
305 | 337 | ||
338 | if (efx->phy_mode & PHY_MODE_SPECIAL) { | ||
339 | /* PHY won't generate a 156.25 MHz clock and MAC stats fetch | ||
340 | * will fail. */ | ||
341 | efx_stats_disable(efx); | ||
342 | } | ||
306 | rc = sfe4001_poweron(efx); | 343 | rc = sfe4001_poweron(efx); |
307 | if (rc) | 344 | if (rc) |
308 | goto fail_ioexp; | 345 | goto fail_ioexp; |
@@ -319,6 +356,74 @@ fail_on: | |||
319 | fail_ioexp: | 356 | fail_ioexp: |
320 | i2c_unregister_device(efx->board_info.ioexp_client); | 357 | i2c_unregister_device(efx->board_info.ioexp_client); |
321 | fail_hwmon: | 358 | fail_hwmon: |
322 | i2c_unregister_device(hwmon_client); | 359 | i2c_unregister_device(efx->board_info.hwmon_client); |
360 | return rc; | ||
361 | } | ||
362 | |||
363 | static int sfn4111t_check_hw(struct efx_nic *efx) | ||
364 | { | ||
365 | s32 status; | ||
366 | |||
367 | /* If XAUI link is up then do not monitor */ | ||
368 | if (EFX_WORKAROUND_7884(efx) && efx->mac_up) | ||
369 | return 0; | ||
370 | |||
371 | /* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */ | ||
372 | status = i2c_smbus_read_byte_data(efx->board_info.hwmon_client, | ||
373 | MAX664X_REG_RSL); | ||
374 | if (status < 0) | ||
375 | return -EIO; | ||
376 | if (status & 0x57) | ||
377 | return -ERANGE; | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static void sfn4111t_fini(struct efx_nic *efx) | ||
382 | { | ||
383 | EFX_INFO(efx, "%s\n", __func__); | ||
384 | |||
385 | device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); | ||
386 | i2c_unregister_device(efx->board_info.hwmon_client); | ||
387 | } | ||
388 | |||
389 | static struct i2c_board_info sfn4111t_a0_hwmon_info = { | ||
390 | I2C_BOARD_INFO("max6647", 0x4e), | ||
391 | .irq = -1, | ||
392 | }; | ||
393 | |||
394 | static struct i2c_board_info sfn4111t_r5_hwmon_info = { | ||
395 | I2C_BOARD_INFO("max6646", 0x4d), | ||
396 | .irq = -1, | ||
397 | }; | ||
398 | |||
399 | int sfn4111t_init(struct efx_nic *efx) | ||
400 | { | ||
401 | int rc; | ||
402 | |||
403 | efx->board_info.hwmon_client = | ||
404 | i2c_new_device(&efx->i2c_adap, | ||
405 | (efx->board_info.minor < 5) ? | ||
406 | &sfn4111t_a0_hwmon_info : | ||
407 | &sfn4111t_r5_hwmon_info); | ||
408 | if (!efx->board_info.hwmon_client) | ||
409 | return -EIO; | ||
410 | |||
411 | efx->board_info.blink = tenxpress_phy_blink; | ||
412 | efx->board_info.monitor = sfn4111t_check_hw; | ||
413 | efx->board_info.fini = sfn4111t_fini; | ||
414 | |||
415 | rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); | ||
416 | if (rc) | ||
417 | goto fail_hwmon; | ||
418 | |||
419 | if (efx->phy_mode & PHY_MODE_SPECIAL) { | ||
420 | efx_stats_disable(efx); | ||
421 | sfn4111t_reset(efx); | ||
422 | } | ||
423 | |||
424 | return 0; | ||
425 | |||
426 | fail_hwmon: | ||
427 | i2c_unregister_device(efx->board_info.hwmon_client); | ||
323 | return rc; | 428 | return rc; |
324 | } | 429 | } |
diff --git a/drivers/net/sfc/spi.h b/drivers/net/sfc/spi.h index feef61942377..1b1ceb411671 100644 --- a/drivers/net/sfc/spi.h +++ b/drivers/net/sfc/spi.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define SPI_WRDI 0x04 /* Reset write enable latch */ | 25 | #define SPI_WRDI 0x04 /* Reset write enable latch */ |
26 | #define SPI_RDSR 0x05 /* Read status register */ | 26 | #define SPI_RDSR 0x05 /* Read status register */ |
27 | #define SPI_WREN 0x06 /* Set write enable latch */ | 27 | #define SPI_WREN 0x06 /* Set write enable latch */ |
28 | #define SPI_SST_EWSR 0x50 /* SST: Enable write to status register */ | ||
28 | 29 | ||
29 | #define SPI_STATUS_WPEN 0x80 /* Write-protect pin enabled */ | 30 | #define SPI_STATUS_WPEN 0x80 /* Write-protect pin enabled */ |
30 | #define SPI_STATUS_BP2 0x10 /* Block protection bit 2 */ | 31 | #define SPI_STATUS_BP2 0x10 /* Block protection bit 2 */ |
@@ -36,6 +37,7 @@ | |||
36 | /** | 37 | /** |
37 | * struct efx_spi_device - an Efx SPI (Serial Peripheral Interface) device | 38 | * struct efx_spi_device - an Efx SPI (Serial Peripheral Interface) device |
38 | * @efx: The Efx controller that owns this device | 39 | * @efx: The Efx controller that owns this device |
40 | * @mtd: MTD state | ||
39 | * @device_id: Controller's id for the device | 41 | * @device_id: Controller's id for the device |
40 | * @size: Size (in bytes) | 42 | * @size: Size (in bytes) |
41 | * @addr_len: Number of address bytes in read/write commands | 43 | * @addr_len: Number of address bytes in read/write commands |
@@ -44,23 +46,51 @@ | |||
44 | * use bit 3 of the command byte as address bit A8, rather | 46 | * use bit 3 of the command byte as address bit A8, rather |
45 | * than having a two-byte address. If this flag is set, then | 47 | * than having a two-byte address. If this flag is set, then |
46 | * commands should be munged in this way. | 48 | * commands should be munged in this way. |
49 | * @erase_command: Erase command (or 0 if sector erase not needed). | ||
50 | * @erase_size: Erase sector size (in bytes) | ||
51 | * Erase commands affect sectors with this size and alignment. | ||
52 | * This must be a power of two. | ||
47 | * @block_size: Write block size (in bytes). | 53 | * @block_size: Write block size (in bytes). |
48 | * Write commands are limited to blocks with this size and alignment. | 54 | * Write commands are limited to blocks with this size and alignment. |
49 | * @read: Read function for the device | ||
50 | * @write: Write function for the device | ||
51 | */ | 55 | */ |
52 | struct efx_spi_device { | 56 | struct efx_spi_device { |
53 | struct efx_nic *efx; | 57 | struct efx_nic *efx; |
58 | #ifdef CONFIG_SFC_MTD | ||
59 | void *mtd; | ||
60 | #endif | ||
54 | int device_id; | 61 | int device_id; |
55 | unsigned int size; | 62 | unsigned int size; |
56 | unsigned int addr_len; | 63 | unsigned int addr_len; |
57 | unsigned int munge_address:1; | 64 | unsigned int munge_address:1; |
65 | u8 erase_command; | ||
66 | unsigned int erase_size; | ||
58 | unsigned int block_size; | 67 | unsigned int block_size; |
59 | }; | 68 | }; |
60 | 69 | ||
70 | int falcon_spi_cmd(const struct efx_spi_device *spi, unsigned int command, | ||
71 | int address, const void* in, void *out, size_t len); | ||
72 | int falcon_spi_wait_write(const struct efx_spi_device *spi); | ||
61 | int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, | 73 | int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, |
62 | size_t len, size_t *retlen, u8 *buffer); | 74 | size_t len, size_t *retlen, u8 *buffer); |
63 | int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, | 75 | int falcon_spi_write(const struct efx_spi_device *spi, loff_t start, |
64 | size_t len, size_t *retlen, const u8 *buffer); | 76 | size_t len, size_t *retlen, const u8 *buffer); |
65 | 77 | ||
78 | /* | ||
79 | * SFC4000 flash is partitioned into: | ||
80 | * 0-0x400 chip and board config (see falcon_hwdefs.h) | ||
81 | * 0x400-0x8000 unused (or may contain VPD if EEPROM not present) | ||
82 | * 0x8000-end boot code (mapped to PCI expansion ROM) | ||
83 | * SFC4000 small EEPROM (size < 0x400) is used for VPD only. | ||
84 | * SFC4000 large EEPROM (size >= 0x400) is partitioned into: | ||
85 | * 0-0x400 chip and board config | ||
86 | * configurable VPD | ||
87 | * 0x800-0x1800 boot config | ||
88 | * Aside from the chip and board config, all of these are optional and may | ||
89 | * be absent or truncated depending on the devices used. | ||
90 | */ | ||
91 | #define FALCON_NVCONFIG_END 0x400U | ||
92 | #define FALCON_FLASH_BOOTCODE_START 0x8000U | ||
93 | #define EFX_EEPROM_BOOTCONFIG_START 0x800U | ||
94 | #define EFX_EEPROM_BOOTCONFIG_END 0x1800U | ||
95 | |||
66 | #endif /* EFX_SPI_H */ | 96 | #endif /* EFX_SPI_H */ |
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index d507c93d666e..f0efd246962c 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /**************************************************************************** | 1 | /**************************************************************************** |
2 | * Driver for Solarflare 802.3an compliant PHY | 2 | * Driver for Solarflare Solarstorm network controllers and boards |
3 | * Copyright 2007 Solarflare Communications Inc. | 3 | * Copyright 2007-2008 Solarflare Communications Inc. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 as published | 6 | * under the terms of the GNU General Public License version 2 as published |
@@ -10,45 +10,78 @@ | |||
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <linux/seq_file.h> | 11 | #include <linux/seq_file.h> |
12 | #include "efx.h" | 12 | #include "efx.h" |
13 | #include "gmii.h" | ||
14 | #include "mdio_10g.h" | 13 | #include "mdio_10g.h" |
15 | #include "falcon.h" | 14 | #include "falcon.h" |
16 | #include "phy.h" | 15 | #include "phy.h" |
17 | #include "falcon_hwdefs.h" | 16 | #include "falcon_hwdefs.h" |
18 | #include "boards.h" | 17 | #include "boards.h" |
19 | #include "mac.h" | 18 | #include "workarounds.h" |
19 | #include "selftest.h" | ||
20 | 20 | ||
21 | /* We expect these MMDs to be in the package */ | 21 | /* We expect these MMDs to be in the package. SFT9001 also has a |
22 | /* AN not here as mdio_check_mmds() requires STAT2 support */ | 22 | * clause 22 extension MMD, but since it doesn't have all the generic |
23 | #define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS0_PMAPMD | \ | 23 | * MMD registers it is pointless to include it here. |
24 | MDIO_MMDREG_DEVS0_PCS | \ | 24 | */ |
25 | MDIO_MMDREG_DEVS0_PHYXS) | 25 | #define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PMAPMD | \ |
26 | 26 | MDIO_MMDREG_DEVS_PCS | \ | |
27 | #define TENXPRESS_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \ | 27 | MDIO_MMDREG_DEVS_PHYXS | \ |
28 | (1 << LOOPBACK_PCS) | \ | 28 | MDIO_MMDREG_DEVS_AN) |
29 | (1 << LOOPBACK_PMAPMD) | \ | 29 | |
30 | (1 << LOOPBACK_NETWORK)) | 30 | #define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \ |
31 | (1 << LOOPBACK_PCS) | \ | ||
32 | (1 << LOOPBACK_PMAPMD) | \ | ||
33 | (1 << LOOPBACK_NETWORK)) | ||
34 | |||
35 | #define SFT9001_LOOPBACKS ((1 << LOOPBACK_GPHY) | \ | ||
36 | (1 << LOOPBACK_PHYXS) | \ | ||
37 | (1 << LOOPBACK_PCS) | \ | ||
38 | (1 << LOOPBACK_PMAPMD) | \ | ||
39 | (1 << LOOPBACK_NETWORK)) | ||
31 | 40 | ||
32 | /* We complain if we fail to see the link partner as 10G capable this many | 41 | /* We complain if we fail to see the link partner as 10G capable this many |
33 | * times in a row (must be > 1 as sampling the autoneg. registers is racy) | 42 | * times in a row (must be > 1 as sampling the autoneg. registers is racy) |
34 | */ | 43 | */ |
35 | #define MAX_BAD_LP_TRIES (5) | 44 | #define MAX_BAD_LP_TRIES (5) |
36 | 45 | ||
46 | /* LASI Control */ | ||
47 | #define PMA_PMD_LASI_CTRL 36866 | ||
48 | #define PMA_PMD_LASI_STATUS 36869 | ||
49 | #define PMA_PMD_LS_ALARM_LBN 0 | ||
50 | #define PMA_PMD_LS_ALARM_WIDTH 1 | ||
51 | #define PMA_PMD_TX_ALARM_LBN 1 | ||
52 | #define PMA_PMD_TX_ALARM_WIDTH 1 | ||
53 | #define PMA_PMD_RX_ALARM_LBN 2 | ||
54 | #define PMA_PMD_RX_ALARM_WIDTH 1 | ||
55 | #define PMA_PMD_AN_ALARM_LBN 3 | ||
56 | #define PMA_PMD_AN_ALARM_WIDTH 1 | ||
57 | |||
37 | /* Extended control register */ | 58 | /* Extended control register */ |
38 | #define PMA_PMD_XCONTROL_REG 0xc000 | 59 | #define PMA_PMD_XCONTROL_REG 49152 |
39 | #define PMA_PMD_LNPGA_POWERDOWN_LBN 8 | 60 | #define PMA_PMD_EXT_GMII_EN_LBN 1 |
40 | #define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1 | 61 | #define PMA_PMD_EXT_GMII_EN_WIDTH 1 |
62 | #define PMA_PMD_EXT_CLK_OUT_LBN 2 | ||
63 | #define PMA_PMD_EXT_CLK_OUT_WIDTH 1 | ||
64 | #define PMA_PMD_LNPGA_POWERDOWN_LBN 8 /* SFX7101 only */ | ||
65 | #define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1 | ||
66 | #define PMA_PMD_EXT_CLK312_LBN 8 /* SFT9001 only */ | ||
67 | #define PMA_PMD_EXT_CLK312_WIDTH 1 | ||
68 | #define PMA_PMD_EXT_LPOWER_LBN 12 | ||
69 | #define PMA_PMD_EXT_LPOWER_WIDTH 1 | ||
70 | #define PMA_PMD_EXT_ROBUST_LBN 14 | ||
71 | #define PMA_PMD_EXT_ROBUST_WIDTH 1 | ||
72 | #define PMA_PMD_EXT_SSR_LBN 15 | ||
73 | #define PMA_PMD_EXT_SSR_WIDTH 1 | ||
41 | 74 | ||
42 | /* extended status register */ | 75 | /* extended status register */ |
43 | #define PMA_PMD_XSTATUS_REG 0xc001 | 76 | #define PMA_PMD_XSTATUS_REG 49153 |
44 | #define PMA_PMD_XSTAT_FLP_LBN (12) | 77 | #define PMA_PMD_XSTAT_FLP_LBN (12) |
45 | 78 | ||
46 | /* LED control register */ | 79 | /* LED control register */ |
47 | #define PMA_PMD_LED_CTRL_REG (0xc007) | 80 | #define PMA_PMD_LED_CTRL_REG 49159 |
48 | #define PMA_PMA_LED_ACTIVITY_LBN (3) | 81 | #define PMA_PMA_LED_ACTIVITY_LBN (3) |
49 | 82 | ||
50 | /* LED function override register */ | 83 | /* LED function override register */ |
51 | #define PMA_PMD_LED_OVERR_REG (0xc009) | 84 | #define PMA_PMD_LED_OVERR_REG 49161 |
52 | /* Bit positions for different LEDs (there are more but not wired on SFE4001)*/ | 85 | /* Bit positions for different LEDs (there are more but not wired on SFE4001)*/ |
53 | #define PMA_PMD_LED_LINK_LBN (0) | 86 | #define PMA_PMD_LED_LINK_LBN (0) |
54 | #define PMA_PMD_LED_SPEED_LBN (2) | 87 | #define PMA_PMD_LED_SPEED_LBN (2) |
@@ -59,64 +92,143 @@ | |||
59 | #define PMA_PMD_LED_ON (1) | 92 | #define PMA_PMD_LED_ON (1) |
60 | #define PMA_PMD_LED_OFF (2) | 93 | #define PMA_PMD_LED_OFF (2) |
61 | #define PMA_PMD_LED_FLASH (3) | 94 | #define PMA_PMD_LED_FLASH (3) |
95 | #define PMA_PMD_LED_MASK 3 | ||
62 | /* All LEDs under hardware control */ | 96 | /* All LEDs under hardware control */ |
63 | #define PMA_PMD_LED_FULL_AUTO (0) | 97 | #define PMA_PMD_LED_FULL_AUTO (0) |
64 | /* Green and Amber under hardware control, Red off */ | 98 | /* Green and Amber under hardware control, Red off */ |
65 | #define PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) | 99 | #define PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) |
66 | 100 | ||
67 | 101 | #define PMA_PMD_SPEED_ENABLE_REG 49192 | |
68 | /* Special Software reset register */ | 102 | #define PMA_PMD_100TX_ADV_LBN 1 |
69 | #define PMA_PMD_EXT_CTRL_REG 49152 | 103 | #define PMA_PMD_100TX_ADV_WIDTH 1 |
70 | #define PMA_PMD_EXT_SSR_LBN 15 | 104 | #define PMA_PMD_1000T_ADV_LBN 2 |
71 | 105 | #define PMA_PMD_1000T_ADV_WIDTH 1 | |
72 | /* Misc register defines */ | 106 | #define PMA_PMD_10000T_ADV_LBN 3 |
73 | #define PCS_CLOCK_CTRL_REG 0xd801 | 107 | #define PMA_PMD_10000T_ADV_WIDTH 1 |
108 | #define PMA_PMD_SPEED_LBN 4 | ||
109 | #define PMA_PMD_SPEED_WIDTH 4 | ||
110 | |||
111 | /* Cable diagnostics - SFT9001 only */ | ||
112 | #define PMA_PMD_CDIAG_CTRL_REG 49213 | ||
113 | #define CDIAG_CTRL_IMMED_LBN 15 | ||
114 | #define CDIAG_CTRL_BRK_LINK_LBN 12 | ||
115 | #define CDIAG_CTRL_IN_PROG_LBN 11 | ||
116 | #define CDIAG_CTRL_LEN_UNIT_LBN 10 | ||
117 | #define CDIAG_CTRL_LEN_METRES 1 | ||
118 | #define PMA_PMD_CDIAG_RES_REG 49174 | ||
119 | #define CDIAG_RES_A_LBN 12 | ||
120 | #define CDIAG_RES_B_LBN 8 | ||
121 | #define CDIAG_RES_C_LBN 4 | ||
122 | #define CDIAG_RES_D_LBN 0 | ||
123 | #define CDIAG_RES_WIDTH 4 | ||
124 | #define CDIAG_RES_OPEN 2 | ||
125 | #define CDIAG_RES_OK 1 | ||
126 | #define CDIAG_RES_INVALID 0 | ||
127 | /* Set of 4 registers for pairs A-D */ | ||
128 | #define PMA_PMD_CDIAG_LEN_REG 49175 | ||
129 | |||
130 | /* Serdes control registers - SFT9001 only */ | ||
131 | #define PMA_PMD_CSERDES_CTRL_REG 64258 | ||
132 | /* Set the 156.25 MHz output to 312.5 MHz to drive Falcon's XMAC */ | ||
133 | #define PMA_PMD_CSERDES_DEFAULT 0x000f | ||
134 | |||
135 | /* Misc register defines - SFX7101 only */ | ||
136 | #define PCS_CLOCK_CTRL_REG 55297 | ||
74 | #define PLL312_RST_N_LBN 2 | 137 | #define PLL312_RST_N_LBN 2 |
75 | 138 | ||
76 | #define PCS_SOFT_RST2_REG 0xd806 | 139 | #define PCS_SOFT_RST2_REG 55302 |
77 | #define SERDES_RST_N_LBN 13 | 140 | #define SERDES_RST_N_LBN 13 |
78 | #define XGXS_RST_N_LBN 12 | 141 | #define XGXS_RST_N_LBN 12 |
79 | 142 | ||
80 | #define PCS_TEST_SELECT_REG 0xd807 /* PRM 10.5.8 */ | 143 | #define PCS_TEST_SELECT_REG 55303 /* PRM 10.5.8 */ |
81 | #define CLK312_EN_LBN 3 | 144 | #define CLK312_EN_LBN 3 |
82 | 145 | ||
83 | /* PHYXS registers */ | 146 | /* PHYXS registers */ |
147 | #define PHYXS_XCONTROL_REG 49152 | ||
148 | #define PHYXS_RESET_LBN 15 | ||
149 | #define PHYXS_RESET_WIDTH 1 | ||
150 | |||
84 | #define PHYXS_TEST1 (49162) | 151 | #define PHYXS_TEST1 (49162) |
85 | #define LOOPBACK_NEAR_LBN (8) | 152 | #define LOOPBACK_NEAR_LBN (8) |
86 | #define LOOPBACK_NEAR_WIDTH (1) | 153 | #define LOOPBACK_NEAR_WIDTH (1) |
87 | 154 | ||
155 | #define PCS_10GBASET_STAT1 32 | ||
156 | #define PCS_10GBASET_BLKLK_LBN 0 | ||
157 | #define PCS_10GBASET_BLKLK_WIDTH 1 | ||
158 | |||
88 | /* Boot status register */ | 159 | /* Boot status register */ |
89 | #define PCS_BOOT_STATUS_REG (0xd000) | 160 | #define PCS_BOOT_STATUS_REG 53248 |
90 | #define PCS_BOOT_FATAL_ERR_LBN (0) | 161 | #define PCS_BOOT_FATAL_ERR_LBN (0) |
91 | #define PCS_BOOT_PROGRESS_LBN (1) | 162 | #define PCS_BOOT_PROGRESS_LBN (1) |
92 | #define PCS_BOOT_PROGRESS_WIDTH (2) | 163 | #define PCS_BOOT_PROGRESS_WIDTH (2) |
93 | #define PCS_BOOT_COMPLETE_LBN (3) | 164 | #define PCS_BOOT_COMPLETE_LBN (3) |
165 | |||
94 | #define PCS_BOOT_MAX_DELAY (100) | 166 | #define PCS_BOOT_MAX_DELAY (100) |
95 | #define PCS_BOOT_POLL_DELAY (10) | 167 | #define PCS_BOOT_POLL_DELAY (10) |
96 | 168 | ||
169 | /* 100M/1G PHY registers */ | ||
170 | #define GPHY_XCONTROL_REG 49152 | ||
171 | #define GPHY_ISOLATE_LBN 10 | ||
172 | #define GPHY_ISOLATE_WIDTH 1 | ||
173 | #define GPHY_DUPLEX_LBN 8 | ||
174 | #define GPHY_DUPLEX_WIDTH 1 | ||
175 | #define GPHY_LOOPBACK_NEAR_LBN 14 | ||
176 | #define GPHY_LOOPBACK_NEAR_WIDTH 1 | ||
177 | |||
178 | #define C22EXT_STATUS_REG 49153 | ||
179 | #define C22EXT_STATUS_LINK_LBN 2 | ||
180 | #define C22EXT_STATUS_LINK_WIDTH 1 | ||
181 | |||
182 | #define C22EXT_MSTSLV_CTRL 49161 | ||
183 | #define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8 | ||
184 | #define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9 | ||
185 | |||
186 | #define C22EXT_MSTSLV_STATUS 49162 | ||
187 | #define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10 | ||
188 | #define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11 | ||
189 | |||
97 | /* Time to wait between powering down the LNPGA and turning off the power | 190 | /* Time to wait between powering down the LNPGA and turning off the power |
98 | * rails */ | 191 | * rails */ |
99 | #define LNPGA_PDOWN_WAIT (HZ / 5) | 192 | #define LNPGA_PDOWN_WAIT (HZ / 5) |
100 | 193 | ||
101 | static int crc_error_reset_threshold = 100; | ||
102 | module_param(crc_error_reset_threshold, int, 0644); | ||
103 | MODULE_PARM_DESC(crc_error_reset_threshold, | ||
104 | "Max number of CRC errors before XAUI reset"); | ||
105 | |||
106 | struct tenxpress_phy_data { | 194 | struct tenxpress_phy_data { |
107 | enum efx_loopback_mode loopback_mode; | 195 | enum efx_loopback_mode loopback_mode; |
108 | atomic_t bad_crc_count; | ||
109 | enum efx_phy_mode phy_mode; | 196 | enum efx_phy_mode phy_mode; |
110 | int bad_lp_tries; | 197 | int bad_lp_tries; |
111 | }; | 198 | }; |
112 | 199 | ||
113 | void tenxpress_crc_err(struct efx_nic *efx) | 200 | static ssize_t show_phy_short_reach(struct device *dev, |
201 | struct device_attribute *attr, char *buf) | ||
114 | { | 202 | { |
115 | struct tenxpress_phy_data *phy_data = efx->phy_data; | 203 | struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); |
116 | if (phy_data != NULL) | 204 | int reg; |
117 | atomic_inc(&phy_data->bad_crc_count); | 205 | |
206 | reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, | ||
207 | MDIO_PMAPMD_10GBT_TXPWR); | ||
208 | return sprintf(buf, "%d\n", | ||
209 | !!(reg & (1 << MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN))); | ||
118 | } | 210 | } |
119 | 211 | ||
212 | static ssize_t set_phy_short_reach(struct device *dev, | ||
213 | struct device_attribute *attr, | ||
214 | const char *buf, size_t count) | ||
215 | { | ||
216 | struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); | ||
217 | |||
218 | rtnl_lock(); | ||
219 | mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, | ||
220 | MDIO_PMAPMD_10GBT_TXPWR, | ||
221 | MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN, | ||
222 | count != 0 && *buf != '0'); | ||
223 | efx_reconfigure_port(efx); | ||
224 | rtnl_unlock(); | ||
225 | |||
226 | return count; | ||
227 | } | ||
228 | |||
229 | static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach, | ||
230 | set_phy_short_reach); | ||
231 | |||
120 | /* Check that the C166 has booted successfully */ | 232 | /* Check that the C166 has booted successfully */ |
121 | static int tenxpress_phy_check(struct efx_nic *efx) | 233 | static int tenxpress_phy_check(struct efx_nic *efx) |
122 | { | 234 | { |
@@ -148,27 +260,44 @@ static int tenxpress_phy_check(struct efx_nic *efx) | |||
148 | 260 | ||
149 | static int tenxpress_init(struct efx_nic *efx) | 261 | static int tenxpress_init(struct efx_nic *efx) |
150 | { | 262 | { |
151 | int rc, reg; | 263 | int phy_id = efx->mii.phy_id; |
264 | int reg; | ||
265 | int rc; | ||
152 | 266 | ||
153 | /* Turn on the clock */ | 267 | if (efx->phy_type == PHY_TYPE_SFX7101) { |
154 | reg = (1 << CLK312_EN_LBN); | 268 | /* Enable 312.5 MHz clock */ |
155 | mdio_clause45_write(efx, efx->mii.phy_id, | 269 | mdio_clause45_write(efx, phy_id, |
156 | MDIO_MMD_PCS, PCS_TEST_SELECT_REG, reg); | 270 | MDIO_MMD_PCS, PCS_TEST_SELECT_REG, |
271 | 1 << CLK312_EN_LBN); | ||
272 | } else { | ||
273 | /* Enable 312.5 MHz clock and GMII */ | ||
274 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
275 | PMA_PMD_XCONTROL_REG); | ||
276 | reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) | | ||
277 | (1 << PMA_PMD_EXT_CLK_OUT_LBN) | | ||
278 | (1 << PMA_PMD_EXT_CLK312_LBN) | | ||
279 | (1 << PMA_PMD_EXT_ROBUST_LBN)); | ||
280 | |||
281 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | ||
282 | PMA_PMD_XCONTROL_REG, reg); | ||
283 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, | ||
284 | GPHY_XCONTROL_REG, GPHY_ISOLATE_LBN, | ||
285 | false); | ||
286 | } | ||
157 | 287 | ||
158 | rc = tenxpress_phy_check(efx); | 288 | rc = tenxpress_phy_check(efx); |
159 | if (rc < 0) | 289 | if (rc < 0) |
160 | return rc; | 290 | return rc; |
161 | 291 | ||
162 | /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */ | 292 | /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */ |
163 | reg = mdio_clause45_read(efx, efx->mii.phy_id, | 293 | if (efx->phy_type == PHY_TYPE_SFX7101) { |
164 | MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG); | 294 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD, |
165 | reg |= (1 << PMA_PMA_LED_ACTIVITY_LBN); | 295 | PMA_PMD_LED_CTRL_REG, |
166 | mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, | 296 | PMA_PMA_LED_ACTIVITY_LBN, |
167 | PMA_PMD_LED_CTRL_REG, reg); | 297 | true); |
168 | 298 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | |
169 | reg = PMA_PMD_LED_DEFAULT; | 299 | PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT); |
170 | mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, | 300 | } |
171 | PMA_PMD_LED_OVERR_REG, reg); | ||
172 | 301 | ||
173 | return rc; | 302 | return rc; |
174 | } | 303 | } |
@@ -184,22 +313,44 @@ static int tenxpress_phy_init(struct efx_nic *efx) | |||
184 | efx->phy_data = phy_data; | 313 | efx->phy_data = phy_data; |
185 | phy_data->phy_mode = efx->phy_mode; | 314 | phy_data->phy_mode = efx->phy_mode; |
186 | 315 | ||
187 | rc = mdio_clause45_wait_reset_mmds(efx, | 316 | if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { |
188 | TENXPRESS_REQUIRED_DEVS); | 317 | if (efx->phy_type == PHY_TYPE_SFT9001A) { |
189 | if (rc < 0) | 318 | int reg; |
190 | goto fail; | 319 | reg = mdio_clause45_read(efx, efx->mii.phy_id, |
320 | MDIO_MMD_PMAPMD, | ||
321 | PMA_PMD_XCONTROL_REG); | ||
322 | reg |= (1 << PMA_PMD_EXT_SSR_LBN); | ||
323 | mdio_clause45_write(efx, efx->mii.phy_id, | ||
324 | MDIO_MMD_PMAPMD, | ||
325 | PMA_PMD_XCONTROL_REG, reg); | ||
326 | mdelay(200); | ||
327 | } | ||
191 | 328 | ||
192 | rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); | 329 | rc = mdio_clause45_wait_reset_mmds(efx, |
193 | if (rc < 0) | 330 | TENXPRESS_REQUIRED_DEVS); |
194 | goto fail; | 331 | if (rc < 0) |
332 | goto fail; | ||
333 | |||
334 | rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); | ||
335 | if (rc < 0) | ||
336 | goto fail; | ||
337 | } | ||
195 | 338 | ||
196 | rc = tenxpress_init(efx); | 339 | rc = tenxpress_init(efx); |
197 | if (rc < 0) | 340 | if (rc < 0) |
198 | goto fail; | 341 | goto fail; |
342 | mdio_clause45_set_pause(efx); | ||
343 | |||
344 | if (efx->phy_type == PHY_TYPE_SFT9001B) { | ||
345 | rc = device_create_file(&efx->pci_dev->dev, | ||
346 | &dev_attr_phy_short_reach); | ||
347 | if (rc) | ||
348 | goto fail; | ||
349 | } | ||
199 | 350 | ||
200 | schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ | 351 | schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ |
201 | 352 | ||
202 | /* Let XGXS and SerDes out of reset and resets 10XPress */ | 353 | /* Let XGXS and SerDes out of reset */ |
203 | falcon_reset_xaui(efx); | 354 | falcon_reset_xaui(efx); |
204 | 355 | ||
205 | return 0; | 356 | return 0; |
@@ -210,21 +361,24 @@ static int tenxpress_phy_init(struct efx_nic *efx) | |||
210 | return rc; | 361 | return rc; |
211 | } | 362 | } |
212 | 363 | ||
364 | /* Perform a "special software reset" on the PHY. The caller is | ||
365 | * responsible for saving and restoring the PHY hardware registers | ||
366 | * properly, and masking/unmasking LASI */ | ||
213 | static int tenxpress_special_reset(struct efx_nic *efx) | 367 | static int tenxpress_special_reset(struct efx_nic *efx) |
214 | { | 368 | { |
215 | int rc, reg; | 369 | int rc, reg; |
216 | 370 | ||
217 | /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so | 371 | /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so |
218 | * a special software reset can glitch the XGMAC sufficiently for stats | 372 | * a special software reset can glitch the XGMAC sufficiently for stats |
219 | * requests to fail. Since we don't ofen special_reset, just lock. */ | 373 | * requests to fail. */ |
220 | spin_lock(&efx->stats_lock); | 374 | efx_stats_disable(efx); |
221 | 375 | ||
222 | /* Initiate reset */ | 376 | /* Initiate reset */ |
223 | reg = mdio_clause45_read(efx, efx->mii.phy_id, | 377 | reg = mdio_clause45_read(efx, efx->mii.phy_id, |
224 | MDIO_MMD_PMAPMD, PMA_PMD_EXT_CTRL_REG); | 378 | MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); |
225 | reg |= (1 << PMA_PMD_EXT_SSR_LBN); | 379 | reg |= (1 << PMA_PMD_EXT_SSR_LBN); |
226 | mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, | 380 | mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, |
227 | PMA_PMD_EXT_CTRL_REG, reg); | 381 | PMA_PMD_XCONTROL_REG, reg); |
228 | 382 | ||
229 | mdelay(200); | 383 | mdelay(200); |
230 | 384 | ||
@@ -232,181 +386,242 @@ static int tenxpress_special_reset(struct efx_nic *efx) | |||
232 | rc = mdio_clause45_wait_reset_mmds(efx, | 386 | rc = mdio_clause45_wait_reset_mmds(efx, |
233 | TENXPRESS_REQUIRED_DEVS); | 387 | TENXPRESS_REQUIRED_DEVS); |
234 | if (rc < 0) | 388 | if (rc < 0) |
235 | goto unlock; | 389 | goto out; |
236 | 390 | ||
237 | /* Try and reconfigure the device */ | 391 | /* Try and reconfigure the device */ |
238 | rc = tenxpress_init(efx); | 392 | rc = tenxpress_init(efx); |
239 | if (rc < 0) | 393 | if (rc < 0) |
240 | goto unlock; | 394 | goto out; |
241 | 395 | ||
242 | unlock: | 396 | /* Wait for the XGXS state machine to churn */ |
243 | spin_unlock(&efx->stats_lock); | 397 | mdelay(10); |
398 | out: | ||
399 | efx_stats_enable(efx); | ||
244 | return rc; | 400 | return rc; |
245 | } | 401 | } |
246 | 402 | ||
247 | static void tenxpress_set_bad_lp(struct efx_nic *efx, bool bad_lp) | 403 | static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok) |
248 | { | 404 | { |
249 | struct tenxpress_phy_data *pd = efx->phy_data; | 405 | struct tenxpress_phy_data *pd = efx->phy_data; |
406 | int phy_id = efx->mii.phy_id; | ||
407 | bool bad_lp; | ||
250 | int reg; | 408 | int reg; |
251 | 409 | ||
410 | if (link_ok) { | ||
411 | bad_lp = false; | ||
412 | } else { | ||
413 | /* Check that AN has started but not completed. */ | ||
414 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | ||
415 | MDIO_AN_STATUS); | ||
416 | if (!(reg & (1 << MDIO_AN_STATUS_LP_AN_CAP_LBN))) | ||
417 | return; /* LP status is unknown */ | ||
418 | bad_lp = !(reg & (1 << MDIO_AN_STATUS_AN_DONE_LBN)); | ||
419 | if (bad_lp) | ||
420 | pd->bad_lp_tries++; | ||
421 | } | ||
422 | |||
252 | /* Nothing to do if all is well and was previously so. */ | 423 | /* Nothing to do if all is well and was previously so. */ |
253 | if (!(bad_lp || pd->bad_lp_tries)) | 424 | if (!pd->bad_lp_tries) |
254 | return; | 425 | return; |
255 | 426 | ||
256 | reg = mdio_clause45_read(efx, efx->mii.phy_id, | 427 | /* Use the RX (red) LED as an error indicator once we've seen AN |
257 | MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG); | 428 | * failure several times in a row, and also log a message. */ |
429 | if (!bad_lp || pd->bad_lp_tries == MAX_BAD_LP_TRIES) { | ||
430 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
431 | PMA_PMD_LED_OVERR_REG); | ||
432 | reg &= ~(PMA_PMD_LED_MASK << PMA_PMD_LED_RX_LBN); | ||
433 | if (!bad_lp) { | ||
434 | reg |= PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN; | ||
435 | } else { | ||
436 | reg |= PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN; | ||
437 | EFX_ERR(efx, "appears to be plugged into a port" | ||
438 | " that is not 10GBASE-T capable. The PHY" | ||
439 | " supports 10GBASE-T ONLY, so no link can" | ||
440 | " be established\n"); | ||
441 | } | ||
442 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | ||
443 | PMA_PMD_LED_OVERR_REG, reg); | ||
444 | pd->bad_lp_tries = bad_lp; | ||
445 | } | ||
446 | } | ||
258 | 447 | ||
259 | if (bad_lp) | 448 | static bool sfx7101_link_ok(struct efx_nic *efx) |
260 | pd->bad_lp_tries++; | 449 | { |
261 | else | 450 | return mdio_clause45_links_ok(efx, |
262 | pd->bad_lp_tries = 0; | 451 | MDIO_MMDREG_DEVS_PMAPMD | |
263 | 452 | MDIO_MMDREG_DEVS_PCS | | |
264 | if (pd->bad_lp_tries == MAX_BAD_LP_TRIES) { | 453 | MDIO_MMDREG_DEVS_PHYXS); |
265 | pd->bad_lp_tries = 0; /* Restart count */ | 454 | } |
266 | reg &= ~(PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN); | 455 | |
267 | reg |= (PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN); | 456 | static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd) |
268 | EFX_ERR(efx, "This NIC appears to be plugged into" | 457 | { |
269 | " a port that is not 10GBASE-T capable.\n" | 458 | int phy_id = efx->mii.phy_id; |
270 | " This PHY is 10GBASE-T ONLY, so no link can" | 459 | u32 reg; |
271 | " be established.\n"); | 460 | |
461 | if (efx_phy_mode_disabled(efx->phy_mode)) | ||
462 | return false; | ||
463 | else if (efx->loopback_mode == LOOPBACK_GPHY) | ||
464 | return true; | ||
465 | else if (efx->loopback_mode) | ||
466 | return mdio_clause45_links_ok(efx, | ||
467 | MDIO_MMDREG_DEVS_PMAPMD | | ||
468 | MDIO_MMDREG_DEVS_PHYXS); | ||
469 | |||
470 | /* We must use the same definition of link state as LASI, | ||
471 | * otherwise we can miss a link state transition | ||
472 | */ | ||
473 | if (ecmd->speed == 10000) { | ||
474 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS, | ||
475 | PCS_10GBASET_STAT1); | ||
476 | return reg & (1 << PCS_10GBASET_BLKLK_LBN); | ||
272 | } else { | 477 | } else { |
273 | reg |= (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN); | 478 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, |
479 | C22EXT_STATUS_REG); | ||
480 | return reg & (1 << C22EXT_STATUS_LINK_LBN); | ||
274 | } | 481 | } |
275 | mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, | ||
276 | PMA_PMD_LED_OVERR_REG, reg); | ||
277 | } | 482 | } |
278 | 483 | ||
279 | /* Check link status and return a boolean OK value. If the link is NOT | 484 | static void tenxpress_ext_loopback(struct efx_nic *efx) |
280 | * OK we have a quick rummage round to see if we appear to be plugged | ||
281 | * into a non-10GBT port and if so warn the user that they won't get | ||
282 | * link any time soon as we are 10GBT only, unless caller specified | ||
283 | * not to do this check (it isn't useful in loopback) */ | ||
284 | static bool tenxpress_link_ok(struct efx_nic *efx, bool check_lp) | ||
285 | { | 485 | { |
286 | bool ok = mdio_clause45_links_ok(efx, TENXPRESS_REQUIRED_DEVS); | 486 | int phy_id = efx->mii.phy_id; |
287 | |||
288 | if (ok) { | ||
289 | tenxpress_set_bad_lp(efx, false); | ||
290 | } else if (check_lp) { | ||
291 | /* Are we plugged into the wrong sort of link? */ | ||
292 | bool bad_lp = false; | ||
293 | int phy_id = efx->mii.phy_id; | ||
294 | int an_stat = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | ||
295 | MDIO_AN_STATUS); | ||
296 | int xphy_stat = mdio_clause45_read(efx, phy_id, | ||
297 | MDIO_MMD_PMAPMD, | ||
298 | PMA_PMD_XSTATUS_REG); | ||
299 | /* Are we plugged into anything that sends FLPs? If | ||
300 | * not we can't distinguish between not being plugged | ||
301 | * in and being plugged into a non-AN antique. The FLP | ||
302 | * bit has the advantage of not clearing when autoneg | ||
303 | * restarts. */ | ||
304 | if (!(xphy_stat & (1 << PMA_PMD_XSTAT_FLP_LBN))) { | ||
305 | tenxpress_set_bad_lp(efx, false); | ||
306 | return ok; | ||
307 | } | ||
308 | 487 | ||
309 | /* If it can do 10GBT it must be XNP capable */ | 488 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS, |
310 | bad_lp = !(an_stat & (1 << MDIO_AN_STATUS_XNP_LBN)); | 489 | PHYXS_TEST1, LOOPBACK_NEAR_LBN, |
311 | if (!bad_lp && (an_stat & (1 << MDIO_AN_STATUS_PAGE_LBN))) { | 490 | efx->loopback_mode == LOOPBACK_PHYXS); |
312 | bad_lp = !(mdio_clause45_read(efx, phy_id, | 491 | if (efx->phy_type != PHY_TYPE_SFX7101) |
313 | MDIO_MMD_AN, MDIO_AN_10GBT_STATUS) & | 492 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, |
314 | (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)); | 493 | GPHY_XCONTROL_REG, |
315 | } | 494 | GPHY_LOOPBACK_NEAR_LBN, |
316 | tenxpress_set_bad_lp(efx, bad_lp); | 495 | efx->loopback_mode == LOOPBACK_GPHY); |
317 | } | ||
318 | return ok; | ||
319 | } | 496 | } |
320 | 497 | ||
321 | static void tenxpress_phyxs_loopback(struct efx_nic *efx) | 498 | static void tenxpress_low_power(struct efx_nic *efx) |
322 | { | 499 | { |
323 | int phy_id = efx->mii.phy_id; | 500 | int phy_id = efx->mii.phy_id; |
324 | int ctrl1, ctrl2; | ||
325 | 501 | ||
326 | ctrl1 = ctrl2 = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, | 502 | if (efx->phy_type == PHY_TYPE_SFX7101) |
327 | PHYXS_TEST1); | 503 | mdio_clause45_set_mmds_lpower( |
328 | if (efx->loopback_mode == LOOPBACK_PHYXS) | 504 | efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER), |
329 | ctrl2 |= (1 << LOOPBACK_NEAR_LBN); | 505 | TENXPRESS_REQUIRED_DEVS); |
330 | else | 506 | else |
331 | ctrl2 &= ~(1 << LOOPBACK_NEAR_LBN); | 507 | mdio_clause45_set_flag( |
332 | if (ctrl1 != ctrl2) | 508 | efx, phy_id, MDIO_MMD_PMAPMD, |
333 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PHYXS, | 509 | PMA_PMD_XCONTROL_REG, PMA_PMD_EXT_LPOWER_LBN, |
334 | PHYXS_TEST1, ctrl2); | 510 | !!(efx->phy_mode & PHY_MODE_LOW_POWER)); |
335 | } | 511 | } |
336 | 512 | ||
337 | static void tenxpress_phy_reconfigure(struct efx_nic *efx) | 513 | static void tenxpress_phy_reconfigure(struct efx_nic *efx) |
338 | { | 514 | { |
339 | struct tenxpress_phy_data *phy_data = efx->phy_data; | 515 | struct tenxpress_phy_data *phy_data = efx->phy_data; |
340 | bool loop_change = LOOPBACK_OUT_OF(phy_data, efx, | 516 | struct ethtool_cmd ecmd; |
341 | TENXPRESS_LOOPBACKS); | 517 | bool phy_mode_change, loop_reset; |
342 | 518 | ||
343 | if (efx->phy_mode & PHY_MODE_SPECIAL) { | 519 | if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) { |
344 | phy_data->phy_mode = efx->phy_mode; | 520 | phy_data->phy_mode = efx->phy_mode; |
345 | return; | 521 | return; |
346 | } | 522 | } |
347 | 523 | ||
348 | /* When coming out of transmit disable, coming out of low power | 524 | tenxpress_low_power(efx); |
349 | * mode, or moving out of any PHY internal loopback mode, | 525 | |
350 | * perform a special software reset */ | 526 | phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL && |
351 | if ((efx->phy_mode == PHY_MODE_NORMAL && | 527 | phy_data->phy_mode != PHY_MODE_NORMAL); |
352 | phy_data->phy_mode != PHY_MODE_NORMAL) || | 528 | loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) || |
353 | loop_change) { | 529 | LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY)); |
354 | tenxpress_special_reset(efx); | 530 | |
355 | falcon_reset_xaui(efx); | 531 | if (loop_reset || phy_mode_change) { |
532 | int rc; | ||
533 | |||
534 | efx->phy_op->get_settings(efx, &ecmd); | ||
535 | |||
536 | if (loop_reset || phy_mode_change) { | ||
537 | tenxpress_special_reset(efx); | ||
538 | |||
539 | /* Reset XAUI if we were in 10G, and are staying | ||
540 | * in 10G. If we're moving into and out of 10G | ||
541 | * then xaui will be reset anyway */ | ||
542 | if (EFX_IS10G(efx)) | ||
543 | falcon_reset_xaui(efx); | ||
544 | } | ||
545 | |||
546 | rc = efx->phy_op->set_settings(efx, &ecmd); | ||
547 | WARN_ON(rc); | ||
356 | } | 548 | } |
357 | 549 | ||
358 | mdio_clause45_transmit_disable(efx); | 550 | mdio_clause45_transmit_disable(efx); |
359 | mdio_clause45_phy_reconfigure(efx); | 551 | mdio_clause45_phy_reconfigure(efx); |
360 | tenxpress_phyxs_loopback(efx); | 552 | tenxpress_ext_loopback(efx); |
361 | 553 | ||
362 | phy_data->loopback_mode = efx->loopback_mode; | 554 | phy_data->loopback_mode = efx->loopback_mode; |
363 | phy_data->phy_mode = efx->phy_mode; | 555 | phy_data->phy_mode = efx->phy_mode; |
364 | efx->link_up = tenxpress_link_ok(efx, false); | ||
365 | efx->link_options = GM_LPA_10000FULL; | ||
366 | } | ||
367 | 556 | ||
368 | static void tenxpress_phy_clear_interrupt(struct efx_nic *efx) | 557 | if (efx->phy_type == PHY_TYPE_SFX7101) { |
369 | { | 558 | efx->link_speed = 10000; |
370 | /* Nothing done here - LASI interrupts aren't reliable so poll */ | 559 | efx->link_fd = true; |
560 | efx->link_up = sfx7101_link_ok(efx); | ||
561 | } else { | ||
562 | efx->phy_op->get_settings(efx, &ecmd); | ||
563 | efx->link_speed = ecmd.speed; | ||
564 | efx->link_fd = ecmd.duplex == DUPLEX_FULL; | ||
565 | efx->link_up = sft9001_link_ok(efx, &ecmd); | ||
566 | } | ||
567 | efx->link_fc = mdio_clause45_get_pause(efx); | ||
371 | } | 568 | } |
372 | 569 | ||
373 | |||
374 | /* Poll PHY for interrupt */ | 570 | /* Poll PHY for interrupt */ |
375 | static int tenxpress_phy_check_hw(struct efx_nic *efx) | 571 | static void tenxpress_phy_poll(struct efx_nic *efx) |
376 | { | 572 | { |
377 | struct tenxpress_phy_data *phy_data = efx->phy_data; | 573 | struct tenxpress_phy_data *phy_data = efx->phy_data; |
378 | bool link_ok; | 574 | bool change = false, link_ok; |
379 | 575 | unsigned link_fc; | |
380 | link_ok = tenxpress_link_ok(efx, true); | 576 | |
577 | if (efx->phy_type == PHY_TYPE_SFX7101) { | ||
578 | link_ok = sfx7101_link_ok(efx); | ||
579 | if (link_ok != efx->link_up) { | ||
580 | change = true; | ||
581 | } else { | ||
582 | link_fc = mdio_clause45_get_pause(efx); | ||
583 | if (link_fc != efx->link_fc) | ||
584 | change = true; | ||
585 | } | ||
586 | sfx7101_check_bad_lp(efx, link_ok); | ||
587 | } else if (efx->loopback_mode) { | ||
588 | bool link_ok = sft9001_link_ok(efx, NULL); | ||
589 | if (link_ok != efx->link_up) | ||
590 | change = true; | ||
591 | } else { | ||
592 | u32 status = mdio_clause45_read(efx, efx->mii.phy_id, | ||
593 | MDIO_MMD_PMAPMD, | ||
594 | PMA_PMD_LASI_STATUS); | ||
595 | if (status & (1 << PMA_PMD_LS_ALARM_LBN)) | ||
596 | change = true; | ||
597 | } | ||
381 | 598 | ||
382 | if (link_ok != efx->link_up) | 599 | if (change) |
383 | falcon_xmac_sim_phy_event(efx); | 600 | falcon_sim_phy_event(efx); |
384 | 601 | ||
385 | if (phy_data->phy_mode != PHY_MODE_NORMAL) | 602 | if (phy_data->phy_mode != PHY_MODE_NORMAL) |
386 | return 0; | 603 | return; |
387 | |||
388 | if (atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) { | ||
389 | EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n"); | ||
390 | falcon_reset_xaui(efx); | ||
391 | atomic_set(&phy_data->bad_crc_count, 0); | ||
392 | } | ||
393 | |||
394 | return 0; | ||
395 | } | 604 | } |
396 | 605 | ||
397 | static void tenxpress_phy_fini(struct efx_nic *efx) | 606 | static void tenxpress_phy_fini(struct efx_nic *efx) |
398 | { | 607 | { |
399 | int reg; | 608 | int reg; |
400 | 609 | ||
401 | /* Power down the LNPGA */ | 610 | if (efx->phy_type == PHY_TYPE_SFT9001B) |
402 | reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); | 611 | device_remove_file(&efx->pci_dev->dev, |
403 | mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, | 612 | &dev_attr_phy_short_reach); |
404 | PMA_PMD_XCONTROL_REG, reg); | ||
405 | 613 | ||
406 | /* Waiting here ensures that the board fini, which can turn off the | 614 | if (efx->phy_type == PHY_TYPE_SFX7101) { |
407 | * power to the PHY, won't get run until the LNPGA powerdown has been | 615 | /* Power down the LNPGA */ |
408 | * given long enough to complete. */ | 616 | reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); |
409 | schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */ | 617 | mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, |
618 | PMA_PMD_XCONTROL_REG, reg); | ||
619 | |||
620 | /* Waiting here ensures that the board fini, which can turn | ||
621 | * off the power to the PHY, won't get run until the LNPGA | ||
622 | * powerdown has been given long enough to complete. */ | ||
623 | schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */ | ||
624 | } | ||
410 | 625 | ||
411 | kfree(efx->phy_data); | 626 | kfree(efx->phy_data); |
412 | efx->phy_data = NULL; | 627 | efx->phy_data = NULL; |
@@ -430,19 +645,206 @@ void tenxpress_phy_blink(struct efx_nic *efx, bool blink) | |||
430 | PMA_PMD_LED_OVERR_REG, reg); | 645 | PMA_PMD_LED_OVERR_REG, reg); |
431 | } | 646 | } |
432 | 647 | ||
433 | static int tenxpress_phy_test(struct efx_nic *efx) | 648 | static const char *const sfx7101_test_names[] = { |
649 | "bist" | ||
650 | }; | ||
651 | |||
652 | static int | ||
653 | sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags) | ||
434 | { | 654 | { |
655 | int rc; | ||
656 | |||
657 | if (!(flags & ETH_TEST_FL_OFFLINE)) | ||
658 | return 0; | ||
659 | |||
435 | /* BIST is automatically run after a special software reset */ | 660 | /* BIST is automatically run after a special software reset */ |
436 | return tenxpress_special_reset(efx); | 661 | rc = tenxpress_special_reset(efx); |
662 | results[0] = rc ? -1 : 1; | ||
663 | return rc; | ||
437 | } | 664 | } |
438 | 665 | ||
439 | struct efx_phy_operations falcon_tenxpress_phy_ops = { | 666 | static const char *const sft9001_test_names[] = { |
667 | "bist", | ||
668 | "cable.pairA.status", | ||
669 | "cable.pairB.status", | ||
670 | "cable.pairC.status", | ||
671 | "cable.pairD.status", | ||
672 | "cable.pairA.length", | ||
673 | "cable.pairB.length", | ||
674 | "cable.pairC.length", | ||
675 | "cable.pairD.length", | ||
676 | }; | ||
677 | |||
678 | static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags) | ||
679 | { | ||
680 | struct ethtool_cmd ecmd; | ||
681 | int phy_id = efx->mii.phy_id; | ||
682 | int rc = 0, rc2, i, res_reg; | ||
683 | |||
684 | if (!(flags & ETH_TEST_FL_OFFLINE)) | ||
685 | return 0; | ||
686 | |||
687 | efx->phy_op->get_settings(efx, &ecmd); | ||
688 | |||
689 | /* Initialise cable diagnostic results to unknown failure */ | ||
690 | for (i = 1; i < 9; ++i) | ||
691 | results[i] = -1; | ||
692 | |||
693 | /* Run cable diagnostics; wait up to 5 seconds for them to complete. | ||
694 | * A cable fault is not a self-test failure, but a timeout is. */ | ||
695 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | ||
696 | PMA_PMD_CDIAG_CTRL_REG, | ||
697 | (1 << CDIAG_CTRL_IMMED_LBN) | | ||
698 | (1 << CDIAG_CTRL_BRK_LINK_LBN) | | ||
699 | (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN)); | ||
700 | i = 0; | ||
701 | while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
702 | PMA_PMD_CDIAG_CTRL_REG) & | ||
703 | (1 << CDIAG_CTRL_IN_PROG_LBN)) { | ||
704 | if (++i == 50) { | ||
705 | rc = -ETIMEDOUT; | ||
706 | goto reset; | ||
707 | } | ||
708 | msleep(100); | ||
709 | } | ||
710 | res_reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, | ||
711 | PMA_PMD_CDIAG_RES_REG); | ||
712 | for (i = 0; i < 4; i++) { | ||
713 | int pair_res = | ||
714 | (res_reg >> (CDIAG_RES_A_LBN - i * CDIAG_RES_WIDTH)) | ||
715 | & ((1 << CDIAG_RES_WIDTH) - 1); | ||
716 | int len_reg = mdio_clause45_read(efx, efx->mii.phy_id, | ||
717 | MDIO_MMD_PMAPMD, | ||
718 | PMA_PMD_CDIAG_LEN_REG + i); | ||
719 | if (pair_res == CDIAG_RES_OK) | ||
720 | results[1 + i] = 1; | ||
721 | else if (pair_res == CDIAG_RES_INVALID) | ||
722 | results[1 + i] = -1; | ||
723 | else | ||
724 | results[1 + i] = -pair_res; | ||
725 | if (pair_res != CDIAG_RES_INVALID && | ||
726 | pair_res != CDIAG_RES_OPEN && | ||
727 | len_reg != 0xffff) | ||
728 | results[5 + i] = len_reg; | ||
729 | } | ||
730 | |||
731 | /* We must reset to exit cable diagnostic mode. The BIST will | ||
732 | * also run when we do this. */ | ||
733 | reset: | ||
734 | rc2 = tenxpress_special_reset(efx); | ||
735 | results[0] = rc2 ? -1 : 1; | ||
736 | if (!rc) | ||
737 | rc = rc2; | ||
738 | |||
739 | rc2 = efx->phy_op->set_settings(efx, &ecmd); | ||
740 | if (!rc) | ||
741 | rc = rc2; | ||
742 | |||
743 | return rc; | ||
744 | } | ||
745 | |||
746 | static void | ||
747 | tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | ||
748 | { | ||
749 | int phy_id = efx->mii.phy_id; | ||
750 | u32 adv = 0, lpa = 0; | ||
751 | int reg; | ||
752 | |||
753 | if (efx->phy_type != PHY_TYPE_SFX7101) { | ||
754 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, | ||
755 | C22EXT_MSTSLV_CTRL); | ||
756 | if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN)) | ||
757 | adv |= ADVERTISED_1000baseT_Full; | ||
758 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, | ||
759 | C22EXT_MSTSLV_STATUS); | ||
760 | if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN)) | ||
761 | lpa |= ADVERTISED_1000baseT_Half; | ||
762 | if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN)) | ||
763 | lpa |= ADVERTISED_1000baseT_Full; | ||
764 | } | ||
765 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | ||
766 | MDIO_AN_10GBT_CTRL); | ||
767 | if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN)) | ||
768 | adv |= ADVERTISED_10000baseT_Full; | ||
769 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | ||
770 | MDIO_AN_10GBT_STATUS); | ||
771 | if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)) | ||
772 | lpa |= ADVERTISED_10000baseT_Full; | ||
773 | |||
774 | mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa); | ||
775 | |||
776 | if (efx->phy_type != PHY_TYPE_SFX7101) | ||
777 | ecmd->supported |= (SUPPORTED_100baseT_Full | | ||
778 | SUPPORTED_1000baseT_Full); | ||
779 | |||
780 | /* In loopback, the PHY automatically brings up the correct interface, | ||
781 | * but doesn't advertise the correct speed. So override it */ | ||
782 | if (efx->loopback_mode == LOOPBACK_GPHY) | ||
783 | ecmd->speed = SPEED_1000; | ||
784 | else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks) | ||
785 | ecmd->speed = SPEED_10000; | ||
786 | } | ||
787 | |||
788 | static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | ||
789 | { | ||
790 | if (!ecmd->autoneg) | ||
791 | return -EINVAL; | ||
792 | |||
793 | return mdio_clause45_set_settings(efx, ecmd); | ||
794 | } | ||
795 | |||
796 | static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising) | ||
797 | { | ||
798 | mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN, | ||
799 | MDIO_AN_10GBT_CTRL, | ||
800 | MDIO_AN_10GBT_CTRL_ADV_10G_LBN, | ||
801 | advertising & ADVERTISED_10000baseT_Full); | ||
802 | } | ||
803 | |||
804 | static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) | ||
805 | { | ||
806 | int phy_id = efx->mii.phy_id; | ||
807 | |||
808 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, | ||
809 | C22EXT_MSTSLV_CTRL, | ||
810 | C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN, | ||
811 | advertising & ADVERTISED_1000baseT_Full); | ||
812 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, | ||
813 | MDIO_AN_10GBT_CTRL, | ||
814 | MDIO_AN_10GBT_CTRL_ADV_10G_LBN, | ||
815 | advertising & ADVERTISED_10000baseT_Full); | ||
816 | } | ||
817 | |||
818 | struct efx_phy_operations falcon_sfx7101_phy_ops = { | ||
819 | .macs = EFX_XMAC, | ||
820 | .init = tenxpress_phy_init, | ||
821 | .reconfigure = tenxpress_phy_reconfigure, | ||
822 | .poll = tenxpress_phy_poll, | ||
823 | .fini = tenxpress_phy_fini, | ||
824 | .clear_interrupt = efx_port_dummy_op_void, | ||
825 | .get_settings = tenxpress_get_settings, | ||
826 | .set_settings = tenxpress_set_settings, | ||
827 | .set_npage_adv = sfx7101_set_npage_adv, | ||
828 | .num_tests = ARRAY_SIZE(sfx7101_test_names), | ||
829 | .test_names = sfx7101_test_names, | ||
830 | .run_tests = sfx7101_run_tests, | ||
831 | .mmds = TENXPRESS_REQUIRED_DEVS, | ||
832 | .loopbacks = SFX7101_LOOPBACKS, | ||
833 | }; | ||
834 | |||
835 | struct efx_phy_operations falcon_sft9001_phy_ops = { | ||
836 | .macs = EFX_GMAC | EFX_XMAC, | ||
440 | .init = tenxpress_phy_init, | 837 | .init = tenxpress_phy_init, |
441 | .reconfigure = tenxpress_phy_reconfigure, | 838 | .reconfigure = tenxpress_phy_reconfigure, |
442 | .check_hw = tenxpress_phy_check_hw, | 839 | .poll = tenxpress_phy_poll, |
443 | .fini = tenxpress_phy_fini, | 840 | .fini = tenxpress_phy_fini, |
444 | .clear_interrupt = tenxpress_phy_clear_interrupt, | 841 | .clear_interrupt = efx_port_dummy_op_void, |
445 | .test = tenxpress_phy_test, | 842 | .get_settings = tenxpress_get_settings, |
843 | .set_settings = tenxpress_set_settings, | ||
844 | .set_npage_adv = sft9001_set_npage_adv, | ||
845 | .num_tests = ARRAY_SIZE(sft9001_test_names), | ||
846 | .test_names = sft9001_test_names, | ||
847 | .run_tests = sft9001_run_tests, | ||
446 | .mmds = TENXPRESS_REQUIRED_DEVS, | 848 | .mmds = TENXPRESS_REQUIRED_DEVS, |
447 | .loopbacks = TENXPRESS_LOOPBACKS, | 849 | .loopbacks = SFT9001_LOOPBACKS, |
448 | }; | 850 | }; |
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index fa7b49d69288..78de68f4a95b 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h | |||
@@ -17,15 +17,18 @@ | |||
17 | 17 | ||
18 | #define EFX_WORKAROUND_ALWAYS(efx) 1 | 18 | #define EFX_WORKAROUND_ALWAYS(efx) 1 |
19 | #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) | 19 | #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) |
20 | #define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx) | ||
21 | #define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \ | ||
22 | (efx)->phy_type == PHY_TYPE_SFT9001B) | ||
20 | 23 | ||
21 | /* XAUI resets if link not detected */ | 24 | /* XAUI resets if link not detected */ |
22 | #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS | 25 | #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS |
23 | /* RX PCIe double split performance issue */ | 26 | /* RX PCIe double split performance issue */ |
24 | #define EFX_WORKAROUND_7575 EFX_WORKAROUND_ALWAYS | 27 | #define EFX_WORKAROUND_7575 EFX_WORKAROUND_ALWAYS |
28 | /* Bit-bashed I2C reads cause performance drop */ | ||
29 | #define EFX_WORKAROUND_7884 EFX_WORKAROUND_10G | ||
25 | /* TX pkt parser problem with <= 16 byte TXes */ | 30 | /* TX pkt parser problem with <= 16 byte TXes */ |
26 | #define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS | 31 | #define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS |
27 | /* Low rate CRC errors require XAUI reset */ | ||
28 | #define EFX_WORKAROUND_10750 EFX_WORKAROUND_ALWAYS | ||
29 | /* TX_EV_PKT_ERR can be caused by a dangling TX descriptor | 32 | /* TX_EV_PKT_ERR can be caused by a dangling TX descriptor |
30 | * or a PCIe error (bug 11028) */ | 33 | * or a PCIe error (bug 11028) */ |
31 | #define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS | 34 | #define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS |
@@ -49,4 +52,9 @@ | |||
49 | /* Leak overlength packets rather than free */ | 52 | /* Leak overlength packets rather than free */ |
50 | #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A | 53 | #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A |
51 | 54 | ||
55 | /* Need to send XNP pages for 100BaseT */ | ||
56 | #define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001 | ||
57 | /* Don't restart AN in near-side loopback */ | ||
58 | #define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001 | ||
59 | |||
52 | #endif /* EFX_WORKAROUNDS_H */ | 60 | #endif /* EFX_WORKAROUNDS_H */ |
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c index 276151df3a70..2d50b6ecf5f9 100644 --- a/drivers/net/sfc/xfp_phy.c +++ b/drivers/net/sfc/xfp_phy.c | |||
@@ -7,22 +7,21 @@ | |||
7 | * by the Free Software Foundation, incorporated herein by reference. | 7 | * by the Free Software Foundation, incorporated herein by reference. |
8 | */ | 8 | */ |
9 | /* | 9 | /* |
10 | * Driver for XFP optical PHYs (plus some support specific to the Quake 2032) | 10 | * Driver for XFP optical PHYs (plus some support specific to the Quake 2022/32) |
11 | * See www.amcc.com for details (search for qt2032) | 11 | * See www.amcc.com for details (search for qt2032) |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/timer.h> | 14 | #include <linux/timer.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include "efx.h" | 16 | #include "efx.h" |
17 | #include "gmii.h" | ||
18 | #include "mdio_10g.h" | 17 | #include "mdio_10g.h" |
19 | #include "xenpack.h" | 18 | #include "xenpack.h" |
20 | #include "phy.h" | 19 | #include "phy.h" |
21 | #include "mac.h" | 20 | #include "falcon.h" |
22 | 21 | ||
23 | #define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS0_PCS | \ | 22 | #define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PCS | \ |
24 | MDIO_MMDREG_DEVS0_PMAPMD | \ | 23 | MDIO_MMDREG_DEVS_PMAPMD | \ |
25 | MDIO_MMDREG_DEVS0_PHYXS) | 24 | MDIO_MMDREG_DEVS_PHYXS) |
26 | 25 | ||
27 | #define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) | \ | 26 | #define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) | \ |
28 | (1 << LOOPBACK_PMAPMD) | \ | 27 | (1 << LOOPBACK_PMAPMD) | \ |
@@ -65,7 +64,7 @@ static int xfp_reset_phy(struct efx_nic *efx) | |||
65 | /* Check that all the MMDs we expect are present and responding. We | 64 | /* Check that all the MMDs we expect are present and responding. We |
66 | * expect faults on some if the link is down, but not on the PHY XS */ | 65 | * expect faults on some if the link is down, but not on the PHY XS */ |
67 | rc = mdio_clause45_check_mmds(efx, XFP_REQUIRED_DEVS, | 66 | rc = mdio_clause45_check_mmds(efx, XFP_REQUIRED_DEVS, |
68 | MDIO_MMDREG_DEVS0_PHYXS); | 67 | MDIO_MMDREG_DEVS_PHYXS); |
69 | if (rc < 0) | 68 | if (rc < 0) |
70 | goto fail; | 69 | goto fail; |
71 | 70 | ||
@@ -120,15 +119,12 @@ static int xfp_link_ok(struct efx_nic *efx) | |||
120 | return mdio_clause45_links_ok(efx, XFP_REQUIRED_DEVS); | 119 | return mdio_clause45_links_ok(efx, XFP_REQUIRED_DEVS); |
121 | } | 120 | } |
122 | 121 | ||
123 | static int xfp_phy_check_hw(struct efx_nic *efx) | 122 | static void xfp_phy_poll(struct efx_nic *efx) |
124 | { | 123 | { |
125 | int rc = 0; | ||
126 | int link_up = xfp_link_ok(efx); | 124 | int link_up = xfp_link_ok(efx); |
127 | /* Simulate a PHY event if link state has changed */ | 125 | /* Simulate a PHY event if link state has changed */ |
128 | if (link_up != efx->link_up) | 126 | if (link_up != efx->link_up) |
129 | falcon_xmac_sim_phy_event(efx); | 127 | falcon_sim_phy_event(efx); |
130 | |||
131 | return rc; | ||
132 | } | 128 | } |
133 | 129 | ||
134 | static void xfp_phy_reconfigure(struct efx_nic *efx) | 130 | static void xfp_phy_reconfigure(struct efx_nic *efx) |
@@ -145,7 +141,9 @@ static void xfp_phy_reconfigure(struct efx_nic *efx) | |||
145 | 141 | ||
146 | phy_data->phy_mode = efx->phy_mode; | 142 | phy_data->phy_mode = efx->phy_mode; |
147 | efx->link_up = xfp_link_ok(efx); | 143 | efx->link_up = xfp_link_ok(efx); |
148 | efx->link_options = GM_LPA_10000FULL; | 144 | efx->link_speed = 10000; |
145 | efx->link_fd = true; | ||
146 | efx->link_fc = efx->wanted_fc; | ||
149 | } | 147 | } |
150 | 148 | ||
151 | 149 | ||
@@ -160,11 +158,14 @@ static void xfp_phy_fini(struct efx_nic *efx) | |||
160 | } | 158 | } |
161 | 159 | ||
162 | struct efx_phy_operations falcon_xfp_phy_ops = { | 160 | struct efx_phy_operations falcon_xfp_phy_ops = { |
161 | .macs = EFX_XMAC, | ||
163 | .init = xfp_phy_init, | 162 | .init = xfp_phy_init, |
164 | .reconfigure = xfp_phy_reconfigure, | 163 | .reconfigure = xfp_phy_reconfigure, |
165 | .check_hw = xfp_phy_check_hw, | 164 | .poll = xfp_phy_poll, |
166 | .fini = xfp_phy_fini, | 165 | .fini = xfp_phy_fini, |
167 | .clear_interrupt = xfp_phy_clear_interrupt, | 166 | .clear_interrupt = xfp_phy_clear_interrupt, |
167 | .get_settings = mdio_clause45_get_settings, | ||
168 | .set_settings = mdio_clause45_set_settings, | ||
168 | .mmds = XFP_REQUIRED_DEVS, | 169 | .mmds = XFP_REQUIRED_DEVS, |
169 | .loopbacks = XFP_LOOPBACKS, | 170 | .loopbacks = XFP_LOOPBACKS, |
170 | }; | 171 | }; |