Print this page
4431 igb support for I354
4616 igb has uninitialized kstats
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/igb/igb_gld.c
+++ new/usr/src/uts/common/io/igb/igb_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 *
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
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 2013, Nexenta Systems, Inc. All rights reserved.
29 + * Copyright 2014 Pluribus Networks Inc.
29 30 */
30 31
31 32 #include "igb_sw.h"
32 33
33 34 int
34 35 igb_m_stat(void *arg, uint_t stat, uint64_t *val)
35 36 {
36 37 igb_t *igb = (igb_t *)arg;
37 38 struct e1000_hw *hw = &igb->hw;
38 39 igb_stat_t *igb_ks;
39 40 uint32_t low_val, high_val;
40 41
41 42 igb_ks = (igb_stat_t *)igb->igb_ks->ks_data;
42 43
43 44 mutex_enter(&igb->gen_lock);
44 45
45 46 if (igb->igb_state & IGB_SUSPENDED) {
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
46 47 mutex_exit(&igb->gen_lock);
47 48 return (ECANCELED);
48 49 }
49 50
50 51 switch (stat) {
51 52 case MAC_STAT_IFSPEED:
52 53 *val = igb->link_speed * 1000000ull;
53 54 break;
54 55
55 56 case MAC_STAT_MULTIRCV:
56 - igb_ks->mprc.value.ui64 +=
57 - E1000_READ_REG(hw, E1000_MPRC);
58 - *val = igb_ks->mprc.value.ui64;
57 + igb->stat_mprc += E1000_READ_REG(hw, E1000_MPRC);
58 + *val = igb->stat_mprc;
59 59 break;
60 60
61 61 case MAC_STAT_BRDCSTRCV:
62 - igb_ks->bprc.value.ui64 +=
63 - E1000_READ_REG(hw, E1000_BPRC);
64 - *val = igb_ks->bprc.value.ui64;
62 + igb->stat_bprc += E1000_READ_REG(hw, E1000_BPRC);
63 + *val = igb->stat_bprc;
65 64 break;
66 65
67 66 case MAC_STAT_MULTIXMT:
68 - igb_ks->mptc.value.ui64 +=
69 - E1000_READ_REG(hw, E1000_MPTC);
70 - *val = igb_ks->mptc.value.ui64;
67 + igb->stat_mptc += E1000_READ_REG(hw, E1000_MPTC);
68 + *val = igb->stat_mptc;
71 69 break;
72 70
73 71 case MAC_STAT_BRDCSTXMT:
74 - igb_ks->bptc.value.ui64 +=
75 - E1000_READ_REG(hw, E1000_BPTC);
76 - *val = igb_ks->bptc.value.ui64;
72 + igb->stat_bptc += E1000_READ_REG(hw, E1000_BPTC);
73 + *val = igb->stat_bptc;
77 74 break;
78 75
79 76 case MAC_STAT_NORCVBUF:
80 - igb_ks->rnbc.value.ui64 +=
81 - E1000_READ_REG(hw, E1000_RNBC);
82 - *val = igb_ks->rnbc.value.ui64;
77 + igb->stat_rnbc += E1000_READ_REG(hw, E1000_RNBC);
78 + *val = igb->stat_rnbc;
83 79 break;
84 80
85 81 case MAC_STAT_IERRORS:
86 - igb_ks->rxerrc.value.ui64 +=
87 - E1000_READ_REG(hw, E1000_RXERRC);
88 - igb_ks->algnerrc.value.ui64 +=
89 - E1000_READ_REG(hw, E1000_ALGNERRC);
82 + igb->stat_rxerrc += E1000_READ_REG(hw, E1000_RXERRC);
83 + igb->stat_algnerrc += E1000_READ_REG(hw, E1000_ALGNERRC);
90 84 igb_ks->rlec.value.ui64 +=
91 85 E1000_READ_REG(hw, E1000_RLEC);
92 - igb_ks->crcerrs.value.ui64 +=
93 - E1000_READ_REG(hw, E1000_CRCERRS);
94 - igb_ks->cexterr.value.ui64 +=
95 - E1000_READ_REG(hw, E1000_CEXTERR);
96 - *val = igb_ks->rxerrc.value.ui64 +
97 - igb_ks->algnerrc.value.ui64 +
86 + igb->stat_crcerrs += E1000_READ_REG(hw, E1000_CRCERRS);
87 + igb->stat_cexterr += E1000_READ_REG(hw, E1000_CEXTERR);
88 + *val = igb->stat_rxerrc +
89 + igb->stat_algnerrc +
98 90 igb_ks->rlec.value.ui64 +
99 - igb_ks->crcerrs.value.ui64 +
100 - igb_ks->cexterr.value.ui64;
91 + igb->stat_crcerrs +
92 + igb->stat_cexterr;
101 93 break;
102 94
103 95 case MAC_STAT_NOXMTBUF:
104 96 *val = 0;
105 97 break;
106 98
107 99 case MAC_STAT_OERRORS:
108 - igb_ks->ecol.value.ui64 +=
109 - E1000_READ_REG(hw, E1000_ECOL);
110 - *val = igb_ks->ecol.value.ui64;
100 + igb->stat_ecol += E1000_READ_REG(hw, E1000_ECOL);
101 + *val = igb->stat_ecol;
111 102 break;
112 103
113 104 case MAC_STAT_COLLISIONS:
114 - igb_ks->colc.value.ui64 +=
115 - E1000_READ_REG(hw, E1000_COLC);
116 - *val = igb_ks->colc.value.ui64;
105 + igb->stat_colc += E1000_READ_REG(hw, E1000_COLC);
106 + *val = igb->stat_colc;
117 107 break;
118 108
119 109 case MAC_STAT_RBYTES:
120 110 /*
121 111 * The 64-bit register will reset whenever the upper
122 112 * 32 bits are read. So we need to read the lower
123 113 * 32 bits first, then read the upper 32 bits.
124 114 */
125 115 low_val = E1000_READ_REG(hw, E1000_TORL);
126 116 high_val = E1000_READ_REG(hw, E1000_TORH);
127 - igb_ks->tor.value.ui64 +=
128 - (uint64_t)high_val << 32 | (uint64_t)low_val;
129 - *val = igb_ks->tor.value.ui64;
117 + igb->stat_tor += (uint64_t)high_val << 32 | (uint64_t)low_val;
118 + *val = igb->stat_tor;
130 119 break;
131 120
132 121 case MAC_STAT_IPACKETS:
133 - igb_ks->tpr.value.ui64 +=
134 - E1000_READ_REG(hw, E1000_TPR);
135 - *val = igb_ks->tpr.value.ui64;
122 + igb->stat_tpr += E1000_READ_REG(hw, E1000_TPR);
123 + *val = igb->stat_tpr;
136 124 break;
137 125
138 126 case MAC_STAT_OBYTES:
139 127 /*
140 128 * The 64-bit register will reset whenever the upper
141 129 * 32 bits are read. So we need to read the lower
142 130 * 32 bits first, then read the upper 32 bits.
143 131 */
144 132 low_val = E1000_READ_REG(hw, E1000_TOTL);
145 133 high_val = E1000_READ_REG(hw, E1000_TOTH);
146 - igb_ks->tot.value.ui64 +=
147 - (uint64_t)high_val << 32 | (uint64_t)low_val;
148 - *val = igb_ks->tot.value.ui64;
134 + igb->stat_tot += (uint64_t)high_val << 32 | (uint64_t)low_val;
135 + *val = igb->stat_tot;
149 136 break;
150 137
151 138 case MAC_STAT_OPACKETS:
152 - igb_ks->tpt.value.ui64 +=
153 - E1000_READ_REG(hw, E1000_TPT);
154 - *val = igb_ks->tpt.value.ui64;
139 + igb->stat_tpt += E1000_READ_REG(hw, E1000_TPT);
140 + *val = igb->stat_tpt;
155 141 break;
156 142
157 143 /* RFC 1643 stats */
158 144 case ETHER_STAT_ALIGN_ERRORS:
159 - igb_ks->algnerrc.value.ui64 +=
160 - E1000_READ_REG(hw, E1000_ALGNERRC);
161 - *val = igb_ks->algnerrc.value.ui64;
145 + igb->stat_algnerrc += E1000_READ_REG(hw, E1000_ALGNERRC);
146 + *val = igb->stat_algnerrc;
162 147 break;
163 148
164 149 case ETHER_STAT_FCS_ERRORS:
165 - igb_ks->crcerrs.value.ui64 +=
166 - E1000_READ_REG(hw, E1000_CRCERRS);
167 - *val = igb_ks->crcerrs.value.ui64;
150 + igb->stat_crcerrs += E1000_READ_REG(hw, E1000_CRCERRS);
151 + *val = igb->stat_crcerrs;
168 152 break;
169 153
170 154 case ETHER_STAT_FIRST_COLLISIONS:
171 - igb_ks->scc.value.ui64 +=
172 - E1000_READ_REG(hw, E1000_SCC);
173 - *val = igb_ks->scc.value.ui64;
155 + igb->stat_scc += E1000_READ_REG(hw, E1000_SCC);
156 + *val = igb->stat_scc;
174 157 break;
175 158
176 159 case ETHER_STAT_MULTI_COLLISIONS:
177 - igb_ks->mcc.value.ui64 +=
178 - E1000_READ_REG(hw, E1000_MCC);
179 - *val = igb_ks->mcc.value.ui64;
160 + igb->stat_mcc += E1000_READ_REG(hw, E1000_MCC);
161 + *val = igb->stat_mcc;
180 162 break;
181 163
182 164 case ETHER_STAT_SQE_ERRORS:
183 - igb_ks->sec.value.ui64 +=
184 - E1000_READ_REG(hw, E1000_SEC);
185 - *val = igb_ks->sec.value.ui64;
165 + igb->stat_sec += E1000_READ_REG(hw, E1000_SEC);
166 + *val = igb->stat_sec;
186 167 break;
187 168
188 169 case ETHER_STAT_DEFER_XMTS:
189 - igb_ks->dc.value.ui64 +=
190 - E1000_READ_REG(hw, E1000_DC);
191 - *val = igb_ks->dc.value.ui64;
170 + igb->stat_dc += E1000_READ_REG(hw, E1000_DC);
171 + *val = igb->stat_dc;
192 172 break;
193 173
194 174 case ETHER_STAT_TX_LATE_COLLISIONS:
195 - igb_ks->latecol.value.ui64 +=
196 - E1000_READ_REG(hw, E1000_LATECOL);
197 - *val = igb_ks->latecol.value.ui64;
175 + igb->stat_latecol += E1000_READ_REG(hw, E1000_LATECOL);
176 + *val = igb->stat_latecol;
198 177 break;
199 178
200 179 case ETHER_STAT_EX_COLLISIONS:
201 - igb_ks->ecol.value.ui64 +=
202 - E1000_READ_REG(hw, E1000_ECOL);
203 - *val = igb_ks->ecol.value.ui64;
180 + igb->stat_ecol += E1000_READ_REG(hw, E1000_ECOL);
181 + *val = igb->stat_ecol;
204 182 break;
205 183
206 184 case ETHER_STAT_MACXMT_ERRORS:
207 - igb_ks->ecol.value.ui64 +=
208 - E1000_READ_REG(hw, E1000_ECOL);
209 - *val = igb_ks->ecol.value.ui64;
185 + igb->stat_ecol += E1000_READ_REG(hw, E1000_ECOL);
186 + *val = igb->stat_ecol;
210 187 break;
211 188
212 189 case ETHER_STAT_CARRIER_ERRORS:
213 - igb_ks->cexterr.value.ui64 +=
214 - E1000_READ_REG(hw, E1000_CEXTERR);
215 - *val = igb_ks->cexterr.value.ui64;
190 + igb->stat_cexterr += E1000_READ_REG(hw, E1000_CEXTERR);
191 + *val = igb->stat_cexterr;
216 192 break;
217 193
218 194 case ETHER_STAT_TOOLONG_ERRORS:
219 - igb_ks->roc.value.ui64 +=
220 - E1000_READ_REG(hw, E1000_ROC);
221 - *val = igb_ks->roc.value.ui64;
195 + igb->stat_roc += E1000_READ_REG(hw, E1000_ROC);
196 + *val = igb->stat_roc;
222 197 break;
223 198
224 199 case ETHER_STAT_MACRCV_ERRORS:
225 - igb_ks->rxerrc.value.ui64 +=
226 - E1000_READ_REG(hw, E1000_RXERRC);
227 - *val = igb_ks->rxerrc.value.ui64;
200 + igb->stat_rxerrc += E1000_READ_REG(hw, E1000_RXERRC);
201 + *val = igb->stat_rxerrc;
228 202 break;
229 203
230 204 /* MII/GMII stats */
231 205 case ETHER_STAT_XCVR_ADDR:
232 206 /* The Internal PHY's MDI address for each MAC is 1 */
233 207 *val = 1;
234 208 break;
235 209
236 210 case ETHER_STAT_XCVR_ID:
237 211 *val = hw->phy.id | hw->phy.revision;
238 212 break;
239 213
240 214 case ETHER_STAT_XCVR_INUSE:
241 215 switch (igb->link_speed) {
242 216 case SPEED_1000:
243 217 *val =
244 218 (hw->phy.media_type == e1000_media_type_copper) ?
245 219 XCVR_1000T : XCVR_1000X;
246 220 break;
247 221 case SPEED_100:
248 222 *val =
249 223 (hw->phy.media_type == e1000_media_type_copper) ?
250 224 (igb->param_100t4_cap == 1) ?
251 225 XCVR_100T4 : XCVR_100T2 : XCVR_100X;
252 226 break;
253 227 case SPEED_10:
254 228 *val = XCVR_10;
255 229 break;
256 230 default:
257 231 *val = XCVR_NONE;
258 232 break;
259 233 }
260 234 break;
261 235
262 236 case ETHER_STAT_CAP_1000FDX:
263 237 *val = igb->param_1000fdx_cap;
264 238 break;
265 239
266 240 case ETHER_STAT_CAP_1000HDX:
267 241 *val = igb->param_1000hdx_cap;
268 242 break;
269 243
270 244 case ETHER_STAT_CAP_100FDX:
271 245 *val = igb->param_100fdx_cap;
272 246 break;
273 247
274 248 case ETHER_STAT_CAP_100HDX:
275 249 *val = igb->param_100hdx_cap;
276 250 break;
277 251
278 252 case ETHER_STAT_CAP_10FDX:
279 253 *val = igb->param_10fdx_cap;
280 254 break;
281 255
282 256 case ETHER_STAT_CAP_10HDX:
283 257 *val = igb->param_10hdx_cap;
284 258 break;
285 259
286 260 case ETHER_STAT_CAP_ASMPAUSE:
287 261 *val = igb->param_asym_pause_cap;
288 262 break;
289 263
290 264 case ETHER_STAT_CAP_PAUSE:
291 265 *val = igb->param_pause_cap;
292 266 break;
293 267
294 268 case ETHER_STAT_CAP_AUTONEG:
295 269 *val = igb->param_autoneg_cap;
296 270 break;
297 271
298 272 case ETHER_STAT_ADV_CAP_1000FDX:
299 273 *val = igb->param_adv_1000fdx_cap;
300 274 break;
301 275
302 276 case ETHER_STAT_ADV_CAP_1000HDX:
303 277 *val = igb->param_adv_1000hdx_cap;
304 278 break;
305 279
306 280 case ETHER_STAT_ADV_CAP_100FDX:
307 281 *val = igb->param_adv_100fdx_cap;
308 282 break;
309 283
310 284 case ETHER_STAT_ADV_CAP_100HDX:
311 285 *val = igb->param_adv_100hdx_cap;
312 286 break;
313 287
314 288 case ETHER_STAT_ADV_CAP_10FDX:
315 289 *val = igb->param_adv_10fdx_cap;
316 290 break;
317 291
318 292 case ETHER_STAT_ADV_CAP_10HDX:
319 293 *val = igb->param_adv_10hdx_cap;
320 294 break;
321 295
322 296 case ETHER_STAT_ADV_CAP_ASMPAUSE:
323 297 *val = igb->param_adv_asym_pause_cap;
324 298 break;
325 299
326 300 case ETHER_STAT_ADV_CAP_PAUSE:
327 301 *val = igb->param_adv_pause_cap;
328 302 break;
329 303
330 304 case ETHER_STAT_ADV_CAP_AUTONEG:
331 305 *val = hw->mac.autoneg;
332 306 break;
333 307
334 308 case ETHER_STAT_LP_CAP_1000FDX:
335 309 *val = igb->param_lp_1000fdx_cap;
336 310 break;
337 311
338 312 case ETHER_STAT_LP_CAP_1000HDX:
339 313 *val = igb->param_lp_1000hdx_cap;
340 314 break;
341 315
342 316 case ETHER_STAT_LP_CAP_100FDX:
343 317 *val = igb->param_lp_100fdx_cap;
344 318 break;
345 319
346 320 case ETHER_STAT_LP_CAP_100HDX:
347 321 *val = igb->param_lp_100hdx_cap;
348 322 break;
349 323
350 324 case ETHER_STAT_LP_CAP_10FDX:
351 325 *val = igb->param_lp_10fdx_cap;
352 326 break;
353 327
354 328 case ETHER_STAT_LP_CAP_10HDX:
355 329 *val = igb->param_lp_10hdx_cap;
356 330 break;
357 331
358 332 case ETHER_STAT_LP_CAP_ASMPAUSE:
359 333 *val = igb->param_lp_asym_pause_cap;
360 334 break;
361 335
362 336 case ETHER_STAT_LP_CAP_PAUSE:
363 337 *val = igb->param_lp_pause_cap;
364 338 break;
365 339
366 340 case ETHER_STAT_LP_CAP_AUTONEG:
367 341 *val = igb->param_lp_autoneg_cap;
368 342 break;
369 343
370 344 case ETHER_STAT_LINK_ASMPAUSE:
371 345 *val = igb->param_asym_pause_cap;
372 346 break;
373 347
374 348 case ETHER_STAT_LINK_PAUSE:
375 349 *val = igb->param_pause_cap;
376 350 break;
377 351
↓ open down ↓ |
140 lines elided |
↑ open up ↑ |
378 352 case ETHER_STAT_LINK_AUTONEG:
379 353 *val = hw->mac.autoneg;
380 354 break;
381 355
382 356 case ETHER_STAT_LINK_DUPLEX:
383 357 *val = (igb->link_duplex == FULL_DUPLEX) ?
384 358 LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
385 359 break;
386 360
387 361 case ETHER_STAT_TOOSHORT_ERRORS:
388 - igb_ks->ruc.value.ui64 +=
389 - E1000_READ_REG(hw, E1000_RUC);
390 - *val = igb_ks->ruc.value.ui64;
362 + igb->stat_ruc += E1000_READ_REG(hw, E1000_RUC);
363 + *val = igb->stat_ruc;
391 364 break;
392 365
393 366 case ETHER_STAT_CAP_REMFAULT:
394 367 *val = igb->param_rem_fault;
395 368 break;
396 369
397 370 case ETHER_STAT_ADV_REMFAULT:
398 371 *val = igb->param_adv_rem_fault;
399 372 break;
400 373
401 374 case ETHER_STAT_LP_REMFAULT:
402 375 *val = igb->param_lp_rem_fault;
403 376 break;
404 377
405 378 case ETHER_STAT_JABBER_ERRORS:
406 - igb_ks->rjc.value.ui64 +=
407 - E1000_READ_REG(hw, E1000_RJC);
408 - *val = igb_ks->rjc.value.ui64;
379 + igb->stat_rjc += E1000_READ_REG(hw, E1000_RJC);
380 + *val = igb->stat_rjc;
409 381 break;
410 382
411 383 case ETHER_STAT_CAP_100T4:
412 384 *val = igb->param_100t4_cap;
413 385 break;
414 386
415 387 case ETHER_STAT_ADV_CAP_100T4:
416 388 *val = igb->param_adv_100t4_cap;
417 389 break;
418 390
419 391 case ETHER_STAT_LP_CAP_100T4:
420 392 *val = igb->param_lp_100t4_cap;
421 393 break;
422 394
423 395 default:
424 396 mutex_exit(&igb->gen_lock);
425 397 return (ENOTSUP);
426 398 }
427 399
428 400 mutex_exit(&igb->gen_lock);
429 401
430 402 if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) {
431 403 ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED);
432 404 return (EIO);
433 405 }
434 406
435 407 return (0);
436 408 }
437 409
438 410 /*
439 411 * Bring the device out of the reset/quiesced state that it
440 412 * was in when the interface was registered.
441 413 */
442 414 int
443 415 igb_m_start(void *arg)
444 416 {
445 417 igb_t *igb = (igb_t *)arg;
446 418
447 419 mutex_enter(&igb->gen_lock);
448 420
449 421 if (igb->igb_state & IGB_SUSPENDED) {
450 422 mutex_exit(&igb->gen_lock);
451 423 return (ECANCELED);
452 424 }
453 425
454 426 if (igb_start(igb, B_TRUE) != IGB_SUCCESS) {
455 427 mutex_exit(&igb->gen_lock);
456 428 return (EIO);
457 429 }
458 430
459 431 atomic_or_32(&igb->igb_state, IGB_STARTED);
460 432
461 433 mutex_exit(&igb->gen_lock);
462 434
463 435 /*
464 436 * Enable and start the watchdog timer
465 437 */
466 438 igb_enable_watchdog_timer(igb);
467 439
468 440 return (0);
469 441 }
470 442
471 443 /*
472 444 * Stop the device and put it in a reset/quiesced state such
473 445 * that the interface can be unregistered.
474 446 */
475 447 void
476 448 igb_m_stop(void *arg)
477 449 {
478 450 igb_t *igb = (igb_t *)arg;
479 451
480 452 mutex_enter(&igb->gen_lock);
481 453
482 454 if (igb->igb_state & IGB_SUSPENDED) {
483 455 mutex_exit(&igb->gen_lock);
484 456 return;
485 457 }
486 458
487 459 atomic_and_32(&igb->igb_state, ~IGB_STARTED);
488 460
489 461 igb_stop(igb, B_TRUE);
490 462
491 463 mutex_exit(&igb->gen_lock);
492 464
493 465 /*
494 466 * Disable and stop the watchdog timer
495 467 */
496 468 igb_disable_watchdog_timer(igb);
497 469 }
498 470
499 471 /*
500 472 * Set the promiscuity of the device.
501 473 */
502 474 int
503 475 igb_m_promisc(void *arg, boolean_t on)
504 476 {
505 477 igb_t *igb = (igb_t *)arg;
506 478 uint32_t reg_val;
507 479
508 480 mutex_enter(&igb->gen_lock);
509 481
510 482 if (igb->igb_state & IGB_SUSPENDED) {
511 483 mutex_exit(&igb->gen_lock);
512 484 return (ECANCELED);
513 485 }
514 486
515 487 reg_val = E1000_READ_REG(&igb->hw, E1000_RCTL);
516 488
517 489 if (on)
518 490 reg_val |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
519 491 else
520 492 reg_val &= (~(E1000_RCTL_UPE | E1000_RCTL_MPE));
521 493
522 494 E1000_WRITE_REG(&igb->hw, E1000_RCTL, reg_val);
523 495
524 496 mutex_exit(&igb->gen_lock);
525 497
526 498 if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) {
527 499 ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED);
528 500 return (EIO);
529 501 }
530 502
531 503 return (0);
532 504 }
533 505
534 506 /*
535 507 * Add/remove the addresses to/from the set of multicast
536 508 * addresses for which the device will receive packets.
537 509 */
538 510 int
539 511 igb_m_multicst(void *arg, boolean_t add, const uint8_t *mcst_addr)
540 512 {
541 513 igb_t *igb = (igb_t *)arg;
542 514 int result;
543 515
544 516 mutex_enter(&igb->gen_lock);
545 517
546 518 if (igb->igb_state & IGB_SUSPENDED) {
547 519 mutex_exit(&igb->gen_lock);
548 520 return (ECANCELED);
549 521 }
550 522
551 523 result = (add) ? igb_multicst_add(igb, mcst_addr)
552 524 : igb_multicst_remove(igb, mcst_addr);
553 525
554 526 mutex_exit(&igb->gen_lock);
555 527
556 528 return (result);
557 529 }
558 530
559 531 /*
560 532 * Pass on M_IOCTL messages passed to the DLD, and support
561 533 * private IOCTLs for debugging and ndd.
562 534 */
563 535 void
564 536 igb_m_ioctl(void *arg, queue_t *q, mblk_t *mp)
565 537 {
566 538 igb_t *igb = (igb_t *)arg;
567 539 struct iocblk *iocp;
568 540 enum ioc_reply status;
569 541
570 542 iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
571 543 iocp->ioc_error = 0;
572 544
573 545 mutex_enter(&igb->gen_lock);
574 546 if (igb->igb_state & IGB_SUSPENDED) {
575 547 mutex_exit(&igb->gen_lock);
576 548 miocnak(q, mp, 0, EINVAL);
577 549 return;
578 550 }
579 551 mutex_exit(&igb->gen_lock);
580 552
581 553 switch (iocp->ioc_cmd) {
582 554 case LB_GET_INFO_SIZE:
583 555 case LB_GET_INFO:
584 556 case LB_GET_MODE:
585 557 case LB_SET_MODE:
586 558 status = igb_loopback_ioctl(igb, iocp, mp);
587 559 break;
588 560
589 561 default:
590 562 status = IOC_INVAL;
591 563 break;
592 564 }
593 565
594 566 /*
595 567 * Decide how to reply
596 568 */
597 569 switch (status) {
598 570 default:
599 571 case IOC_INVAL:
600 572 /*
601 573 * Error, reply with a NAK and EINVAL or the specified error
602 574 */
603 575 miocnak(q, mp, 0, iocp->ioc_error == 0 ?
604 576 EINVAL : iocp->ioc_error);
605 577 break;
606 578
607 579 case IOC_DONE:
608 580 /*
609 581 * OK, reply already sent
610 582 */
611 583 break;
612 584
613 585 case IOC_ACK:
614 586 /*
615 587 * OK, reply with an ACK
616 588 */
617 589 miocack(q, mp, 0, 0);
618 590 break;
619 591
620 592 case IOC_REPLY:
621 593 /*
622 594 * OK, send prepared reply as ACK or NAK
623 595 */
624 596 mp->b_datap->db_type = iocp->ioc_error == 0 ?
625 597 M_IOCACK : M_IOCNAK;
626 598 qreply(q, mp);
627 599 break;
628 600 }
629 601 }
630 602
631 603 /*
632 604 * Add a MAC address to the target RX group.
633 605 */
634 606 static int
635 607 igb_addmac(void *arg, const uint8_t *mac_addr)
636 608 {
637 609 igb_rx_group_t *rx_group = (igb_rx_group_t *)arg;
638 610 igb_t *igb = rx_group->igb;
639 611 struct e1000_hw *hw = &igb->hw;
640 612 int i, slot;
641 613
642 614 mutex_enter(&igb->gen_lock);
643 615
644 616 if (igb->igb_state & IGB_SUSPENDED) {
645 617 mutex_exit(&igb->gen_lock);
646 618 return (ECANCELED);
647 619 }
648 620
649 621 if (igb->unicst_avail == 0) {
650 622 /* no slots available */
651 623 mutex_exit(&igb->gen_lock);
652 624 return (ENOSPC);
653 625 }
654 626
655 627 /*
656 628 * The slots from 0 to igb->num_rx_groups are reserved slots which
657 629 * are 1 to 1 mapped with group index directly. The other slots are
658 630 * shared between the all of groups. While adding a MAC address,
659 631 * it will try to set the reserved slots first, then the shared slots.
660 632 */
661 633 slot = -1;
662 634 if (igb->unicst_addr[rx_group->index].mac.set == 1) {
663 635 /*
664 636 * The reserved slot for current group is used, find the free
665 637 * slots in the shared slots.
666 638 */
667 639 for (i = igb->num_rx_groups; i < igb->unicst_total; i++) {
668 640 if (igb->unicst_addr[i].mac.set == 0) {
669 641 slot = i;
670 642 break;
671 643 }
672 644 }
673 645 } else
674 646 slot = rx_group->index;
675 647
676 648 if (slot == -1) {
677 649 /* no slots available in the shared slots */
678 650 mutex_exit(&igb->gen_lock);
679 651 return (ENOSPC);
680 652 }
681 653
682 654 /* Set VMDq according to the mode supported by hardware. */
683 655 e1000_rar_set_vmdq(hw, mac_addr, slot, igb->vmdq_mode, rx_group->index);
684 656
685 657 bcopy(mac_addr, igb->unicst_addr[slot].mac.addr, ETHERADDRL);
686 658 igb->unicst_addr[slot].mac.group_index = rx_group->index;
687 659 igb->unicst_addr[slot].mac.set = 1;
688 660 igb->unicst_avail--;
689 661
690 662 mutex_exit(&igb->gen_lock);
691 663
692 664 return (0);
693 665 }
694 666
695 667 /*
696 668 * Remove a MAC address from the specified RX group.
697 669 */
698 670 static int
699 671 igb_remmac(void *arg, const uint8_t *mac_addr)
700 672 {
701 673 igb_rx_group_t *rx_group = (igb_rx_group_t *)arg;
702 674 igb_t *igb = rx_group->igb;
703 675 struct e1000_hw *hw = &igb->hw;
704 676 int slot;
705 677
706 678 mutex_enter(&igb->gen_lock);
707 679
708 680 if (igb->igb_state & IGB_SUSPENDED) {
709 681 mutex_exit(&igb->gen_lock);
710 682 return (ECANCELED);
711 683 }
712 684
713 685 slot = igb_unicst_find(igb, mac_addr);
714 686 if (slot == -1) {
715 687 mutex_exit(&igb->gen_lock);
716 688 return (EINVAL);
717 689 }
718 690
719 691 if (igb->unicst_addr[slot].mac.set == 0) {
720 692 mutex_exit(&igb->gen_lock);
721 693 return (EINVAL);
722 694 }
723 695
724 696 /* Clear the MAC ddress in the slot */
725 697 e1000_rar_clear(hw, slot);
726 698 igb->unicst_addr[slot].mac.set = 0;
727 699 igb->unicst_avail++;
728 700
729 701 mutex_exit(&igb->gen_lock);
730 702
731 703 return (0);
732 704 }
733 705
734 706 /*
735 707 * Enable interrupt on the specificed rx ring.
736 708 */
737 709 int
738 710 igb_rx_ring_intr_enable(mac_intr_handle_t intrh)
739 711 {
740 712 igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)intrh;
741 713 igb_t *igb = rx_ring->igb;
742 714 struct e1000_hw *hw = &igb->hw;
743 715 uint32_t index = rx_ring->index;
744 716
745 717 if (igb->intr_type == DDI_INTR_TYPE_MSIX) {
746 718 /* Interrupt enabling for MSI-X */
747 719 igb->eims_mask |= (E1000_EICR_RX_QUEUE0 << index);
748 720 E1000_WRITE_REG(hw, E1000_EIMS, igb->eims_mask);
749 721 E1000_WRITE_REG(hw, E1000_EIAC, igb->eims_mask);
750 722 } else {
751 723 ASSERT(index == 0);
752 724 /* Interrupt enabling for MSI and legacy */
753 725 igb->ims_mask |= E1000_IMS_RXT0;
754 726 E1000_WRITE_REG(hw, E1000_IMS, igb->ims_mask);
755 727 }
756 728
757 729 E1000_WRITE_FLUSH(hw);
758 730
759 731 return (0);
760 732 }
761 733
762 734 /*
763 735 * Disable interrupt on the specificed rx ring.
764 736 */
765 737 int
766 738 igb_rx_ring_intr_disable(mac_intr_handle_t intrh)
767 739 {
768 740 igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)intrh;
769 741 igb_t *igb = rx_ring->igb;
770 742 struct e1000_hw *hw = &igb->hw;
771 743 uint32_t index = rx_ring->index;
772 744
773 745 if (igb->intr_type == DDI_INTR_TYPE_MSIX) {
774 746 /* Interrupt disabling for MSI-X */
775 747 igb->eims_mask &= ~(E1000_EICR_RX_QUEUE0 << index);
776 748 E1000_WRITE_REG(hw, E1000_EIMC,
777 749 (E1000_EICR_RX_QUEUE0 << index));
778 750 E1000_WRITE_REG(hw, E1000_EIAC, igb->eims_mask);
779 751 } else {
780 752 ASSERT(index == 0);
781 753 /* Interrupt disabling for MSI and legacy */
782 754 igb->ims_mask &= ~E1000_IMS_RXT0;
783 755 E1000_WRITE_REG(hw, E1000_IMC, E1000_IMS_RXT0);
784 756 }
785 757
786 758 E1000_WRITE_FLUSH(hw);
787 759
788 760 return (0);
789 761 }
790 762
791 763 /*
792 764 * Get the global ring index by a ring index within a group.
793 765 */
794 766 int
795 767 igb_get_rx_ring_index(igb_t *igb, int gindex, int rindex)
796 768 {
797 769 igb_rx_ring_t *rx_ring;
798 770 int i;
799 771
800 772 for (i = 0; i < igb->num_rx_rings; i++) {
801 773 rx_ring = &igb->rx_rings[i];
802 774 if (rx_ring->group_index == gindex)
803 775 rindex--;
804 776 if (rindex < 0)
805 777 return (i);
806 778 }
807 779
808 780 return (-1);
809 781 }
810 782
811 783 static int
812 784 igb_ring_start(mac_ring_driver_t rh, uint64_t mr_gen_num)
813 785 {
814 786 igb_rx_ring_t *rx_ring = (igb_rx_ring_t *)rh;
815 787
816 788 mutex_enter(&rx_ring->rx_lock);
817 789 rx_ring->ring_gen_num = mr_gen_num;
818 790 mutex_exit(&rx_ring->rx_lock);
819 791 return (0);
820 792 }
821 793
822 794 /*
823 795 * Callback funtion for MAC layer to register all rings.
824 796 */
825 797 /* ARGSUSED */
826 798 void
827 799 igb_fill_ring(void *arg, mac_ring_type_t rtype, const int rg_index,
828 800 const int index, mac_ring_info_t *infop, mac_ring_handle_t rh)
829 801 {
830 802 igb_t *igb = (igb_t *)arg;
831 803 mac_intr_t *mintr = &infop->mri_intr;
832 804
833 805 switch (rtype) {
834 806 case MAC_RING_TYPE_RX: {
835 807 igb_rx_ring_t *rx_ring;
836 808 int global_index;
837 809
838 810 /*
839 811 * 'index' is the ring index within the group.
840 812 * We need the global ring index by searching in group.
841 813 */
842 814 global_index = igb_get_rx_ring_index(igb, rg_index, index);
843 815
844 816 ASSERT(global_index >= 0);
845 817
846 818 rx_ring = &igb->rx_rings[global_index];
847 819 rx_ring->ring_handle = rh;
848 820
849 821 infop->mri_driver = (mac_ring_driver_t)rx_ring;
850 822 infop->mri_start = igb_ring_start;
851 823 infop->mri_stop = NULL;
852 824 infop->mri_poll = (mac_ring_poll_t)igb_rx_ring_poll;
853 825 infop->mri_stat = igb_rx_ring_stat;
854 826
855 827 mintr->mi_handle = (mac_intr_handle_t)rx_ring;
856 828 mintr->mi_enable = igb_rx_ring_intr_enable;
857 829 mintr->mi_disable = igb_rx_ring_intr_disable;
858 830 if (igb->intr_type & (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) {
859 831 mintr->mi_ddi_handle =
860 832 igb->htable[rx_ring->intr_vector];
861 833 }
862 834 break;
863 835 }
864 836 case MAC_RING_TYPE_TX: {
865 837 ASSERT(index < igb->num_tx_rings);
866 838
867 839 igb_tx_ring_t *tx_ring = &igb->tx_rings[index];
868 840 tx_ring->ring_handle = rh;
869 841
870 842 infop->mri_driver = (mac_ring_driver_t)tx_ring;
871 843 infop->mri_start = NULL;
872 844 infop->mri_stop = NULL;
873 845 infop->mri_tx = igb_tx_ring_send;
874 846 infop->mri_stat = igb_tx_ring_stat;
875 847 if (igb->intr_type & (DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI)) {
876 848 mintr->mi_ddi_handle =
877 849 igb->htable[tx_ring->intr_vector];
878 850 }
879 851 break;
880 852 }
881 853 default:
882 854 break;
883 855 }
884 856 }
885 857
886 858 void
887 859 igb_fill_group(void *arg, mac_ring_type_t rtype, const int index,
888 860 mac_group_info_t *infop, mac_group_handle_t gh)
889 861 {
890 862 igb_t *igb = (igb_t *)arg;
891 863
892 864 switch (rtype) {
893 865 case MAC_RING_TYPE_RX: {
894 866 igb_rx_group_t *rx_group;
895 867
896 868 ASSERT((index >= 0) && (index < igb->num_rx_groups));
897 869
898 870 rx_group = &igb->rx_groups[index];
899 871 rx_group->group_handle = gh;
900 872
901 873 infop->mgi_driver = (mac_group_driver_t)rx_group;
902 874 infop->mgi_start = NULL;
903 875 infop->mgi_stop = NULL;
904 876 infop->mgi_addmac = igb_addmac;
905 877 infop->mgi_remmac = igb_remmac;
906 878 infop->mgi_count = (igb->num_rx_rings / igb->num_rx_groups);
907 879
908 880 break;
909 881 }
910 882 case MAC_RING_TYPE_TX:
911 883 break;
912 884 default:
913 885 break;
914 886 }
915 887 }
916 888
917 889 /*
918 890 * Obtain the MAC's capabilities and associated data from
919 891 * the driver.
920 892 */
921 893 boolean_t
922 894 igb_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
923 895 {
924 896 igb_t *igb = (igb_t *)arg;
925 897
926 898 switch (cap) {
927 899 case MAC_CAPAB_HCKSUM: {
928 900 uint32_t *tx_hcksum_flags = cap_data;
929 901
930 902 /*
931 903 * We advertise our capabilities only if tx hcksum offload is
932 904 * enabled. On receive, the stack will accept checksummed
933 905 * packets anyway, even if we haven't said we can deliver
934 906 * them.
935 907 */
936 908 if (!igb->tx_hcksum_enable)
937 909 return (B_FALSE);
938 910
939 911 *tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM;
940 912 break;
941 913 }
942 914 case MAC_CAPAB_LSO: {
943 915 mac_capab_lso_t *cap_lso = cap_data;
944 916
945 917 if (igb->lso_enable) {
946 918 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
947 919 cap_lso->lso_basic_tcp_ipv4.lso_max = IGB_LSO_MAXLEN;
948 920 break;
949 921 } else {
950 922 return (B_FALSE);
951 923 }
952 924 }
953 925 case MAC_CAPAB_RINGS: {
954 926 mac_capab_rings_t *cap_rings = cap_data;
955 927
956 928 switch (cap_rings->mr_type) {
957 929 case MAC_RING_TYPE_RX:
958 930 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
959 931 cap_rings->mr_rnum = igb->num_rx_rings;
960 932 cap_rings->mr_gnum = igb->num_rx_groups;
961 933 cap_rings->mr_rget = igb_fill_ring;
962 934 cap_rings->mr_gget = igb_fill_group;
963 935 cap_rings->mr_gaddring = NULL;
964 936 cap_rings->mr_gremring = NULL;
965 937
966 938 break;
967 939 case MAC_RING_TYPE_TX:
968 940 cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
969 941 cap_rings->mr_rnum = igb->num_tx_rings;
970 942 cap_rings->mr_gnum = 0;
971 943 cap_rings->mr_rget = igb_fill_ring;
972 944 cap_rings->mr_gget = NULL;
973 945
974 946 break;
975 947 default:
976 948 break;
977 949 }
978 950 break;
979 951 }
980 952
981 953 default:
982 954 return (B_FALSE);
983 955 }
984 956 return (B_TRUE);
985 957 }
986 958
987 959 int
988 960 igb_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
989 961 uint_t pr_valsize, const void *pr_val)
990 962 {
991 963 igb_t *igb = (igb_t *)arg;
992 964 struct e1000_hw *hw = &igb->hw;
993 965 int err = 0;
994 966 uint32_t flow_control;
995 967 uint32_t cur_mtu, new_mtu;
996 968 uint32_t rx_size;
997 969 uint32_t tx_size;
998 970
999 971 mutex_enter(&igb->gen_lock);
1000 972 if (igb->igb_state & IGB_SUSPENDED) {
1001 973 mutex_exit(&igb->gen_lock);
1002 974 return (ECANCELED);
1003 975 }
1004 976
1005 977 if (igb->loopback_mode != IGB_LB_NONE && igb_param_locked(pr_num)) {
1006 978 /*
1007 979 * All en_* parameters are locked (read-only)
1008 980 * while the device is in any sort of loopback mode.
1009 981 */
1010 982 mutex_exit(&igb->gen_lock);
1011 983 return (EBUSY);
1012 984 }
1013 985
1014 986 switch (pr_num) {
1015 987 case MAC_PROP_EN_1000FDX_CAP:
1016 988 /* read/write on copper, read-only on serdes */
1017 989 if (hw->phy.media_type != e1000_media_type_copper) {
1018 990 err = ENOTSUP;
1019 991 break;
1020 992 }
1021 993 igb->param_en_1000fdx_cap = *(uint8_t *)pr_val;
1022 994 igb->param_adv_1000fdx_cap = *(uint8_t *)pr_val;
1023 995 goto setup_link;
1024 996 case MAC_PROP_EN_100FDX_CAP:
1025 997 if (hw->phy.media_type != e1000_media_type_copper) {
1026 998 err = ENOTSUP;
1027 999 break;
1028 1000 }
1029 1001 igb->param_en_100fdx_cap = *(uint8_t *)pr_val;
1030 1002 igb->param_adv_100fdx_cap = *(uint8_t *)pr_val;
1031 1003 goto setup_link;
1032 1004 case MAC_PROP_EN_100HDX_CAP:
1033 1005 if (hw->phy.media_type != e1000_media_type_copper) {
1034 1006 err = ENOTSUP;
1035 1007 break;
1036 1008 }
1037 1009 igb->param_en_100hdx_cap = *(uint8_t *)pr_val;
1038 1010 igb->param_adv_100hdx_cap = *(uint8_t *)pr_val;
1039 1011 goto setup_link;
1040 1012 case MAC_PROP_EN_10FDX_CAP:
1041 1013 if (hw->phy.media_type != e1000_media_type_copper) {
1042 1014 err = ENOTSUP;
1043 1015 break;
1044 1016 }
1045 1017 igb->param_en_10fdx_cap = *(uint8_t *)pr_val;
1046 1018 igb->param_adv_10fdx_cap = *(uint8_t *)pr_val;
1047 1019 goto setup_link;
1048 1020 case MAC_PROP_EN_10HDX_CAP:
1049 1021 if (hw->phy.media_type != e1000_media_type_copper) {
1050 1022 err = ENOTSUP;
1051 1023 break;
1052 1024 }
1053 1025 igb->param_en_10hdx_cap = *(uint8_t *)pr_val;
1054 1026 igb->param_adv_10hdx_cap = *(uint8_t *)pr_val;
1055 1027 goto setup_link;
1056 1028 case MAC_PROP_AUTONEG:
1057 1029 if (hw->phy.media_type != e1000_media_type_copper) {
1058 1030 err = ENOTSUP;
1059 1031 break;
1060 1032 }
1061 1033 igb->param_adv_autoneg_cap = *(uint8_t *)pr_val;
1062 1034 goto setup_link;
1063 1035 case MAC_PROP_FLOWCTRL:
1064 1036 bcopy(pr_val, &flow_control, sizeof (flow_control));
1065 1037
1066 1038 switch (flow_control) {
1067 1039 default:
1068 1040 err = EINVAL;
1069 1041 break;
1070 1042 case LINK_FLOWCTRL_NONE:
1071 1043 hw->fc.requested_mode = e1000_fc_none;
1072 1044 break;
1073 1045 case LINK_FLOWCTRL_RX:
1074 1046 hw->fc.requested_mode = e1000_fc_rx_pause;
1075 1047 break;
1076 1048 case LINK_FLOWCTRL_TX:
1077 1049 hw->fc.requested_mode = e1000_fc_tx_pause;
1078 1050 break;
1079 1051 case LINK_FLOWCTRL_BI:
1080 1052 hw->fc.requested_mode = e1000_fc_full;
1081 1053 break;
1082 1054 }
1083 1055 setup_link:
1084 1056 if (err == 0) {
1085 1057 if (igb_setup_link(igb, B_TRUE) != IGB_SUCCESS)
1086 1058 err = EINVAL;
1087 1059 }
1088 1060 break;
1089 1061 case MAC_PROP_ADV_1000FDX_CAP:
1090 1062 case MAC_PROP_ADV_1000HDX_CAP:
1091 1063 case MAC_PROP_ADV_100T4_CAP:
1092 1064 case MAC_PROP_ADV_100FDX_CAP:
1093 1065 case MAC_PROP_ADV_100HDX_CAP:
1094 1066 case MAC_PROP_ADV_10FDX_CAP:
1095 1067 case MAC_PROP_ADV_10HDX_CAP:
1096 1068 case MAC_PROP_EN_1000HDX_CAP:
1097 1069 case MAC_PROP_EN_100T4_CAP:
1098 1070 case MAC_PROP_STATUS:
1099 1071 case MAC_PROP_SPEED:
1100 1072 case MAC_PROP_DUPLEX:
1101 1073 err = ENOTSUP; /* read-only prop. Can't set this. */
1102 1074 break;
1103 1075 case MAC_PROP_MTU:
1104 1076 /* adapter must be stopped for an MTU change */
1105 1077 if (igb->igb_state & IGB_STARTED) {
1106 1078 err = EBUSY;
1107 1079 break;
1108 1080 }
1109 1081
1110 1082 cur_mtu = igb->default_mtu;
1111 1083 bcopy(pr_val, &new_mtu, sizeof (new_mtu));
1112 1084 if (new_mtu == cur_mtu) {
1113 1085 err = 0;
1114 1086 break;
1115 1087 }
1116 1088
1117 1089 if (new_mtu < MIN_MTU || new_mtu > MAX_MTU) {
1118 1090 err = EINVAL;
1119 1091 break;
1120 1092 }
1121 1093
1122 1094 err = mac_maxsdu_update(igb->mac_hdl, new_mtu);
1123 1095 if (err == 0) {
1124 1096 igb->default_mtu = new_mtu;
1125 1097 igb->max_frame_size = igb->default_mtu +
1126 1098 sizeof (struct ether_vlan_header) + ETHERFCSL;
1127 1099
1128 1100 /*
1129 1101 * Set rx buffer size
1130 1102 */
1131 1103 rx_size = igb->max_frame_size + IPHDR_ALIGN_ROOM;
1132 1104 igb->rx_buf_size = ((rx_size >> 10) + ((rx_size &
1133 1105 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
1134 1106
1135 1107 /*
1136 1108 * Set tx buffer size
1137 1109 */
1138 1110 tx_size = igb->max_frame_size;
1139 1111 igb->tx_buf_size = ((tx_size >> 10) + ((tx_size &
1140 1112 (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
1141 1113 }
1142 1114 break;
1143 1115 case MAC_PROP_PRIVATE:
1144 1116 err = igb_set_priv_prop(igb, pr_name, pr_valsize, pr_val);
1145 1117 break;
1146 1118 default:
1147 1119 err = EINVAL;
1148 1120 break;
1149 1121 }
1150 1122
1151 1123 mutex_exit(&igb->gen_lock);
1152 1124
1153 1125 if (igb_check_acc_handle(igb->osdep.reg_handle) != DDI_FM_OK) {
1154 1126 ddi_fm_service_impact(igb->dip, DDI_SERVICE_DEGRADED);
1155 1127 return (EIO);
1156 1128 }
1157 1129
1158 1130 return (err);
1159 1131 }
1160 1132
1161 1133 int
1162 1134 igb_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
1163 1135 uint_t pr_valsize, void *pr_val)
1164 1136 {
1165 1137 igb_t *igb = (igb_t *)arg;
1166 1138 struct e1000_hw *hw = &igb->hw;
1167 1139 int err = 0;
1168 1140 uint32_t flow_control;
1169 1141 uint64_t tmp = 0;
1170 1142
1171 1143 switch (pr_num) {
1172 1144 case MAC_PROP_DUPLEX:
1173 1145 ASSERT(pr_valsize >= sizeof (link_duplex_t));
1174 1146 bcopy(&igb->link_duplex, pr_val, sizeof (link_duplex_t));
1175 1147 break;
1176 1148 case MAC_PROP_SPEED:
1177 1149 ASSERT(pr_valsize >= sizeof (uint64_t));
1178 1150 tmp = igb->link_speed * 1000000ull;
1179 1151 bcopy(&tmp, pr_val, sizeof (tmp));
1180 1152 break;
1181 1153 case MAC_PROP_AUTONEG:
1182 1154 ASSERT(pr_valsize >= sizeof (uint8_t));
1183 1155 *(uint8_t *)pr_val = igb->param_adv_autoneg_cap;
1184 1156 break;
1185 1157 case MAC_PROP_FLOWCTRL:
1186 1158 ASSERT(pr_valsize >= sizeof (uint32_t));
1187 1159 switch (hw->fc.requested_mode) {
1188 1160 case e1000_fc_none:
1189 1161 flow_control = LINK_FLOWCTRL_NONE;
1190 1162 break;
1191 1163 case e1000_fc_rx_pause:
1192 1164 flow_control = LINK_FLOWCTRL_RX;
1193 1165 break;
1194 1166 case e1000_fc_tx_pause:
1195 1167 flow_control = LINK_FLOWCTRL_TX;
1196 1168 break;
1197 1169 case e1000_fc_full:
1198 1170 flow_control = LINK_FLOWCTRL_BI;
1199 1171 break;
1200 1172 }
1201 1173 bcopy(&flow_control, pr_val, sizeof (flow_control));
1202 1174 break;
1203 1175 case MAC_PROP_ADV_1000FDX_CAP:
1204 1176 *(uint8_t *)pr_val = igb->param_adv_1000fdx_cap;
1205 1177 break;
1206 1178 case MAC_PROP_EN_1000FDX_CAP:
1207 1179 *(uint8_t *)pr_val = igb->param_en_1000fdx_cap;
1208 1180 break;
1209 1181 case MAC_PROP_ADV_1000HDX_CAP:
1210 1182 *(uint8_t *)pr_val = igb->param_adv_1000hdx_cap;
1211 1183 break;
1212 1184 case MAC_PROP_EN_1000HDX_CAP:
1213 1185 *(uint8_t *)pr_val = igb->param_en_1000hdx_cap;
1214 1186 break;
1215 1187 case MAC_PROP_ADV_100T4_CAP:
1216 1188 *(uint8_t *)pr_val = igb->param_adv_100t4_cap;
1217 1189 break;
1218 1190 case MAC_PROP_EN_100T4_CAP:
1219 1191 *(uint8_t *)pr_val = igb->param_en_100t4_cap;
1220 1192 break;
1221 1193 case MAC_PROP_ADV_100FDX_CAP:
1222 1194 *(uint8_t *)pr_val = igb->param_adv_100fdx_cap;
1223 1195 break;
1224 1196 case MAC_PROP_EN_100FDX_CAP:
1225 1197 *(uint8_t *)pr_val = igb->param_en_100fdx_cap;
1226 1198 break;
1227 1199 case MAC_PROP_ADV_100HDX_CAP:
1228 1200 *(uint8_t *)pr_val = igb->param_adv_100hdx_cap;
1229 1201 break;
1230 1202 case MAC_PROP_EN_100HDX_CAP:
1231 1203 *(uint8_t *)pr_val = igb->param_en_100hdx_cap;
1232 1204 break;
1233 1205 case MAC_PROP_ADV_10FDX_CAP:
1234 1206 *(uint8_t *)pr_val = igb->param_adv_10fdx_cap;
1235 1207 break;
1236 1208 case MAC_PROP_EN_10FDX_CAP:
1237 1209 *(uint8_t *)pr_val = igb->param_en_10fdx_cap;
1238 1210 break;
1239 1211 case MAC_PROP_ADV_10HDX_CAP:
1240 1212 *(uint8_t *)pr_val = igb->param_adv_10hdx_cap;
1241 1213 break;
1242 1214 case MAC_PROP_EN_10HDX_CAP:
1243 1215 *(uint8_t *)pr_val = igb->param_en_10hdx_cap;
1244 1216 break;
1245 1217 case MAC_PROP_PRIVATE:
1246 1218 err = igb_get_priv_prop(igb, pr_name, pr_valsize, pr_val);
1247 1219 break;
1248 1220 default:
1249 1221 err = EINVAL;
1250 1222 break;
1251 1223 }
1252 1224 return (err);
1253 1225 }
1254 1226
1255 1227 void
1256 1228 igb_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
1257 1229 mac_prop_info_handle_t prh)
1258 1230 {
1259 1231 igb_t *igb = (igb_t *)arg;
1260 1232 struct e1000_hw *hw = &igb->hw;
1261 1233 uint16_t phy_status, phy_ext_status;
1262 1234
1263 1235 switch (pr_num) {
1264 1236 case MAC_PROP_DUPLEX:
1265 1237 case MAC_PROP_SPEED:
1266 1238 case MAC_PROP_ADV_1000FDX_CAP:
1267 1239 case MAC_PROP_ADV_1000HDX_CAP:
1268 1240 case MAC_PROP_EN_1000HDX_CAP:
1269 1241 case MAC_PROP_ADV_100T4_CAP:
1270 1242 case MAC_PROP_EN_100T4_CAP:
1271 1243 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1272 1244 break;
1273 1245
1274 1246 case MAC_PROP_EN_1000FDX_CAP:
1275 1247 if (hw->phy.media_type != e1000_media_type_copper) {
1276 1248 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1277 1249 } else {
1278 1250 (void) e1000_read_phy_reg(hw, PHY_EXT_STATUS,
1279 1251 &phy_ext_status);
1280 1252 mac_prop_info_set_default_uint8(prh,
1281 1253 ((phy_ext_status & IEEE_ESR_1000T_FD_CAPS) ||
1282 1254 (phy_ext_status & IEEE_ESR_1000X_FD_CAPS)) ? 1 : 0);
1283 1255 }
1284 1256 break;
1285 1257
1286 1258 case MAC_PROP_ADV_100FDX_CAP:
1287 1259 case MAC_PROP_EN_100FDX_CAP:
1288 1260 if (hw->phy.media_type != e1000_media_type_copper) {
1289 1261 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1290 1262 } else {
1291 1263 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1292 1264 mac_prop_info_set_default_uint8(prh,
1293 1265 ((phy_status & MII_SR_100X_FD_CAPS) ||
1294 1266 (phy_status & MII_SR_100T2_FD_CAPS)) ? 1 : 0);
1295 1267 }
1296 1268 break;
1297 1269
1298 1270 case MAC_PROP_ADV_100HDX_CAP:
1299 1271 case MAC_PROP_EN_100HDX_CAP:
1300 1272 if (hw->phy.media_type != e1000_media_type_copper) {
1301 1273 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1302 1274 } else {
1303 1275 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1304 1276 mac_prop_info_set_default_uint8(prh,
1305 1277 ((phy_status & MII_SR_100X_HD_CAPS) ||
1306 1278 (phy_status & MII_SR_100T2_HD_CAPS)) ? 1 : 0);
1307 1279 }
1308 1280 break;
1309 1281
1310 1282 case MAC_PROP_ADV_10FDX_CAP:
1311 1283 case MAC_PROP_EN_10FDX_CAP:
1312 1284 if (hw->phy.media_type != e1000_media_type_copper) {
1313 1285 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1314 1286 } else {
1315 1287 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1316 1288 mac_prop_info_set_default_uint8(prh,
1317 1289 (phy_status & MII_SR_10T_FD_CAPS) ? 1 : 0);
1318 1290 }
1319 1291 break;
1320 1292
1321 1293 case MAC_PROP_ADV_10HDX_CAP:
1322 1294 case MAC_PROP_EN_10HDX_CAP:
1323 1295 if (hw->phy.media_type != e1000_media_type_copper) {
1324 1296 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1325 1297 } else {
1326 1298 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1327 1299 mac_prop_info_set_default_uint8(prh,
1328 1300 (phy_status & MII_SR_10T_HD_CAPS) ? 1 : 0);
1329 1301 }
1330 1302 break;
1331 1303
1332 1304 case MAC_PROP_AUTONEG:
1333 1305 if (hw->phy.media_type != e1000_media_type_copper) {
1334 1306 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1335 1307 } else {
1336 1308 (void) e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
1337 1309 mac_prop_info_set_default_uint8(prh,
1338 1310 (phy_status & MII_SR_AUTONEG_CAPS) ? 1 : 0);
1339 1311 }
1340 1312 break;
1341 1313
1342 1314 case MAC_PROP_FLOWCTRL:
1343 1315 mac_prop_info_set_default_link_flowctrl(prh, LINK_FLOWCTRL_BI);
1344 1316 break;
1345 1317
1346 1318 case MAC_PROP_MTU:
1347 1319 mac_prop_info_set_range_uint32(prh, MIN_MTU, MAX_MTU);
1348 1320 break;
1349 1321
1350 1322 case MAC_PROP_PRIVATE:
1351 1323 igb_priv_prop_info(igb, pr_name, prh);
1352 1324 break;
1353 1325 }
1354 1326
1355 1327 }
1356 1328
1357 1329 boolean_t
1358 1330 igb_param_locked(mac_prop_id_t pr_num)
1359 1331 {
1360 1332 /*
1361 1333 * All en_* parameters are locked (read-only) while
1362 1334 * the device is in any sort of loopback mode ...
1363 1335 */
1364 1336 switch (pr_num) {
1365 1337 case MAC_PROP_EN_1000FDX_CAP:
1366 1338 case MAC_PROP_EN_1000HDX_CAP:
1367 1339 case MAC_PROP_EN_100T4_CAP:
1368 1340 case MAC_PROP_EN_100FDX_CAP:
1369 1341 case MAC_PROP_EN_100HDX_CAP:
1370 1342 case MAC_PROP_EN_10FDX_CAP:
1371 1343 case MAC_PROP_EN_10HDX_CAP:
1372 1344 case MAC_PROP_AUTONEG:
1373 1345 case MAC_PROP_FLOWCTRL:
1374 1346 return (B_TRUE);
1375 1347 }
1376 1348 return (B_FALSE);
1377 1349 }
1378 1350
1379 1351 /* ARGSUSED */
1380 1352 int
1381 1353 igb_set_priv_prop(igb_t *igb, const char *pr_name,
1382 1354 uint_t pr_valsize, const void *pr_val)
1383 1355 {
1384 1356 int err = 0;
1385 1357 long result;
↓ open down ↓ |
967 lines elided |
↑ open up ↑ |
1386 1358 struct e1000_hw *hw = &igb->hw;
1387 1359 int i;
1388 1360
1389 1361 if (strcmp(pr_name, "_eee_support") == 0) {
1390 1362 if (pr_val == NULL)
1391 1363 return (EINVAL);
1392 1364 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1393 1365 switch (result) {
1394 1366 case 0:
1395 1367 case 1:
1396 - if (hw->mac.type != e1000_i350) {
1397 - /*
1398 - * For now, only supported on I350.
1399 - * Add new mac.type values (or use < instead)
1400 - * as new cards offer up EEE.
1401 - */
1368 + /*
1369 + * For now, only supported on I350/I354.
1370 + * Add new mac.type values (or use < instead)
1371 + * as new cards offer up EEE.
1372 + */
1373 + switch (hw->mac.type) {
1374 + case e1000_i350:
1375 + /* Must set this prior to the set call. */
1376 + hw->dev_spec._82575.eee_disable = !result;
1377 + if (e1000_set_eee_i350(hw) != E1000_SUCCESS)
1378 + err = EIO;
1379 + break;
1380 + case e1000_i354:
1381 + /* Must set this prior to the set call. */
1382 + hw->dev_spec._82575.eee_disable = !result;
1383 + if (e1000_set_eee_i354(hw) != E1000_SUCCESS)
1384 + err = EIO;
1385 + break;
1386 + default:
1402 1387 return (ENXIO);
1403 1388 }
1404 - /* Must set this prior to the set call. */
1405 - hw->dev_spec._82575.eee_disable = !result;
1406 - if (e1000_set_eee_i350(hw) != E1000_SUCCESS)
1407 - err = EIO;
1408 1389 break;
1409 1390 default:
1410 1391 err = EINVAL;
1411 1392 /* FALLTHRU */
1412 1393 }
1413 1394 return (err);
1414 1395 }
1415 1396 if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
1416 1397 if (pr_val == NULL) {
1417 1398 err = EINVAL;
1418 1399 return (err);
1419 1400 }
1420 1401 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1421 1402 if (result < MIN_TX_COPY_THRESHOLD ||
1422 1403 result > MAX_TX_COPY_THRESHOLD)
1423 1404 err = EINVAL;
1424 1405 else {
1425 1406 igb->tx_copy_thresh = (uint32_t)result;
1426 1407 }
1427 1408 return (err);
1428 1409 }
1429 1410 if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
1430 1411 if (pr_val == NULL) {
1431 1412 err = EINVAL;
1432 1413 return (err);
1433 1414 }
1434 1415 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1435 1416 if (result < MIN_TX_RECYCLE_THRESHOLD ||
1436 1417 result > MAX_TX_RECYCLE_THRESHOLD)
1437 1418 err = EINVAL;
1438 1419 else {
1439 1420 igb->tx_recycle_thresh = (uint32_t)result;
1440 1421 }
1441 1422 return (err);
1442 1423 }
1443 1424 if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
1444 1425 if (pr_val == NULL) {
1445 1426 err = EINVAL;
1446 1427 return (err);
1447 1428 }
1448 1429 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1449 1430 if (result < MIN_TX_OVERLOAD_THRESHOLD ||
1450 1431 result > MAX_TX_OVERLOAD_THRESHOLD)
1451 1432 err = EINVAL;
1452 1433 else {
1453 1434 igb->tx_overload_thresh = (uint32_t)result;
1454 1435 }
1455 1436 return (err);
1456 1437 }
1457 1438 if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
1458 1439 if (pr_val == NULL) {
1459 1440 err = EINVAL;
1460 1441 return (err);
1461 1442 }
1462 1443 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1463 1444 if (result < MIN_TX_RESCHED_THRESHOLD ||
1464 1445 result > MAX_TX_RESCHED_THRESHOLD ||
1465 1446 result > igb->tx_ring_size)
1466 1447 err = EINVAL;
1467 1448 else {
1468 1449 igb->tx_resched_thresh = (uint32_t)result;
1469 1450 }
1470 1451 return (err);
1471 1452 }
1472 1453 if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
1473 1454 if (pr_val == NULL) {
1474 1455 err = EINVAL;
1475 1456 return (err);
1476 1457 }
1477 1458 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1478 1459 if (result < MIN_RX_COPY_THRESHOLD ||
1479 1460 result > MAX_RX_COPY_THRESHOLD)
1480 1461 err = EINVAL;
1481 1462 else {
1482 1463 igb->rx_copy_thresh = (uint32_t)result;
1483 1464 }
1484 1465 return (err);
1485 1466 }
1486 1467 if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
1487 1468 if (pr_val == NULL) {
1488 1469 err = EINVAL;
1489 1470 return (err);
1490 1471 }
1491 1472 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1492 1473 if (result < MIN_RX_LIMIT_PER_INTR ||
1493 1474 result > MAX_RX_LIMIT_PER_INTR)
1494 1475 err = EINVAL;
1495 1476 else {
1496 1477 igb->rx_limit_per_intr = (uint32_t)result;
1497 1478 }
1498 1479 return (err);
1499 1480 }
1500 1481 if (strcmp(pr_name, "_intr_throttling") == 0) {
1501 1482 if (pr_val == NULL) {
1502 1483 err = EINVAL;
1503 1484 return (err);
1504 1485 }
1505 1486 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1506 1487
1507 1488 if (result < igb->capab->min_intr_throttle ||
1508 1489 result > igb->capab->max_intr_throttle)
1509 1490 err = EINVAL;
1510 1491 else {
1511 1492 igb->intr_throttling[0] = (uint32_t)result;
1512 1493
1513 1494 for (i = 0; i < MAX_NUM_EITR; i++)
1514 1495 igb->intr_throttling[i] =
1515 1496 igb->intr_throttling[0];
1516 1497
1517 1498 /* Set interrupt throttling rate */
1518 1499 for (i = 0; i < igb->intr_cnt; i++)
1519 1500 E1000_WRITE_REG(hw, E1000_EITR(i),
1520 1501 igb->intr_throttling[i]);
1521 1502 }
1522 1503 return (err);
1523 1504 }
1524 1505 return (ENOTSUP);
1525 1506 }
1526 1507
1527 1508 int
1528 1509 igb_get_priv_prop(igb_t *igb, const char *pr_name, uint_t pr_valsize,
1529 1510 void *pr_val)
1530 1511 {
1531 1512 int value;
↓ open down ↓ |
114 lines elided |
↑ open up ↑ |
1532 1513
1533 1514 if (strcmp(pr_name, "_adv_pause_cap") == 0) {
1534 1515 value = igb->param_adv_pause_cap;
1535 1516 } else if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
1536 1517 value = igb->param_adv_asym_pause_cap;
1537 1518 } else if (strcmp(pr_name, "_eee_support") == 0) {
1538 1519 /*
1539 1520 * For now, only supported on I350. Add new mac.type values
1540 1521 * (or use < instead) as new cards offer up EEE.
1541 1522 */
1542 - value = (igb->hw.mac.type != e1000_i350) ? 0 :
1543 - !(igb->hw.dev_spec._82575.eee_disable);
1523 + switch (igb->hw.mac.type) {
1524 + case e1000_i350:
1525 + case e1000_i354:
1526 + value = !(igb->hw.dev_spec._82575.eee_disable);
1527 + break;
1528 + default:
1529 + value = 0;
1530 + }
1544 1531 } else if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
1545 1532 value = igb->tx_copy_thresh;
1546 1533 } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
1547 1534 value = igb->tx_recycle_thresh;
1548 1535 } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
1549 1536 value = igb->tx_overload_thresh;
1550 1537 } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
1551 1538 value = igb->tx_resched_thresh;
1552 1539 } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
1553 1540 value = igb->rx_copy_thresh;
1554 1541 } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
1555 1542 value = igb->rx_limit_per_intr;
1556 1543 } else if (strcmp(pr_name, "_intr_throttling") == 0) {
1557 1544 value = igb->intr_throttling[0];
1558 1545 } else {
1559 1546 return (ENOTSUP);
1560 1547 }
1561 1548
1562 1549 (void) snprintf(pr_val, pr_valsize, "%d", value);
1563 1550 return (0);
1564 1551 }
1565 1552
1566 1553 void
1567 1554 igb_priv_prop_info(igb_t *igb, const char *pr_name, mac_prop_info_handle_t prh)
1568 1555 {
1569 1556 char valstr[64];
1570 1557 int value;
1571 1558
1572 1559 if (strcmp(pr_name, "_adv_pause_cap") == 0 ||
1573 1560 strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
1574 1561 mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1575 1562 return;
1576 1563 } else if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
1577 1564 value = DEFAULT_TX_COPY_THRESHOLD;
1578 1565 } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
1579 1566 value = DEFAULT_TX_RECYCLE_THRESHOLD;
1580 1567 } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
1581 1568 value = DEFAULT_TX_OVERLOAD_THRESHOLD;
1582 1569 } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
1583 1570 value = DEFAULT_TX_RESCHED_THRESHOLD;
1584 1571 } else if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
1585 1572 value = DEFAULT_RX_COPY_THRESHOLD;
1586 1573 } else if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
1587 1574 value = DEFAULT_RX_LIMIT_PER_INTR;
1588 1575 } else if (strcmp(pr_name, "_intr_throttling") == 0) {
1589 1576 value = igb->capab->def_intr_throttle;
1590 1577 } else {
1591 1578 return;
1592 1579 }
1593 1580
1594 1581 (void) snprintf(valstr, sizeof (valstr), "%d", value);
1595 1582 mac_prop_info_set_default_str(prh, valstr);
1596 1583 }
↓ open down ↓ |
43 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX