Print this page
6064 ixgbe needs X550 support
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/ixgbe/ixgbe_gld.c
+++ new/usr/src/uts/common/io/ixgbe/ixgbe_gld.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright(c) 2007-2010 Intel Corporation. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 28 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
29 29 * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved.
30 30 */
31 31
32 32 #include "ixgbe_sw.h"
33 33
34 34 /*
35 35 * Bring the device out of the reset/quiesced state that it
36 36 * was in when the interface was registered.
37 37 */
38 38 int
39 39 ixgbe_m_start(void *arg)
40 40 {
41 41 ixgbe_t *ixgbe = (ixgbe_t *)arg;
42 42
43 43 mutex_enter(&ixgbe->gen_lock);
44 44
45 45 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
46 46 mutex_exit(&ixgbe->gen_lock);
47 47 return (ECANCELED);
48 48 }
49 49
50 50 if (ixgbe_start(ixgbe, B_TRUE) != IXGBE_SUCCESS) {
51 51 mutex_exit(&ixgbe->gen_lock);
52 52 return (EIO);
53 53 }
54 54
55 55 atomic_or_32(&ixgbe->ixgbe_state, IXGBE_STARTED);
56 56
57 57 mutex_exit(&ixgbe->gen_lock);
58 58
59 59 /*
60 60 * Enable and start the watchdog timer
61 61 */
62 62 ixgbe_enable_watchdog_timer(ixgbe);
63 63
64 64 return (0);
65 65 }
66 66
67 67 /*
68 68 * Stop the device and put it in a reset/quiesced state such
69 69 * that the interface can be unregistered.
70 70 */
71 71 void
72 72 ixgbe_m_stop(void *arg)
73 73 {
74 74 ixgbe_t *ixgbe = (ixgbe_t *)arg;
75 75
76 76 mutex_enter(&ixgbe->gen_lock);
77 77
78 78 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
79 79 mutex_exit(&ixgbe->gen_lock);
80 80 return;
81 81 }
82 82
83 83 atomic_and_32(&ixgbe->ixgbe_state, ~IXGBE_STARTED);
84 84
85 85 ixgbe_stop(ixgbe, B_TRUE);
86 86
87 87 mutex_exit(&ixgbe->gen_lock);
88 88
89 89 /*
90 90 * Disable and stop the watchdog timer
91 91 */
92 92 ixgbe_disable_watchdog_timer(ixgbe);
93 93 }
94 94
95 95 /*
96 96 * Set the promiscuity of the device.
97 97 */
98 98 int
99 99 ixgbe_m_promisc(void *arg, boolean_t on)
100 100 {
101 101 ixgbe_t *ixgbe = (ixgbe_t *)arg;
102 102 uint32_t reg_val;
103 103 struct ixgbe_hw *hw = &ixgbe->hw;
104 104
105 105 mutex_enter(&ixgbe->gen_lock);
106 106
107 107 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
108 108 mutex_exit(&ixgbe->gen_lock);
109 109 return (ECANCELED);
110 110 }
111 111 reg_val = IXGBE_READ_REG(hw, IXGBE_FCTRL);
112 112
113 113 if (on)
114 114 reg_val |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
115 115 else
116 116 reg_val &= (~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE));
117 117
118 118 IXGBE_WRITE_REG(&ixgbe->hw, IXGBE_FCTRL, reg_val);
119 119
120 120 mutex_exit(&ixgbe->gen_lock);
121 121
122 122 return (0);
123 123 }
124 124
125 125 /*
126 126 * Add/remove the addresses to/from the set of multicast
127 127 * addresses for which the device will receive packets.
128 128 */
129 129 int
130 130 ixgbe_m_multicst(void *arg, boolean_t add, const uint8_t *mcst_addr)
131 131 {
132 132 ixgbe_t *ixgbe = (ixgbe_t *)arg;
133 133 int result;
134 134
135 135 mutex_enter(&ixgbe->gen_lock);
136 136
137 137 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
138 138 mutex_exit(&ixgbe->gen_lock);
139 139 return (ECANCELED);
140 140 }
141 141
142 142 result = (add) ? ixgbe_multicst_add(ixgbe, mcst_addr)
143 143 : ixgbe_multicst_remove(ixgbe, mcst_addr);
144 144
145 145 mutex_exit(&ixgbe->gen_lock);
146 146
147 147 return (result);
148 148 }
149 149
150 150 /*
151 151 * Pass on M_IOCTL messages passed to the DLD, and support
152 152 * private IOCTLs for debugging and ndd.
153 153 */
154 154 void
155 155 ixgbe_m_ioctl(void *arg, queue_t *q, mblk_t *mp)
156 156 {
157 157 ixgbe_t *ixgbe = (ixgbe_t *)arg;
158 158 struct iocblk *iocp;
159 159 enum ioc_reply status;
160 160
161 161 iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
162 162 iocp->ioc_error = 0;
163 163
164 164 mutex_enter(&ixgbe->gen_lock);
165 165 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
166 166 mutex_exit(&ixgbe->gen_lock);
167 167 miocnak(q, mp, 0, EINVAL);
168 168 return;
169 169 }
170 170 mutex_exit(&ixgbe->gen_lock);
171 171
172 172 switch (iocp->ioc_cmd) {
173 173 case LB_GET_INFO_SIZE:
174 174 case LB_GET_INFO:
175 175 case LB_GET_MODE:
176 176 case LB_SET_MODE:
177 177 status = ixgbe_loopback_ioctl(ixgbe, iocp, mp);
178 178 break;
179 179
180 180 default:
181 181 status = IOC_INVAL;
182 182 break;
183 183 }
184 184
185 185 /*
186 186 * Decide how to reply
187 187 */
188 188 switch (status) {
189 189 default:
190 190 case IOC_INVAL:
191 191 /*
192 192 * Error, reply with a NAK and EINVAL or the specified error
193 193 */
194 194 miocnak(q, mp, 0, iocp->ioc_error == 0 ?
195 195 EINVAL : iocp->ioc_error);
196 196 break;
197 197
198 198 case IOC_DONE:
199 199 /*
200 200 * OK, reply already sent
201 201 */
202 202 break;
203 203
204 204 case IOC_ACK:
205 205 /*
206 206 * OK, reply with an ACK
207 207 */
208 208 miocack(q, mp, 0, 0);
209 209 break;
210 210
211 211 case IOC_REPLY:
212 212 /*
213 213 * OK, send prepared reply as ACK or NAK
214 214 */
215 215 mp->b_datap->db_type = iocp->ioc_error == 0 ?
216 216 M_IOCACK : M_IOCNAK;
217 217 qreply(q, mp);
218 218 break;
219 219 }
220 220 }
221 221
222 222 /*
223 223 * Obtain the MAC's capabilities and associated data from
224 224 * the driver.
225 225 */
226 226 boolean_t
227 227 ixgbe_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
228 228 {
229 229 ixgbe_t *ixgbe = (ixgbe_t *)arg;
230 230
231 231 switch (cap) {
232 232 case MAC_CAPAB_HCKSUM: {
233 233 uint32_t *tx_hcksum_flags = cap_data;
234 234
235 235 /*
236 236 * We advertise our capabilities only if tx hcksum offload is
237 237 * enabled. On receive, the stack will accept checksummed
238 238 * packets anyway, even if we haven't said we can deliver
239 239 * them.
240 240 */
241 241 if (!ixgbe->tx_hcksum_enable)
242 242 return (B_FALSE);
243 243
244 244 *tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM;
245 245 break;
246 246 }
247 247 case MAC_CAPAB_LSO: {
248 248 mac_capab_lso_t *cap_lso = cap_data;
249 249
250 250 if (ixgbe->lso_enable) {
251 251 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
252 252 cap_lso->lso_basic_tcp_ipv4.lso_max = IXGBE_LSO_MAXLEN;
253 253 break;
254 254 } else {
255 255 return (B_FALSE);
256 256 }
257 257 }
258 258 case MAC_CAPAB_RINGS: {
259 259 mac_capab_rings_t *cap_rings = cap_data;
260 260
261 261 switch (cap_rings->mr_type) {
262 262 case MAC_RING_TYPE_RX:
263 263 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
264 264 cap_rings->mr_rnum = ixgbe->num_rx_rings;
265 265 cap_rings->mr_gnum = ixgbe->num_rx_groups;
266 266 cap_rings->mr_rget = ixgbe_fill_ring;
267 267 cap_rings->mr_gget = ixgbe_fill_group;
268 268 cap_rings->mr_gaddring = NULL;
269 269 cap_rings->mr_gremring = NULL;
270 270 break;
271 271 case MAC_RING_TYPE_TX:
272 272 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
273 273 cap_rings->mr_rnum = ixgbe->num_tx_rings;
274 274 cap_rings->mr_gnum = 0;
275 275 cap_rings->mr_rget = ixgbe_fill_ring;
276 276 cap_rings->mr_gget = NULL;
277 277 break;
278 278 default:
279 279 break;
280 280 }
281 281 break;
282 282 }
283 283 default:
284 284 return (B_FALSE);
285 285 }
286 286 return (B_TRUE);
287 287 }
288 288
289 289 int
↓ open down ↓ |
289 lines elided |
↑ open up ↑ |
290 290 ixgbe_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
291 291 uint_t pr_valsize, const void *pr_val)
292 292 {
293 293 ixgbe_t *ixgbe = (ixgbe_t *)arg;
294 294 struct ixgbe_hw *hw = &ixgbe->hw;
295 295 int err = 0;
296 296 uint32_t flow_control;
297 297 uint32_t cur_mtu, new_mtu;
298 298 uint32_t rx_size;
299 299 uint32_t tx_size;
300 + ixgbe_link_speed speeds = 0;
300 301
301 302 mutex_enter(&ixgbe->gen_lock);
302 303 if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
303 304 mutex_exit(&ixgbe->gen_lock);
304 305 return (ECANCELED);
305 306 }
306 307
308 + /*
309 + * We cannot always rely on the common code maintaining
310 + * hw->phy.speeds_supported, therefore we fall back to use the recorded
311 + * supported speeds which were obtained during instance init in
312 + * ixgbe_init_params().
313 + */
314 + speeds = hw->phy.speeds_supported;
315 + if (speeds == 0)
316 + speeds = ixgbe->speeds_supported;
317 +
307 318 if (ixgbe->loopback_mode != IXGBE_LB_NONE &&
308 319 ixgbe_param_locked(pr_num)) {
309 320 /*
310 321 * All en_* parameters are locked (read-only)
311 322 * while the device is in any sort of loopback mode.
312 323 */
313 324 mutex_exit(&ixgbe->gen_lock);
314 325 return (EBUSY);
315 326 }
316 327
328 + /*
329 + * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked
330 + * read-only on non-baseT PHYs.
331 + */
317 332 switch (pr_num) {
318 333 case MAC_PROP_EN_10GFDX_CAP:
319 - /* read/write on copper, read-only on serdes */
320 - if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
321 - err = ENOTSUP;
322 - break;
323 - } else {
334 + if (hw->phy.media_type == ixgbe_media_type_copper &&
335 + speeds & IXGBE_LINK_SPEED_10GB_FULL) {
324 336 ixgbe->param_en_10000fdx_cap = *(uint8_t *)pr_val;
325 - ixgbe->param_adv_10000fdx_cap = *(uint8_t *)pr_val;
326 337 goto setup_link;
338 + } else {
339 + err = ENOTSUP;
340 + break;
327 341 }
328 - case MAC_PROP_EN_1000FDX_CAP:
329 - /* read/write on copper, read-only on serdes */
330 - if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
342 + case MAC_PROP_EN_5000FDX_CAP:
343 + if (hw->phy.media_type == ixgbe_media_type_copper &&
344 + speeds & IXGBE_LINK_SPEED_5GB_FULL) {
345 + ixgbe->param_en_5000fdx_cap = *(uint8_t *)pr_val;
346 + goto setup_link;
347 + } else {
331 348 err = ENOTSUP;
332 349 break;
350 + }
351 + case MAC_PROP_EN_2500FDX_CAP:
352 + if (hw->phy.media_type == ixgbe_media_type_copper &&
353 + speeds & IXGBE_LINK_SPEED_2_5GB_FULL) {
354 + ixgbe->param_en_2500fdx_cap = *(uint8_t *)pr_val;
355 + goto setup_link;
333 356 } else {
357 + err = ENOTSUP;
358 + break;
359 + }
360 + case MAC_PROP_EN_1000FDX_CAP:
361 + if (hw->phy.media_type == ixgbe_media_type_copper &&
362 + speeds & IXGBE_LINK_SPEED_1GB_FULL) {
334 363 ixgbe->param_en_1000fdx_cap = *(uint8_t *)pr_val;
335 - ixgbe->param_adv_1000fdx_cap = *(uint8_t *)pr_val;
336 364 goto setup_link;
337 - }
338 - case MAC_PROP_EN_100FDX_CAP:
339 - /* read/write on copper, read-only on serdes */
340 - if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
365 + } else {
341 366 err = ENOTSUP;
342 367 break;
343 - } else {
368 + }
369 + case MAC_PROP_EN_100FDX_CAP:
370 + if (hw->phy.media_type == ixgbe_media_type_copper &&
371 + speeds & IXGBE_LINK_SPEED_100_FULL) {
344 372 ixgbe->param_en_100fdx_cap = *(uint8_t *)pr_val;
345 - ixgbe->param_adv_100fdx_cap = *(uint8_t *)pr_val;
346 373 goto setup_link;
374 + } else {
375 + err = ENOTSUP;
376 + break;
347 377 }
348 378 case MAC_PROP_AUTONEG:
349 - /* read/write on copper, read-only on serdes */
350 379 if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
351 380 err = ENOTSUP;
352 381 break;
353 382 } else {
354 383 ixgbe->param_adv_autoneg_cap = *(uint8_t *)pr_val;
355 384 goto setup_link;
356 385 }
357 386 case MAC_PROP_FLOWCTRL:
358 387 bcopy(pr_val, &flow_control, sizeof (flow_control));
359 388
360 389 switch (flow_control) {
361 390 default:
362 391 err = EINVAL;
363 392 break;
364 393 case LINK_FLOWCTRL_NONE:
365 394 hw->fc.requested_mode = ixgbe_fc_none;
366 395 break;
367 396 case LINK_FLOWCTRL_RX:
368 397 hw->fc.requested_mode = ixgbe_fc_rx_pause;
369 398 break;
370 399 case LINK_FLOWCTRL_TX:
371 400 hw->fc.requested_mode = ixgbe_fc_tx_pause;
372 401 break;
373 402 case LINK_FLOWCTRL_BI:
374 403 hw->fc.requested_mode = ixgbe_fc_full;
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
375 404 break;
376 405 }
377 406 setup_link:
378 407 if (err == 0) {
379 408 if (ixgbe_driver_setup_link(ixgbe, B_TRUE) !=
380 409 IXGBE_SUCCESS)
381 410 err = EINVAL;
382 411 }
383 412 break;
384 413 case MAC_PROP_ADV_10GFDX_CAP:
414 + case MAC_PROP_ADV_5000FDX_CAP:
415 + case MAC_PROP_ADV_2500FDX_CAP:
385 416 case MAC_PROP_ADV_1000FDX_CAP:
386 417 case MAC_PROP_ADV_100FDX_CAP:
387 418 case MAC_PROP_STATUS:
388 419 case MAC_PROP_SPEED:
389 420 case MAC_PROP_DUPLEX:
390 421 err = ENOTSUP; /* read-only prop. Can't set this. */
391 422 break;
392 423 case MAC_PROP_MTU:
393 424 cur_mtu = ixgbe->default_mtu;
394 425 bcopy(pr_val, &new_mtu, sizeof (new_mtu));
395 426 if (new_mtu == cur_mtu) {
396 427 err = 0;
397 428 break;
398 429 }
399 430
400 431 if (new_mtu < DEFAULT_MTU || new_mtu > ixgbe->capab->max_mtu) {
401 432 err = EINVAL;
402 433 break;
403 434 }
404 435
405 436 if (ixgbe->ixgbe_state & IXGBE_STARTED) {
406 437 err = EBUSY;
407 438 break;
408 439 }
409 440
410 441 err = mac_maxsdu_update(ixgbe->mac_hdl, new_mtu);
411 442 if (err == 0) {
412 443 ixgbe->default_mtu = new_mtu;
413 444 ixgbe->max_frame_size = ixgbe->default_mtu +
414 445 sizeof (struct ether_vlan_header) + ETHERFCSL;
415 446
416 447 /*
417 448 * Set rx buffer size
418 449 */
419 450 rx_size = ixgbe->max_frame_size + IPHDR_ALIGN_ROOM;
420 451 ixgbe->rx_buf_size = ((rx_size >> 10) + ((rx_size &
421 452 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
422 453
423 454 /*
424 455 * Set tx buffer size
425 456 */
426 457 tx_size = ixgbe->max_frame_size;
427 458 ixgbe->tx_buf_size = ((tx_size >> 10) + ((tx_size &
428 459 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
429 460 }
430 461 break;
431 462 case MAC_PROP_PRIVATE:
432 463 err = ixgbe_set_priv_prop(ixgbe, pr_name, pr_valsize, pr_val);
433 464 break;
434 465 default:
435 466 err = ENOTSUP;
436 467 break;
437 468 }
438 469 mutex_exit(&ixgbe->gen_lock);
439 470 return (err);
440 471 }
↓ open down ↓ |
46 lines elided |
↑ open up ↑ |
441 472
442 473 int
443 474 ixgbe_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
444 475 uint_t pr_valsize, void *pr_val)
445 476 {
446 477 ixgbe_t *ixgbe = (ixgbe_t *)arg;
447 478 struct ixgbe_hw *hw = &ixgbe->hw;
448 479 int err = 0;
449 480 uint32_t flow_control;
450 481 uint64_t tmp = 0;
482 + ixgbe_link_speed speeds = 0;
451 483
484 + /*
485 + * We cannot always rely on the common code maintaining
486 + * hw->phy.speeds_supported, therefore we fall back to use the recorded
487 + * supported speeds which were obtained during instance init in
488 + * ixgbe_init_params().
489 + */
490 + speeds = hw->phy.speeds_supported;
491 + if (speeds == 0)
492 + speeds = ixgbe->speeds_supported;
493 +
452 494 switch (pr_num) {
453 495 case MAC_PROP_DUPLEX:
454 496 ASSERT(pr_valsize >= sizeof (link_duplex_t));
455 497 bcopy(&ixgbe->link_duplex, pr_val,
456 498 sizeof (link_duplex_t));
457 499 break;
458 500 case MAC_PROP_SPEED:
459 501 ASSERT(pr_valsize >= sizeof (uint64_t));
460 502 tmp = ixgbe->link_speed * 1000000ull;
461 503 bcopy(&tmp, pr_val, sizeof (tmp));
462 504 break;
463 505 case MAC_PROP_AUTONEG:
464 506 *(uint8_t *)pr_val = ixgbe->param_adv_autoneg_cap;
465 507 break;
466 508 case MAC_PROP_FLOWCTRL:
467 509 ASSERT(pr_valsize >= sizeof (uint32_t));
468 510
469 511 switch (hw->fc.requested_mode) {
470 512 case ixgbe_fc_none:
471 513 flow_control = LINK_FLOWCTRL_NONE;
472 514 break;
473 515 case ixgbe_fc_rx_pause:
474 516 flow_control = LINK_FLOWCTRL_RX;
475 517 break;
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
476 518 case ixgbe_fc_tx_pause:
477 519 flow_control = LINK_FLOWCTRL_TX;
478 520 break;
479 521 case ixgbe_fc_full:
480 522 flow_control = LINK_FLOWCTRL_BI;
481 523 break;
482 524 }
483 525 bcopy(&flow_control, pr_val, sizeof (flow_control));
484 526 break;
485 527 case MAC_PROP_ADV_10GFDX_CAP:
486 - *(uint8_t *)pr_val = ixgbe->param_adv_10000fdx_cap;
528 + if (speeds & IXGBE_LINK_SPEED_10GB_FULL)
529 + *(uint8_t *)pr_val = ixgbe->param_adv_10000fdx_cap;
530 + else
531 + err = ENOTSUP;
487 532 break;
488 533 case MAC_PROP_EN_10GFDX_CAP:
489 - *(uint8_t *)pr_val = ixgbe->param_en_10000fdx_cap;
534 + if (speeds & IXGBE_LINK_SPEED_10GB_FULL)
535 + *(uint8_t *)pr_val = ixgbe->param_en_10000fdx_cap;
536 + else
537 + err = ENOTSUP;
490 538 break;
539 + case MAC_PROP_ADV_5000FDX_CAP:
540 + if (speeds & IXGBE_LINK_SPEED_5GB_FULL)
541 + *(uint8_t *)pr_val = ixgbe->param_adv_5000fdx_cap;
542 + else
543 + err = ENOTSUP;
544 + break;
545 + case MAC_PROP_EN_5000FDX_CAP:
546 + if (speeds & IXGBE_LINK_SPEED_5GB_FULL)
547 + *(uint8_t *)pr_val = ixgbe->param_en_5000fdx_cap;
548 + else
549 + err = ENOTSUP;
550 + break;
551 + case MAC_PROP_ADV_2500FDX_CAP:
552 + if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL)
553 + *(uint8_t *)pr_val = ixgbe->param_adv_2500fdx_cap;
554 + else
555 + err = ENOTSUP;
556 + break;
557 + case MAC_PROP_EN_2500FDX_CAP:
558 + if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL)
559 + *(uint8_t *)pr_val = ixgbe->param_en_2500fdx_cap;
560 + else
561 + err = ENOTSUP;
562 + break;
491 563 case MAC_PROP_ADV_1000FDX_CAP:
492 - *(uint8_t *)pr_val = ixgbe->param_adv_1000fdx_cap;
564 + if (speeds & IXGBE_LINK_SPEED_1GB_FULL)
565 + *(uint8_t *)pr_val = ixgbe->param_adv_1000fdx_cap;
566 + else
567 + err = ENOTSUP;
493 568 break;
494 569 case MAC_PROP_EN_1000FDX_CAP:
495 - *(uint8_t *)pr_val = ixgbe->param_en_1000fdx_cap;
570 + if (speeds & IXGBE_LINK_SPEED_1GB_FULL)
571 + *(uint8_t *)pr_val = ixgbe->param_en_1000fdx_cap;
572 + else
573 + err = ENOTSUP;
496 574 break;
497 575 case MAC_PROP_ADV_100FDX_CAP:
498 - *(uint8_t *)pr_val = ixgbe->param_adv_100fdx_cap;
576 + if (speeds & IXGBE_LINK_SPEED_100_FULL)
577 + *(uint8_t *)pr_val = ixgbe->param_adv_100fdx_cap;
578 + else
579 + err = ENOTSUP;
499 580 break;
500 581 case MAC_PROP_EN_100FDX_CAP:
501 - *(uint8_t *)pr_val = ixgbe->param_en_100fdx_cap;
582 + if (speeds & IXGBE_LINK_SPEED_100_FULL)
583 + *(uint8_t *)pr_val = ixgbe->param_en_100fdx_cap;
584 + else
585 + err = ENOTSUP;
502 586 break;
503 587 case MAC_PROP_PRIVATE:
504 588 err = ixgbe_get_priv_prop(ixgbe, pr_name,
505 589 pr_valsize, pr_val);
506 590 break;
507 591 default:
508 592 err = ENOTSUP;
509 593 break;
510 594 }
511 595 return (err);
512 596 }
513 597
514 598 void
515 599 ixgbe_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
516 600 mac_prop_info_handle_t prh)
517 601 {
518 602 ixgbe_t *ixgbe = (ixgbe_t *)arg;
603 + struct ixgbe_hw *hw = &ixgbe->hw;
519 604 uint_t perm;
605 + uint8_t value;
606 + ixgbe_link_speed speeds = 0;
520 607
608 + /*
609 + * We cannot always rely on the common code maintaining
610 + * hw->phy.speeds_supported, therefore we fall back to use the
611 + * recorded supported speeds which were obtained during instance init in
612 + * ixgbe_init_params().
613 + */
614 + speeds = hw->phy.speeds_supported;
615 + if (speeds == 0)
616 + speeds = ixgbe->speeds_supported;
617 +
521 618 switch (pr_num) {
522 619 case MAC_PROP_DUPLEX:
523 620 case MAC_PROP_SPEED:
524 621 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
525 622 break;
526 623
527 624 case MAC_PROP_ADV_100FDX_CAP:
625 + mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
626 + value = (speeds & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0;
627 + mac_prop_info_set_default_uint8(prh, value);
628 + break;
629 +
528 630 case MAC_PROP_ADV_1000FDX_CAP:
631 + mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
632 + value = (speeds & IXGBE_LINK_SPEED_1GB_FULL) ? 1 : 0;
633 + mac_prop_info_set_default_uint8(prh, value);
634 + break;
635 +
636 + case MAC_PROP_ADV_2500FDX_CAP:
637 + mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
638 + value = (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) ? 1 : 0;
639 + mac_prop_info_set_default_uint8(prh, value);
640 + break;
641 +
642 + case MAC_PROP_ADV_5000FDX_CAP:
643 + mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
644 + value = (speeds & IXGBE_LINK_SPEED_5GB_FULL) ? 1 : 0;
645 + mac_prop_info_set_default_uint8(prh, value);
646 + break;
647 +
529 648 case MAC_PROP_ADV_10GFDX_CAP:
530 649 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
531 - mac_prop_info_set_default_uint8(prh, 1);
650 + value = (speeds & IXGBE_LINK_SPEED_10GB_FULL) ? 1 : 0;
651 + mac_prop_info_set_default_uint8(prh, value);
532 652 break;
533 653
654 + /*
655 + * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked
656 + * read-only on non-baseT (SFP) PHYs.
657 + */
534 658 case MAC_PROP_AUTONEG:
535 - case MAC_PROP_EN_10GFDX_CAP:
536 - case MAC_PROP_EN_1000FDX_CAP:
537 - case MAC_PROP_EN_100FDX_CAP:
538 - perm = (ixgbe->hw.phy.media_type == ixgbe_media_type_copper) ?
659 + perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
539 660 MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
540 661 mac_prop_info_set_perm(prh, perm);
541 662 mac_prop_info_set_default_uint8(prh, 1);
542 663 break;
543 664
665 + case MAC_PROP_EN_10GFDX_CAP:
666 + if (speeds & IXGBE_LINK_SPEED_10GB_FULL) {
667 + perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
668 + MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
669 + mac_prop_info_set_perm(prh, perm);
670 + mac_prop_info_set_default_uint8(prh, 1);
671 + }
672 + break;
673 +
674 + case MAC_PROP_EN_5000FDX_CAP:
675 + if (speeds & IXGBE_LINK_SPEED_5GB_FULL) {
676 + perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
677 + MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
678 + mac_prop_info_set_perm(prh, perm);
679 + mac_prop_info_set_default_uint8(prh, 1);
680 + }
681 + break;
682 +
683 + case MAC_PROP_EN_2500FDX_CAP:
684 + if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) {
685 + perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
686 + MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
687 + mac_prop_info_set_perm(prh, perm);
688 + mac_prop_info_set_default_uint8(prh, 1);
689 + }
690 + break;
691 +
692 + case MAC_PROP_EN_1000FDX_CAP:
693 + if (speeds & IXGBE_LINK_SPEED_1GB_FULL) {
694 + perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
695 + MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
696 + mac_prop_info_set_perm(prh, perm);
697 + mac_prop_info_set_default_uint8(prh, 1);
698 + }
699 + break;
700 +
701 + case MAC_PROP_EN_100FDX_CAP:
702 + if (speeds & IXGBE_LINK_SPEED_100_FULL) {
703 + perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
704 + MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
705 + mac_prop_info_set_perm(prh, perm);
706 + mac_prop_info_set_default_uint8(prh, 1);
707 + }
708 + break;
709 +
544 710 case MAC_PROP_FLOWCTRL:
545 711 mac_prop_info_set_default_link_flowctrl(prh,
546 712 LINK_FLOWCTRL_NONE);
547 713 break;
548 714
549 715 case MAC_PROP_MTU:
550 716 mac_prop_info_set_range_uint32(prh,
551 717 DEFAULT_MTU, ixgbe->capab->max_mtu);
552 718 break;
553 719
554 720 case MAC_PROP_PRIVATE: {
555 721 char valstr[64];
556 722 int value;
557 723
558 724 bzero(valstr, sizeof (valstr));
559 725
560 726 if (strcmp(pr_name, "_adv_pause_cap") == 0 ||
561 727 strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
562 728 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
563 729 return;
564 730 }
565 731
566 732 if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
567 733 value = DEFAULT_TX_COPY_THRESHOLD;
568 734 } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
569 735 value = DEFAULT_TX_RECYCLE_THRESHOLD;
570 736 } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
571 737 value = DEFAULT_TX_OVERLOAD_THRESHOLD;
572 738 } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
573 739 value = DEFAULT_TX_RESCHED_THRESHOLD;
574 740 } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
575 741 value = DEFAULT_RX_COPY_THRESHOLD;
576 742 } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
577 743 value = DEFAULT_RX_LIMIT_PER_INTR;
578 744 } if (strcmp(pr_name, "_intr_throttling") == 0) {
579 745 value = ixgbe->capab->def_intr_throttle;
580 746 } else {
581 747 return;
582 748 }
583 749
584 750 (void) snprintf(valstr, sizeof (valstr), "%x", value);
585 751 }
586 752 }
587 753 }
↓ open down ↓ |
34 lines elided |
↑ open up ↑ |
588 754
589 755 boolean_t
590 756 ixgbe_param_locked(mac_prop_id_t pr_num)
591 757 {
592 758 /*
593 759 * All en_* parameters are locked (read-only) while
594 760 * the device is in any sort of loopback mode ...
595 761 */
596 762 switch (pr_num) {
597 763 case MAC_PROP_EN_10GFDX_CAP:
764 + case MAC_PROP_EN_5000FDX_CAP:
765 + case MAC_PROP_EN_2500FDX_CAP:
598 766 case MAC_PROP_EN_1000FDX_CAP:
599 767 case MAC_PROP_EN_100FDX_CAP:
600 768 case MAC_PROP_AUTONEG:
601 769 case MAC_PROP_FLOWCTRL:
602 770 return (B_TRUE);
603 771 }
604 772 return (B_FALSE);
605 773 }
606 774
607 775 /* ARGSUSED */
608 776 int
609 777 ixgbe_set_priv_prop(ixgbe_t *ixgbe, const char *pr_name,
610 778 uint_t pr_valsize, const void *pr_val)
611 779 {
612 780 int err = 0;
613 781 long result;
614 782 struct ixgbe_hw *hw = &ixgbe->hw;
615 783 int i;
616 784
617 785 if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
618 786 if (pr_val == NULL) {
619 787 err = EINVAL;
620 788 return (err);
621 789 }
622 790 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
623 791 if (result < MIN_TX_COPY_THRESHOLD ||
624 792 result > MAX_TX_COPY_THRESHOLD)
625 793 err = EINVAL;
626 794 else {
627 795 ixgbe->tx_copy_thresh = (uint32_t)result;
628 796 }
629 797 return (err);
630 798 }
631 799 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
632 800 if (pr_val == NULL) {
633 801 err = EINVAL;
634 802 return (err);
635 803 }
636 804 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
637 805 if (result < MIN_TX_RECYCLE_THRESHOLD ||
638 806 result > MAX_TX_RECYCLE_THRESHOLD)
639 807 err = EINVAL;
640 808 else {
641 809 ixgbe->tx_recycle_thresh = (uint32_t)result;
642 810 }
643 811 return (err);
644 812 }
645 813 if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
646 814 if (pr_val == NULL) {
647 815 err = EINVAL;
648 816 return (err);
649 817 }
650 818 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
651 819 if (result < MIN_TX_OVERLOAD_THRESHOLD ||
652 820 result > MAX_TX_OVERLOAD_THRESHOLD)
653 821 err = EINVAL;
654 822 else {
655 823 ixgbe->tx_overload_thresh = (uint32_t)result;
656 824 }
657 825 return (err);
658 826 }
659 827 if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
660 828 if (pr_val == NULL) {
661 829 err = EINVAL;
662 830 return (err);
663 831 }
664 832 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
665 833 if (result < MIN_TX_RESCHED_THRESHOLD ||
666 834 result > MAX_TX_RESCHED_THRESHOLD)
667 835 err = EINVAL;
668 836 else {
669 837 ixgbe->tx_resched_thresh = (uint32_t)result;
670 838 }
671 839 return (err);
672 840 }
673 841 if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
674 842 if (pr_val == NULL) {
675 843 err = EINVAL;
676 844 return (err);
677 845 }
678 846 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
679 847 if (result < MIN_RX_COPY_THRESHOLD ||
680 848 result > MAX_RX_COPY_THRESHOLD)
681 849 err = EINVAL;
682 850 else {
683 851 ixgbe->rx_copy_thresh = (uint32_t)result;
684 852 }
685 853 return (err);
686 854 }
687 855 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
688 856 if (pr_val == NULL) {
689 857 err = EINVAL;
690 858 return (err);
691 859 }
692 860 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
693 861 if (result < MIN_RX_LIMIT_PER_INTR ||
694 862 result > MAX_RX_LIMIT_PER_INTR)
695 863 err = EINVAL;
696 864 else {
697 865 ixgbe->rx_limit_per_intr = (uint32_t)result;
698 866 }
699 867 return (err);
700 868 }
701 869 if (strcmp(pr_name, "_intr_throttling") == 0) {
702 870 if (pr_val == NULL) {
703 871 err = EINVAL;
704 872 return (err);
↓ open down ↓ |
97 lines elided |
↑ open up ↑ |
705 873 }
706 874 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
707 875
708 876 if (result < ixgbe->capab->min_intr_throttle ||
709 877 result > ixgbe->capab->max_intr_throttle)
710 878 err = EINVAL;
711 879 else {
712 880 ixgbe->intr_throttling[0] = (uint32_t)result;
713 881
714 882 /*
715 - * 82599 and X540 require the interrupt throttling
883 + * 82599, X540 and X550 require the interrupt throttling
716 884 * rate is a multiple of 8. This is enforced by the
717 885 * register definiton.
718 886 */
719 887 if (hw->mac.type == ixgbe_mac_82599EB ||
720 - hw->mac.type == ixgbe_mac_X540) {
888 + hw->mac.type == ixgbe_mac_X540 ||
889 + hw->mac.type == ixgbe_mac_X550 ||
890 + hw->mac.type == ixgbe_mac_X550EM_x) {
721 891 ixgbe->intr_throttling[0] =
722 892 ixgbe->intr_throttling[0] & 0xFF8;
723 893 }
724 894
725 895 for (i = 0; i < MAX_INTR_VECTOR; i++)
726 896 ixgbe->intr_throttling[i] =
727 897 ixgbe->intr_throttling[0];
728 898
729 899 /* Set interrupt throttling rate */
730 900 for (i = 0; i < ixgbe->intr_cnt; i++)
731 901 IXGBE_WRITE_REG(hw, IXGBE_EITR(i),
732 902 ixgbe->intr_throttling[i]);
733 903 }
734 904 return (err);
735 905 }
736 906 return (ENOTSUP);
737 907 }
738 908
739 909 int
740 910 ixgbe_get_priv_prop(ixgbe_t *ixgbe, const char *pr_name,
741 911 uint_t pr_valsize, void *pr_val)
742 912 {
743 913 int err = ENOTSUP;
744 914 int value;
745 915
746 916 if (strcmp(pr_name, "_adv_pause_cap") == 0) {
747 917 value = ixgbe->param_adv_pause_cap;
748 918 err = 0;
749 919 goto done;
750 920 }
751 921 if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
752 922 value = ixgbe->param_adv_asym_pause_cap;
753 923 err = 0;
754 924 goto done;
755 925 }
756 926 if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
757 927 value = ixgbe->tx_copy_thresh;
758 928 err = 0;
759 929 goto done;
760 930 }
761 931 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
762 932 value = ixgbe->tx_recycle_thresh;
763 933 err = 0;
764 934 goto done;
765 935 }
766 936 if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
767 937 value = ixgbe->tx_overload_thresh;
768 938 err = 0;
769 939 goto done;
770 940 }
771 941 if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
772 942 value = ixgbe->tx_resched_thresh;
773 943 err = 0;
774 944 goto done;
775 945 }
776 946 if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
777 947 value = ixgbe->rx_copy_thresh;
778 948 err = 0;
779 949 goto done;
780 950 }
781 951 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
782 952 value = ixgbe->rx_limit_per_intr;
783 953 err = 0;
784 954 goto done;
785 955 }
786 956 if (strcmp(pr_name, "_intr_throttling") == 0) {
787 957 value = ixgbe->intr_throttling[0];
788 958 err = 0;
789 959 goto done;
790 960 }
791 961 done:
792 962 if (err == 0) {
793 963 (void) snprintf(pr_val, pr_valsize, "%d", value);
794 964 }
795 965 return (err);
796 966 }
↓ open down ↓ |
66 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX