2 * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved.
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36 * # of exact address filters. The first one is used for the station address,
37 * the rest are available for multicast addresses.
39 #define EXACT_ADDR_FILTERS 8
41 static inline int macidx(const struct cmac
*mac
)
43 return mac
->offset
/ (XGMAC0_1_BASE_ADDR
- XGMAC0_0_BASE_ADDR
);
46 static void xaui_serdes_reset(struct cmac
*mac
)
48 static const unsigned int clear
[] = {
49 F_PWRDN0
| F_PWRDN1
, F_RESETPLL01
, F_RESET0
| F_RESET1
,
50 F_PWRDN2
| F_PWRDN3
, F_RESETPLL23
, F_RESET2
| F_RESET3
54 struct adapter
*adap
= mac
->adapter
;
55 u32 ctrl
= A_XGM_SERDES_CTRL0
+ mac
->offset
;
57 t3_write_reg(adap
, ctrl
, adap
->params
.vpd
.xauicfg
[macidx(mac
)] |
58 F_RESET3
| F_RESET2
| F_RESET1
| F_RESET0
|
59 F_PWRDN3
| F_PWRDN2
| F_PWRDN1
| F_PWRDN0
|
60 F_RESETPLL23
| F_RESETPLL01
);
61 t3_read_reg(adap
, ctrl
);
64 for (i
= 0; i
< ARRAY_SIZE(clear
); i
++) {
65 t3_set_reg_field(adap
, ctrl
, clear
[i
], 0);
70 void t3b_pcs_reset(struct cmac
*mac
)
72 t3_set_reg_field(mac
->adapter
, A_XGM_RESET_CTRL
+ mac
->offset
,
75 t3_set_reg_field(mac
->adapter
, A_XGM_RESET_CTRL
+ mac
->offset
, 0,
79 int t3_mac_reset(struct cmac
*mac
)
81 static const struct addr_val_pair mac_reset_avp
[] = {
84 {A_XGM_RX_CFG
, F_DISPAUSEFRAMES
| F_EN1536BFRAMES
|
85 F_RMFCS
| F_ENJUMBO
| F_ENHASHMCAST
},
86 {A_XGM_RX_HASH_LOW
, 0},
87 {A_XGM_RX_HASH_HIGH
, 0},
88 {A_XGM_RX_EXACT_MATCH_LOW_1
, 0},
89 {A_XGM_RX_EXACT_MATCH_LOW_2
, 0},
90 {A_XGM_RX_EXACT_MATCH_LOW_3
, 0},
91 {A_XGM_RX_EXACT_MATCH_LOW_4
, 0},
92 {A_XGM_RX_EXACT_MATCH_LOW_5
, 0},
93 {A_XGM_RX_EXACT_MATCH_LOW_6
, 0},
94 {A_XGM_RX_EXACT_MATCH_LOW_7
, 0},
95 {A_XGM_RX_EXACT_MATCH_LOW_8
, 0},
96 {A_XGM_STAT_CTRL
, F_CLRSTATS
}
99 struct adapter
*adap
= mac
->adapter
;
100 unsigned int oft
= mac
->offset
;
102 t3_write_reg(adap
, A_XGM_RESET_CTRL
+ oft
, F_MAC_RESET_
);
103 t3_read_reg(adap
, A_XGM_RESET_CTRL
+ oft
); /* flush */
105 t3_write_regs(adap
, mac_reset_avp
, ARRAY_SIZE(mac_reset_avp
), oft
);
106 t3_set_reg_field(adap
, A_XGM_RXFIFO_CFG
+ oft
,
107 F_RXSTRFRWRD
| F_DISERRFRAMES
,
108 uses_xaui(adap
) ? 0 : F_RXSTRFRWRD
);
110 if (uses_xaui(adap
)) {
111 if (adap
->params
.rev
== 0) {
112 t3_set_reg_field(adap
, A_XGM_SERDES_CTRL
+ oft
, 0,
113 F_RXENABLE
| F_TXENABLE
);
114 if (t3_wait_op_done(adap
, A_XGM_SERDES_STATUS1
+ oft
,
115 F_CMULOCK
, 1, 5, 2)) {
117 "MAC %d XAUI SERDES CMU lock failed\n",
121 t3_set_reg_field(adap
, A_XGM_SERDES_CTRL
+ oft
, 0,
124 xaui_serdes_reset(mac
);
130 else if (uses_xaui(adap
))
131 val
|= F_PCS_RESET_
| F_XG2G_RESET_
;
133 val
|= F_RGMII_RESET_
| F_XG2G_RESET_
;
134 t3_write_reg(adap
, A_XGM_RESET_CTRL
+ oft
, val
);
135 t3_read_reg(adap
, A_XGM_RESET_CTRL
+ oft
); /* flush */
136 if ((val
& F_PCS_RESET_
) && adap
->params
.rev
) {
141 memset(&mac
->stats
, 0, sizeof(mac
->stats
));
145 static int t3b2_mac_reset(struct cmac
*mac
)
147 struct adapter
*adap
= mac
->adapter
;
148 unsigned int oft
= mac
->offset
;
152 t3_set_reg_field(adap
, A_MPS_CFG
, F_PORT0ACTIVE
, 0);
154 t3_set_reg_field(adap
, A_MPS_CFG
, F_PORT1ACTIVE
, 0);
156 t3_write_reg(adap
, A_XGM_RESET_CTRL
+ oft
, F_MAC_RESET_
);
157 t3_read_reg(adap
, A_XGM_RESET_CTRL
+ oft
); /* flush */
161 /* Check for xgm Rx fifo empty */
162 if (t3_wait_op_done(adap
, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT
+ oft
,
163 0x80000000, 1, 5, 2)) {
164 CH_ERR(adap
, "MAC %d Rx fifo drain failed\n",
169 t3_write_reg(adap
, A_XGM_RESET_CTRL
+ oft
, 0);
170 t3_read_reg(adap
, A_XGM_RESET_CTRL
+ oft
); /* flush */
175 else if (uses_xaui(adap
))
176 val
|= F_PCS_RESET_
| F_XG2G_RESET_
;
178 val
|= F_RGMII_RESET_
| F_XG2G_RESET_
;
179 t3_write_reg(adap
, A_XGM_RESET_CTRL
+ oft
, val
);
180 t3_read_reg(adap
, A_XGM_RESET_CTRL
+ oft
); /* flush */
181 if ((val
& F_PCS_RESET_
) && adap
->params
.rev
) {
185 t3_write_reg(adap
, A_XGM_RX_CFG
+ oft
,
186 F_DISPAUSEFRAMES
| F_EN1536BFRAMES
|
187 F_RMFCS
| F_ENJUMBO
| F_ENHASHMCAST
);
190 t3_set_reg_field(adap
, A_MPS_CFG
, 0, F_PORT0ACTIVE
);
192 t3_set_reg_field(adap
, A_MPS_CFG
, 0, F_PORT1ACTIVE
);
198 * Set the exact match register 'idx' to recognize the given Ethernet address.
200 static void set_addr_filter(struct cmac
*mac
, int idx
, const u8
* addr
)
202 u32 addr_lo
, addr_hi
;
203 unsigned int oft
= mac
->offset
+ idx
* 8;
205 addr_lo
= (addr
[3] << 24) | (addr
[2] << 16) | (addr
[1] << 8) | addr
[0];
206 addr_hi
= (addr
[5] << 8) | addr
[4];
208 t3_write_reg(mac
->adapter
, A_XGM_RX_EXACT_MATCH_LOW_1
+ oft
, addr_lo
);
209 t3_write_reg(mac
->adapter
, A_XGM_RX_EXACT_MATCH_HIGH_1
+ oft
, addr_hi
);
212 /* Set one of the station's unicast MAC addresses. */
213 int t3_mac_set_address(struct cmac
*mac
, unsigned int idx
, u8 addr
[6])
215 if (idx
>= mac
->nucast
)
217 set_addr_filter(mac
, idx
, addr
);
222 * Specify the number of exact address filters that should be reserved for
223 * unicast addresses. Caller should reload the unicast and multicast addresses
224 * after calling this.
226 int t3_mac_set_num_ucast(struct cmac
*mac
, int n
)
228 if (n
> EXACT_ADDR_FILTERS
)
234 static void disable_exact_filters(struct cmac
*mac
)
236 unsigned int i
, reg
= mac
->offset
+ A_XGM_RX_EXACT_MATCH_LOW_1
;
238 for (i
= 0; i
< EXACT_ADDR_FILTERS
; i
++, reg
+= 8) {
239 u32 v
= t3_read_reg(mac
->adapter
, reg
);
240 t3_write_reg(mac
->adapter
, reg
, v
);
242 t3_read_reg(mac
->adapter
, A_XGM_RX_EXACT_MATCH_LOW_1
); /* flush */
245 static void enable_exact_filters(struct cmac
*mac
)
247 unsigned int i
, reg
= mac
->offset
+ A_XGM_RX_EXACT_MATCH_HIGH_1
;
249 for (i
= 0; i
< EXACT_ADDR_FILTERS
; i
++, reg
+= 8) {
250 u32 v
= t3_read_reg(mac
->adapter
, reg
);
251 t3_write_reg(mac
->adapter
, reg
, v
);
253 t3_read_reg(mac
->adapter
, A_XGM_RX_EXACT_MATCH_LOW_1
); /* flush */
256 /* Calculate the RX hash filter index of an Ethernet address */
257 static int hash_hw_addr(const u8
* addr
)
259 int hash
= 0, octet
, bit
, i
= 0, c
;
261 for (octet
= 0; octet
< 6; ++octet
)
262 for (c
= addr
[octet
], bit
= 0; bit
< 8; c
>>= 1, ++bit
) {
263 hash
^= (c
& 1) << i
;
270 int t3_mac_set_rx_mode(struct cmac
*mac
, struct t3_rx_mode
*rm
)
272 u32 val
, hash_lo
, hash_hi
;
273 struct adapter
*adap
= mac
->adapter
;
274 unsigned int oft
= mac
->offset
;
276 val
= t3_read_reg(adap
, A_XGM_RX_CFG
+ oft
) & ~F_COPYALLFRAMES
;
277 if (rm
->dev
->flags
& IFF_PROMISC
)
278 val
|= F_COPYALLFRAMES
;
279 t3_write_reg(adap
, A_XGM_RX_CFG
+ oft
, val
);
281 if (rm
->dev
->flags
& IFF_ALLMULTI
)
282 hash_lo
= hash_hi
= 0xffffffff;
285 int exact_addr_idx
= mac
->nucast
;
287 hash_lo
= hash_hi
= 0;
288 while ((addr
= t3_get_next_mcaddr(rm
)))
289 if (exact_addr_idx
< EXACT_ADDR_FILTERS
)
290 set_addr_filter(mac
, exact_addr_idx
++, addr
);
292 int hash
= hash_hw_addr(addr
);
295 hash_lo
|= (1 << hash
);
297 hash_hi
|= (1 << (hash
- 32));
301 t3_write_reg(adap
, A_XGM_RX_HASH_LOW
+ oft
, hash_lo
);
302 t3_write_reg(adap
, A_XGM_RX_HASH_HIGH
+ oft
, hash_hi
);
306 static int rx_fifo_hwm(int mtu
)
310 hwm
= max(MAC_RXFIFO_SIZE
- 3 * mtu
, (MAC_RXFIFO_SIZE
* 38) / 100);
311 return min(hwm
, MAC_RXFIFO_SIZE
- 8192);
314 int t3_mac_set_mtu(struct cmac
*mac
, unsigned int mtu
)
317 unsigned int thres
, v
;
318 struct adapter
*adap
= mac
->adapter
;
321 * MAX_FRAME_SIZE inludes header + FCS, mtu doesn't. The HW max
322 * packet size register includes header, but not FCS.
325 if (mtu
> MAX_FRAME_SIZE
- 4)
327 t3_write_reg(adap
, A_XGM_RX_MAX_PKT_SIZE
+ mac
->offset
, mtu
);
330 * Adjust the PAUSE frame watermarks. We always set the LWM, and the
331 * HWM only if flow-control is enabled.
333 hwm
= max_t(unsigned int, MAC_RXFIFO_SIZE
- 3 * mtu
,
334 MAC_RXFIFO_SIZE
* 38 / 100);
335 hwm
= min(hwm
, MAC_RXFIFO_SIZE
- 8192);
336 lwm
= min(3 * (int)mtu
, MAC_RXFIFO_SIZE
/ 4);
338 if (adap
->params
.rev
== T3_REV_B2
&&
339 (t3_read_reg(adap
, A_XGM_RX_CTRL
+ mac
->offset
) & F_RXEN
)) {
340 disable_exact_filters(mac
);
341 v
= t3_read_reg(adap
, A_XGM_RX_CFG
+ mac
->offset
);
342 t3_set_reg_field(adap
, A_XGM_RX_CFG
+ mac
->offset
,
343 F_ENHASHMCAST
| F_COPYALLFRAMES
, F_DISBCAST
);
346 if (t3_wait_op_done(adap
,
347 A_XGM_RX_MAX_PKT_SIZE_ERR_CNT
+
349 1 << 31, 1, 20, 5)) {
350 t3_write_reg(adap
, A_XGM_RX_CFG
+ mac
->offset
, v
);
351 enable_exact_filters(mac
);
354 t3_write_reg(adap
, A_XGM_RX_MAX_PKT_SIZE
+ mac
->offset
, mtu
);
355 t3_write_reg(adap
, A_XGM_RX_CFG
+ mac
->offset
, v
);
356 enable_exact_filters(mac
);
358 t3_write_reg(adap
, A_XGM_RX_MAX_PKT_SIZE
+ mac
->offset
, mtu
);
361 * Adjust the PAUSE frame watermarks. We always set the LWM, and the
362 * HWM only if flow-control is enabled.
364 hwm
= rx_fifo_hwm(mtu
);
365 lwm
= min(3 * (int)mtu
, MAC_RXFIFO_SIZE
/ 4);
366 v
= t3_read_reg(adap
, A_XGM_RXFIFO_CFG
+ mac
->offset
);
367 v
&= ~V_RXFIFOPAUSELWM(M_RXFIFOPAUSELWM
);
368 v
|= V_RXFIFOPAUSELWM(lwm
/ 8);
369 if (G_RXFIFOPAUSEHWM(v
))
370 v
= (v
& ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM
)) |
371 V_RXFIFOPAUSEHWM(hwm
/ 8);
373 t3_write_reg(adap
, A_XGM_RXFIFO_CFG
+ mac
->offset
, v
);
375 /* Adjust the TX FIFO threshold based on the MTU */
376 thres
= (adap
->params
.vpd
.cclk
* 1000) / 15625;
377 thres
= (thres
* mtu
) / 1000;
380 thres
= mtu
> thres
? (mtu
- thres
+ 7) / 8 : 0;
381 thres
= max(thres
, 8U); /* need at least 8 */
382 t3_set_reg_field(adap
, A_XGM_TXFIFO_CFG
+ mac
->offset
,
383 V_TXFIFOTHRESH(M_TXFIFOTHRESH
) | V_TXIPG(M_TXIPG
),
384 V_TXFIFOTHRESH(thres
) | V_TXIPG(1));
386 if (adap
->params
.rev
> 0)
387 t3_write_reg(adap
, A_XGM_PAUSE_TIMER
+ mac
->offset
,
388 (hwm
- lwm
) * 4 / 8);
389 t3_write_reg(adap
, A_XGM_TX_PAUSE_QUANTA
+ mac
->offset
,
390 MAC_RXFIFO_SIZE
* 4 * 8 / 512);
394 int t3_mac_set_speed_duplex_fc(struct cmac
*mac
, int speed
, int duplex
, int fc
)
397 struct adapter
*adap
= mac
->adapter
;
398 unsigned int oft
= mac
->offset
;
400 if (duplex
>= 0 && duplex
!= DUPLEX_FULL
)
403 if (speed
== SPEED_10
)
404 val
= V_PORTSPEED(0);
405 else if (speed
== SPEED_100
)
406 val
= V_PORTSPEED(1);
407 else if (speed
== SPEED_1000
)
408 val
= V_PORTSPEED(2);
409 else if (speed
== SPEED_10000
)
410 val
= V_PORTSPEED(3);
414 t3_set_reg_field(adap
, A_XGM_PORT_CFG
+ oft
,
415 V_PORTSPEED(M_PORTSPEED
), val
);
418 val
= t3_read_reg(adap
, A_XGM_RXFIFO_CFG
+ oft
);
419 val
&= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM
);
421 val
|= V_RXFIFOPAUSEHWM(rx_fifo_hwm(
423 A_XGM_RX_MAX_PKT_SIZE
425 t3_write_reg(adap
, A_XGM_RXFIFO_CFG
+ oft
, val
);
427 t3_set_reg_field(adap
, A_XGM_TX_CFG
+ oft
, F_TXPAUSEEN
,
428 (fc
& PAUSE_RX
) ? F_TXPAUSEEN
: 0);
432 int t3_mac_enable(struct cmac
*mac
, int which
)
434 int idx
= macidx(mac
);
435 struct adapter
*adap
= mac
->adapter
;
436 unsigned int oft
= mac
->offset
;
437 struct mac_stats
*s
= &mac
->stats
;
439 if (which
& MAC_DIRECTION_TX
) {
440 t3_write_reg(adap
, A_TP_PIO_ADDR
, A_TP_TX_DROP_CFG_CH0
+ idx
);
441 t3_write_reg(adap
, A_TP_PIO_DATA
, 0xc0ede401);
442 t3_write_reg(adap
, A_TP_PIO_ADDR
, A_TP_TX_DROP_MODE
);
443 t3_set_reg_field(adap
, A_TP_PIO_DATA
, 1 << idx
, 1 << idx
);
445 t3_write_reg(adap
, A_XGM_TX_CTRL
+ oft
, F_TXEN
);
447 t3_write_reg(adap
, A_TP_PIO_ADDR
, A_TP_TX_DROP_CNT_CH0
+ idx
);
448 mac
->tx_mcnt
= s
->tx_frames
;
449 mac
->tx_tcnt
= (G_TXDROPCNTCH0RCVD(t3_read_reg(adap
,
451 mac
->tx_xcnt
= (G_TXSPI4SOPCNT(t3_read_reg(adap
,
452 A_XGM_TX_SPI4_SOP_EOP_CNT
+
454 mac
->rx_mcnt
= s
->rx_frames
;
455 mac
->rx_pause
= s
->rx_pause
;
456 mac
->rx_xcnt
= (G_TXSPI4SOPCNT(t3_read_reg(adap
,
457 A_XGM_RX_SPI4_SOP_EOP_CNT
+
459 mac
->rx_ocnt
= s
->rx_fifo_ovfl
;
463 if (which
& MAC_DIRECTION_RX
)
464 t3_write_reg(adap
, A_XGM_RX_CTRL
+ oft
, F_RXEN
);
468 int t3_mac_disable(struct cmac
*mac
, int which
)
470 struct adapter
*adap
= mac
->adapter
;
472 if (which
& MAC_DIRECTION_TX
) {
473 t3_write_reg(adap
, A_XGM_TX_CTRL
+ mac
->offset
, 0);
476 if (which
& MAC_DIRECTION_RX
) {
477 int val
= F_MAC_RESET_
;
479 t3_set_reg_field(mac
->adapter
, A_XGM_RESET_CTRL
+ mac
->offset
,
482 t3_write_reg(adap
, A_XGM_RX_CTRL
+ mac
->offset
, 0);
485 else if (uses_xaui(adap
))
486 val
|= F_PCS_RESET_
| F_XG2G_RESET_
;
488 val
|= F_RGMII_RESET_
| F_XG2G_RESET_
;
489 t3_write_reg(mac
->adapter
, A_XGM_RESET_CTRL
+ mac
->offset
, val
);
494 int t3b2_mac_watchdog_task(struct cmac
*mac
)
496 struct adapter
*adap
= mac
->adapter
;
497 struct mac_stats
*s
= &mac
->stats
;
498 unsigned int tx_tcnt
, tx_xcnt
;
499 unsigned int tx_mcnt
= s
->tx_frames
;
500 unsigned int rx_mcnt
= s
->rx_frames
;
501 unsigned int rx_xcnt
;
505 tx_xcnt
= 1; /* By default tx_xcnt is making progress */
506 tx_tcnt
= mac
->tx_tcnt
; /* If tx_mcnt is progressing ignore tx_tcnt */
507 rx_xcnt
= 1; /* By default rx_xcnt is making progress */
508 if (tx_mcnt
== mac
->tx_mcnt
&& mac
->rx_pause
== s
->rx_pause
) {
509 tx_xcnt
= (G_TXSPI4SOPCNT(t3_read_reg(adap
,
510 A_XGM_TX_SPI4_SOP_EOP_CNT
+
513 t3_write_reg(adap
, A_TP_PIO_ADDR
,
514 A_TP_TX_DROP_CNT_CH0
+ macidx(mac
));
515 tx_tcnt
= (G_TXDROPCNTCH0RCVD(t3_read_reg(adap
,
525 if ((tx_tcnt
!= mac
->tx_tcnt
) && (mac
->tx_xcnt
== 0)) {
526 if (mac
->toggle_cnt
> 4) {
539 if (rx_mcnt
!= mac
->rx_mcnt
) {
540 rx_xcnt
= (G_TXSPI4SOPCNT(t3_read_reg(adap
,
541 A_XGM_RX_SPI4_SOP_EOP_CNT
+
545 mac
->rx_ocnt
= s
->rx_fifo_ovfl
;
549 if (mac
->rx_mcnt
!= s
->rx_frames
&& rx_xcnt
== 0 &&
556 mac
->tx_tcnt
= tx_tcnt
;
557 mac
->tx_xcnt
= tx_xcnt
;
558 mac
->tx_mcnt
= s
->tx_frames
;
559 mac
->rx_xcnt
= rx_xcnt
;
560 mac
->rx_mcnt
= s
->rx_frames
;
561 mac
->rx_pause
= s
->rx_pause
;
563 t3_write_reg(adap
, A_XGM_TX_CTRL
+ mac
->offset
, 0);
564 t3_read_reg(adap
, A_XGM_TX_CTRL
+ mac
->offset
); /* flush */
565 t3_write_reg(adap
, A_XGM_TX_CTRL
+ mac
->offset
, mac
->txen
);
566 t3_read_reg(adap
, A_XGM_TX_CTRL
+ mac
->offset
); /* flush */
568 } else if (status
== 2) {
576 * This function is called periodically to accumulate the current values of the
577 * RMON counters into the port statistics. Since the packet counters are only
578 * 32 bits they can overflow in ~286 secs at 10G, so the function should be
579 * called more frequently than that. The byte counters are 45-bit wide, they
580 * would overflow in ~7.8 hours.
582 const struct mac_stats
*t3_mac_update_stats(struct cmac
*mac
)
584 #define RMON_READ(mac, addr) t3_read_reg(mac->adapter, addr + mac->offset)
585 #define RMON_UPDATE(mac, name, reg) \
586 (mac)->stats.name += (u64)RMON_READ(mac, A_XGM_STAT_##reg)
587 #define RMON_UPDATE64(mac, name, reg_lo, reg_hi) \
588 (mac)->stats.name += RMON_READ(mac, A_XGM_STAT_##reg_lo) + \
589 ((u64)RMON_READ(mac, A_XGM_STAT_##reg_hi) << 32)
593 RMON_UPDATE64(mac
, rx_octets
, RX_BYTES_LOW
, RX_BYTES_HIGH
);
594 RMON_UPDATE64(mac
, rx_frames
, RX_FRAMES_LOW
, RX_FRAMES_HIGH
);
595 RMON_UPDATE(mac
, rx_mcast_frames
, RX_MCAST_FRAMES
);
596 RMON_UPDATE(mac
, rx_bcast_frames
, RX_BCAST_FRAMES
);
597 RMON_UPDATE(mac
, rx_fcs_errs
, RX_CRC_ERR_FRAMES
);
598 RMON_UPDATE(mac
, rx_pause
, RX_PAUSE_FRAMES
);
599 RMON_UPDATE(mac
, rx_jabber
, RX_JABBER_FRAMES
);
600 RMON_UPDATE(mac
, rx_short
, RX_SHORT_FRAMES
);
601 RMON_UPDATE(mac
, rx_symbol_errs
, RX_SYM_CODE_ERR_FRAMES
);
603 RMON_UPDATE(mac
, rx_too_long
, RX_OVERSIZE_FRAMES
);
605 v
= RMON_READ(mac
, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT
);
606 if (mac
->adapter
->params
.rev
== T3_REV_B2
)
608 mac
->stats
.rx_too_long
+= v
;
610 RMON_UPDATE(mac
, rx_frames_64
, RX_64B_FRAMES
);
611 RMON_UPDATE(mac
, rx_frames_65_127
, RX_65_127B_FRAMES
);
612 RMON_UPDATE(mac
, rx_frames_128_255
, RX_128_255B_FRAMES
);
613 RMON_UPDATE(mac
, rx_frames_256_511
, RX_256_511B_FRAMES
);
614 RMON_UPDATE(mac
, rx_frames_512_1023
, RX_512_1023B_FRAMES
);
615 RMON_UPDATE(mac
, rx_frames_1024_1518
, RX_1024_1518B_FRAMES
);
616 RMON_UPDATE(mac
, rx_frames_1519_max
, RX_1519_MAXB_FRAMES
);
618 RMON_UPDATE64(mac
, tx_octets
, TX_BYTE_LOW
, TX_BYTE_HIGH
);
619 RMON_UPDATE64(mac
, tx_frames
, TX_FRAME_LOW
, TX_FRAME_HIGH
);
620 RMON_UPDATE(mac
, tx_mcast_frames
, TX_MCAST
);
621 RMON_UPDATE(mac
, tx_bcast_frames
, TX_BCAST
);
622 RMON_UPDATE(mac
, tx_pause
, TX_PAUSE
);
623 /* This counts error frames in general (bad FCS, underrun, etc). */
624 RMON_UPDATE(mac
, tx_underrun
, TX_ERR_FRAMES
);
626 RMON_UPDATE(mac
, tx_frames_64
, TX_64B_FRAMES
);
627 RMON_UPDATE(mac
, tx_frames_65_127
, TX_65_127B_FRAMES
);
628 RMON_UPDATE(mac
, tx_frames_128_255
, TX_128_255B_FRAMES
);
629 RMON_UPDATE(mac
, tx_frames_256_511
, TX_256_511B_FRAMES
);
630 RMON_UPDATE(mac
, tx_frames_512_1023
, TX_512_1023B_FRAMES
);
631 RMON_UPDATE(mac
, tx_frames_1024_1518
, TX_1024_1518B_FRAMES
);
632 RMON_UPDATE(mac
, tx_frames_1519_max
, TX_1519_MAXB_FRAMES
);
634 /* The next stat isn't clear-on-read. */
635 t3_write_reg(mac
->adapter
, A_TP_MIB_INDEX
, mac
->offset
? 51 : 50);
636 v
= t3_read_reg(mac
->adapter
, A_TP_MIB_RDATA
);
637 lo
= (u32
) mac
->stats
.rx_cong_drops
;
638 mac
->stats
.rx_cong_drops
+= (u64
) (v
- lo
);