Deleted Added
full compact
cxgb_xgmac.c (172096) cxgb_xgmac.c (176472)
1
2/**************************************************************************
3
4Copyright (c) 2007, Chelsio Inc.
5All rights reserved.
6
7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions are met:

--- 15 unchanged lines hidden (view full) ---

24INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27POSSIBILITY OF SUCH DAMAGE.
28
29***************************************************************************/
30
31#include <sys/cdefs.h>
1
2/**************************************************************************
3
4Copyright (c) 2007, Chelsio Inc.
5All rights reserved.
6
7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions are met:

--- 15 unchanged lines hidden (view full) ---

24INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27POSSIBILITY OF SUCH DAMAGE.
28
29***************************************************************************/
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/dev/cxgb/common/cxgb_xgmac.c 172096 2007-09-09 01:28:03Z kmacy $");
32__FBSDID("$FreeBSD: head/sys/dev/cxgb/common/cxgb_xgmac.c 176472 2008-02-23 01:06:17Z kmacy $");
33
34#ifdef CONFIG_DEFINED
35#include <cxgb_include.h>
36#else
37#include <dev/cxgb/cxgb_include.h>
38#endif
39
40#undef msleep

--- 29 unchanged lines hidden (view full) ---

70 udelay(15);
71
72 for (i = 0; i < ARRAY_SIZE(clear); i++) {
73 t3_set_reg_field(adap, ctrl, clear[i], 0);
74 udelay(15);
75 }
76}
77
33
34#ifdef CONFIG_DEFINED
35#include <cxgb_include.h>
36#else
37#include <dev/cxgb/cxgb_include.h>
38#endif
39
40#undef msleep

--- 29 unchanged lines hidden (view full) ---

70 udelay(15);
71
72 for (i = 0; i < ARRAY_SIZE(clear); i++) {
73 t3_set_reg_field(adap, ctrl, clear[i], 0);
74 udelay(15);
75 }
76}
77
78/**
79 * t3b_pcs_reset - reset the PCS on T3B+ adapters
80 * @mac: the XGMAC handle
81 *
82 * Reset the XGMAC PCS block on T3B+ adapters.
83 */
78void t3b_pcs_reset(struct cmac *mac)
79{
80 t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset,
81 F_PCS_RESET_, 0);
82 udelay(20);
83 t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset, 0,
84 F_PCS_RESET_);
85}
86
84void t3b_pcs_reset(struct cmac *mac)
85{
86 t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset,
87 F_PCS_RESET_, 0);
88 udelay(20);
89 t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset, 0,
90 F_PCS_RESET_);
91}
92
93/**
94 * t3_mac_reset - reset a MAC
95 * @mac: the MAC to reset
96 *
97 * Reset the given MAC.
98 */
87int t3_mac_reset(struct cmac *mac)
88{
89 static struct addr_val_pair mac_reset_avp[] = {
90 { A_XGM_TX_CTRL, 0 },
91 { A_XGM_RX_CTRL, 0 },
92 { A_XGM_RX_CFG, F_DISPAUSEFRAMES | F_EN1536BFRAMES |
93 F_RMFCS | F_ENJUMBO | F_ENHASHMCAST },
94 { A_XGM_RX_HASH_LOW, 0 },

--- 14 unchanged lines hidden (view full) ---

109
110 t3_write_reg(adap, A_XGM_RESET_CTRL + oft, F_MAC_RESET_);
111 (void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
112
113 t3_write_regs(adap, mac_reset_avp, ARRAY_SIZE(mac_reset_avp), oft);
114 t3_set_reg_field(adap, A_XGM_RXFIFO_CFG + oft,
115 F_RXSTRFRWRD | F_DISERRFRAMES,
116 uses_xaui(adap) ? 0 : F_RXSTRFRWRD);
99int t3_mac_reset(struct cmac *mac)
100{
101 static struct addr_val_pair mac_reset_avp[] = {
102 { A_XGM_TX_CTRL, 0 },
103 { A_XGM_RX_CTRL, 0 },
104 { A_XGM_RX_CFG, F_DISPAUSEFRAMES | F_EN1536BFRAMES |
105 F_RMFCS | F_ENJUMBO | F_ENHASHMCAST },
106 { A_XGM_RX_HASH_LOW, 0 },

--- 14 unchanged lines hidden (view full) ---

121
122 t3_write_reg(adap, A_XGM_RESET_CTRL + oft, F_MAC_RESET_);
123 (void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
124
125 t3_write_regs(adap, mac_reset_avp, ARRAY_SIZE(mac_reset_avp), oft);
126 t3_set_reg_field(adap, A_XGM_RXFIFO_CFG + oft,
127 F_RXSTRFRWRD | F_DISERRFRAMES,
128 uses_xaui(adap) ? 0 : F_RXSTRFRWRD);
129 t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + oft, 0, F_UNDERUNFIX);
117
118 if (uses_xaui(adap)) {
119 if (adap->params.rev == 0) {
120 t3_set_reg_field(adap, A_XGM_SERDES_CTRL + oft, 0,
121 F_RXENABLE | F_TXENABLE);
122 if (t3_wait_op_done(adap, A_XGM_SERDES_STATUS1 + oft,
123 F_CMULOCK, 1, 5, 2)) {
124 CH_ERR(adap,

--- 16 unchanged lines hidden (view full) ---

141 t3_set_reg_field(adap, A_XGM_RX_CFG + oft, 0, F_COPYPREAMBLE |
142 F_ENNON802_3PREAMBLE);
143 t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + oft,
144 V_TXFIFOTHRESH(M_TXFIFOTHRESH),
145 V_TXFIFOTHRESH(64));
146 t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
147 t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN);
148 }
130
131 if (uses_xaui(adap)) {
132 if (adap->params.rev == 0) {
133 t3_set_reg_field(adap, A_XGM_SERDES_CTRL + oft, 0,
134 F_RXENABLE | F_TXENABLE);
135 if (t3_wait_op_done(adap, A_XGM_SERDES_STATUS1 + oft,
136 F_CMULOCK, 1, 5, 2)) {
137 CH_ERR(adap,

--- 16 unchanged lines hidden (view full) ---

154 t3_set_reg_field(adap, A_XGM_RX_CFG + oft, 0, F_COPYPREAMBLE |
155 F_ENNON802_3PREAMBLE);
156 t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + oft,
157 V_TXFIFOTHRESH(M_TXFIFOTHRESH),
158 V_TXFIFOTHRESH(64));
159 t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
160 t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN);
161 }
149
150 val = F_MAC_RESET_;
162 t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + oft,
163 V_RXMAXFRAMERSIZE(M_RXMAXFRAMERSIZE),
164 V_RXMAXFRAMERSIZE(MAX_FRAME_SIZE) | F_RXENFRAMER);
165 val = F_MAC_RESET_ | F_XGMAC_STOP_EN;
151 if (is_10G(adap) || mac->multiport)
152 val |= F_PCS_RESET_;
153 else if (uses_xaui(adap))
154 val |= F_PCS_RESET_ | F_XG2G_RESET_;
155 else
156 val |= F_RGMII_RESET_ | F_XG2G_RESET_;
157 t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val);
158 (void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */

--- 72 unchanged lines hidden (view full) ---

231
232 addr_lo = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
233 addr_hi = (addr[5] << 8) | addr[4];
234
235 t3_write_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_LOW_1 + oft, addr_lo);
236 t3_write_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_HIGH_1 + oft, addr_hi);
237}
238
166 if (is_10G(adap) || mac->multiport)
167 val |= F_PCS_RESET_;
168 else if (uses_xaui(adap))
169 val |= F_PCS_RESET_ | F_XG2G_RESET_;
170 else
171 val |= F_RGMII_RESET_ | F_XG2G_RESET_;
172 t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val);
173 (void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */

--- 72 unchanged lines hidden (view full) ---

246
247 addr_lo = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
248 addr_hi = (addr[5] << 8) | addr[4];
249
250 t3_write_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_LOW_1 + oft, addr_lo);
251 t3_write_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_HIGH_1 + oft, addr_hi);
252}
253
239/* Set one of the station's unicast MAC addresses. */
254/**
255 * t3_mac_set_address - set one of the station's unicast MAC addresses
256 * @mac: the MAC handle
257 * @idx: index of the exact address match filter to use
258 * @addr: the Ethernet address
259 *
260 * Set one of the station's unicast MAC addresses.
261 */
240int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6])
241{
242 if (mac->multiport)
243 idx = mac->ext_port + idx * mac->adapter->params.nports;
244 if (idx >= mac->nucast)
245 return -EINVAL;
246 set_addr_filter(mac, idx, addr);
247 if (mac->multiport && idx < mac->adapter->params.nports)
248 t3_vsc7323_set_addr(mac->adapter, addr, idx);
249 return 0;
250}
251
262int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6])
263{
264 if (mac->multiport)
265 idx = mac->ext_port + idx * mac->adapter->params.nports;
266 if (idx >= mac->nucast)
267 return -EINVAL;
268 set_addr_filter(mac, idx, addr);
269 if (mac->multiport && idx < mac->adapter->params.nports)
270 t3_vsc7323_set_addr(mac->adapter, addr, idx);
271 return 0;
272}
273
252/*
253 * Specify the number of exact address filters that should be reserved for
254 * unicast addresses. Caller should reload the unicast and multicast addresses
255 * after calling this.
274/**
275 * t3_mac_set_num_ucast - set the number of unicast addresses needed
276 * @mac: the MAC handle
277 * @n: number of unicast addresses needed
278 *
279 * Specify the number of exact address filters that should be reserved for
280 * unicast addresses. Caller should reload the unicast and multicast
281 * addresses after calling this.
256 */
257int t3_mac_set_num_ucast(struct cmac *mac, unsigned char n)
258{
259 if (n > EXACT_ADDR_FILTERS)
260 return -EINVAL;
261 mac->nucast = n;
262 return 0;
263}

--- 29 unchanged lines hidden (view full) ---

293 for (c = addr[octet], bit = 0; bit < 8; c >>= 1, ++bit) {
294 hash ^= (c & 1) << i;
295 if (++i == 6)
296 i = 0;
297 }
298 return hash;
299}
300
282 */
283int t3_mac_set_num_ucast(struct cmac *mac, unsigned char n)
284{
285 if (n > EXACT_ADDR_FILTERS)
286 return -EINVAL;
287 mac->nucast = n;
288 return 0;
289}

--- 29 unchanged lines hidden (view full) ---

319 for (c = addr[octet], bit = 0; bit < 8; c >>= 1, ++bit) {
320 hash ^= (c & 1) << i;
321 if (++i == 6)
322 i = 0;
323 }
324 return hash;
325}
326
327/**
328 * t3_mac_set_rx_mode - set the Rx mode and address filters
329 * @mac: the MAC to configure
330 * @rm: structure containing the Rx mode and MAC addresses needed
331 *
332 * Configures the MAC Rx mode (promiscuity, etc) and exact and hash
333 * address filters.
334 */
301int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm)
302{
303 u32 hash_lo, hash_hi;
304 adapter_t *adap = mac->adapter;
305 unsigned int oft = mac->offset;
306
307 if (promisc_rx_mode(rm))
308 mac->promisc_map |= 1 << mac->ext_port;

--- 30 unchanged lines hidden (view full) ---

339static int rx_fifo_hwm(int mtu)
340{
341 int hwm;
342
343 hwm = max(MAC_RXFIFO_SIZE - 3 * mtu, (MAC_RXFIFO_SIZE * 38) / 100);
344 return min(hwm, MAC_RXFIFO_SIZE - 8192);
345}
346
335int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm)
336{
337 u32 hash_lo, hash_hi;
338 adapter_t *adap = mac->adapter;
339 unsigned int oft = mac->offset;
340
341 if (promisc_rx_mode(rm))
342 mac->promisc_map |= 1 << mac->ext_port;

--- 30 unchanged lines hidden (view full) ---

373static int rx_fifo_hwm(int mtu)
374{
375 int hwm;
376
377 hwm = max(MAC_RXFIFO_SIZE - 3 * mtu, (MAC_RXFIFO_SIZE * 38) / 100);
378 return min(hwm, MAC_RXFIFO_SIZE - 8192);
379}
380
381/**
382 * t3_mac_set_mtu - set the MAC MTU
383 * @mac: the MAC to configure
384 * @mtu: the MTU
385 *
386 * Sets the MAC MTU and adjusts the FIFO PAUSE watermarks accordingly.
387 */
347int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
348{
388int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
389{
349 int hwm, lwm;
350 unsigned int thres, v;
390 int hwm, lwm, divisor;
391 int ipg;
392 unsigned int thres, v, reg;
351 adapter_t *adap = mac->adapter;
352
353 /*
354 * MAX_FRAME_SIZE inludes header + FCS, mtu doesn't. The HW max
355 * packet size register includes header, but not FCS.
356 */
357 mtu += 14;
358 if (mac->multiport)
359 mtu += 8; /* for preamble */
360 if (mtu > MAX_FRAME_SIZE - 4)
361 return -EINVAL;
362 if (mac->multiport)
363 return t3_vsc7323_set_mtu(adap, mtu - 4, mac->ext_port);
364
393 adapter_t *adap = mac->adapter;
394
395 /*
396 * MAX_FRAME_SIZE inludes header + FCS, mtu doesn't. The HW max
397 * packet size register includes header, but not FCS.
398 */
399 mtu += 14;
400 if (mac->multiport)
401 mtu += 8; /* for preamble */
402 if (mtu > MAX_FRAME_SIZE - 4)
403 return -EINVAL;
404 if (mac->multiport)
405 return t3_vsc7323_set_mtu(adap, mtu - 4, mac->ext_port);
406
365 if (adap->params.rev == T3_REV_B2 &&
407 if (adap->params.rev >= T3_REV_B2 &&
366 (t3_read_reg(adap, A_XGM_RX_CTRL + mac->offset) & F_RXEN)) {
367 disable_exact_filters(mac);
368 v = t3_read_reg(adap, A_XGM_RX_CFG + mac->offset);
369 t3_set_reg_field(adap, A_XGM_RX_CFG + mac->offset,
370 F_ENHASHMCAST | F_COPYALLFRAMES, F_DISBCAST);
371
408 (t3_read_reg(adap, A_XGM_RX_CTRL + mac->offset) & F_RXEN)) {
409 disable_exact_filters(mac);
410 v = t3_read_reg(adap, A_XGM_RX_CFG + mac->offset);
411 t3_set_reg_field(adap, A_XGM_RX_CFG + mac->offset,
412 F_ENHASHMCAST | F_COPYALLFRAMES, F_DISBCAST);
413
372 /* drain rx FIFO */
373 if (t3_wait_op_done(adap,
374 A_XGM_RX_MAX_PKT_SIZE_ERR_CNT + mac->offset,
375 1 << 31, 1, 20, 5)) {
414 reg = adap->params.rev == T3_REV_B2 ?
415 A_XGM_RX_MAX_PKT_SIZE_ERR_CNT : A_XGM_RXFIFO_CFG;
416
417 /* drain RX FIFO */
418 if (t3_wait_op_done(adap, reg + mac->offset,
419 F_RXFIFO_EMPTY, 1, 20, 5)) {
376 t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
377 enable_exact_filters(mac);
378 return -EIO;
379 }
420 t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
421 enable_exact_filters(mac);
422 return -EIO;
423 }
380 t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
424 t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
425 V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
426 V_RXMAXPKTSIZE(mtu));
381 t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
382 enable_exact_filters(mac);
383 } else
427 t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
428 enable_exact_filters(mac);
429 } else
384 t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
385
430 t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
431 V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
432 V_RXMAXPKTSIZE(mtu));
433
386 /*
387 * Adjust the PAUSE frame watermarks. We always set the LWM, and the
388 * HWM only if flow-control is enabled.
389 */
390 hwm = rx_fifo_hwm(mtu);
391 lwm = min(3 * (int) mtu, MAC_RXFIFO_SIZE /4);
392 v = t3_read_reg(adap, A_XGM_RXFIFO_CFG + mac->offset);
393 v &= ~V_RXFIFOPAUSELWM(M_RXFIFOPAUSELWM);

--- 6 unchanged lines hidden (view full) ---

400
401 /* Adjust the TX FIFO threshold based on the MTU */
402 thres = (adap->params.vpd.cclk * 1000) / 15625;
403 thres = (thres * mtu) / 1000;
404 if (is_10G(adap))
405 thres /= 10;
406 thres = mtu > thres ? (mtu - thres + 7) / 8 : 0;
407 thres = max(thres, 8U); /* need at least 8 */
434 /*
435 * Adjust the PAUSE frame watermarks. We always set the LWM, and the
436 * HWM only if flow-control is enabled.
437 */
438 hwm = rx_fifo_hwm(mtu);
439 lwm = min(3 * (int) mtu, MAC_RXFIFO_SIZE /4);
440 v = t3_read_reg(adap, A_XGM_RXFIFO_CFG + mac->offset);
441 v &= ~V_RXFIFOPAUSELWM(M_RXFIFOPAUSELWM);

--- 6 unchanged lines hidden (view full) ---

448
449 /* Adjust the TX FIFO threshold based on the MTU */
450 thres = (adap->params.vpd.cclk * 1000) / 15625;
451 thres = (thres * mtu) / 1000;
452 if (is_10G(adap))
453 thres /= 10;
454 thres = mtu > thres ? (mtu - thres + 7) / 8 : 0;
455 thres = max(thres, 8U); /* need at least 8 */
456 ipg = (adap->params.rev == T3_REV_C) ? 0 : 1;
408 t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + mac->offset,
409 V_TXFIFOTHRESH(M_TXFIFOTHRESH) | V_TXIPG(M_TXIPG),
457 t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + mac->offset,
458 V_TXFIFOTHRESH(M_TXFIFOTHRESH) | V_TXIPG(M_TXIPG),
410 V_TXFIFOTHRESH(thres) | V_TXIPG(1));
459 V_TXFIFOTHRESH(thres) | V_TXIPG(ipg));
411
412 /* Assuming a minimum drain rate of 2.5Gbps...
413 */
460
461 /* Assuming a minimum drain rate of 2.5Gbps...
462 */
414 if (adap->params.rev > 0)
463 if (adap->params.rev > 0) {
464 divisor = (adap->params.rev == T3_REV_C) ? 64 : 8;
415 t3_write_reg(adap, A_XGM_PAUSE_TIMER + mac->offset,
465 t3_write_reg(adap, A_XGM_PAUSE_TIMER + mac->offset,
416 (hwm - lwm) * 4 / 8);
466 (hwm - lwm) * 4 / divisor);
467 }
417 t3_write_reg(adap, A_XGM_TX_PAUSE_QUANTA + mac->offset,
418 MAC_RXFIFO_SIZE * 4 * 8 / 512);
419 return 0;
420}
421
468 t3_write_reg(adap, A_XGM_TX_PAUSE_QUANTA + mac->offset,
469 MAC_RXFIFO_SIZE * 4 * 8 / 512);
470 return 0;
471}
472
473/**
474 * t3_mac_set_speed_duplex_fc - set MAC speed, duplex and flow control
475 * @mac: the MAC to configure
476 * @speed: the desired speed (10/100/1000/10000)
477 * @duplex: the desired duplex
478 * @fc: desired Tx/Rx PAUSE configuration
479 *
480 * Set the MAC speed, duplex (actually only full-duplex is supported), and
481 * flow control. If a parameter value is negative the corresponding
482 * MAC setting is left at its current value.
483 */
422int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc)
423{
424 u32 val;
425 adapter_t *adap = mac->adapter;
426 unsigned int oft = mac->offset;
427
428 if (duplex >= 0 && duplex != DUPLEX_FULL)
429 return -EINVAL;

--- 31 unchanged lines hidden (view full) ---

461 A_XGM_RX_MAX_PKT_SIZE + oft)) / 8);
462 t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val);
463
464 t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
465 (fc & PAUSE_RX) ? F_TXPAUSEEN : 0);
466 return 0;
467}
468
484int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc)
485{
486 u32 val;
487 adapter_t *adap = mac->adapter;
488 unsigned int oft = mac->offset;
489
490 if (duplex >= 0 && duplex != DUPLEX_FULL)
491 return -EINVAL;

--- 31 unchanged lines hidden (view full) ---

523 A_XGM_RX_MAX_PKT_SIZE + oft)) / 8);
524 t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val);
525
526 t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
527 (fc & PAUSE_RX) ? F_TXPAUSEEN : 0);
528 return 0;
529}
530
531/**
532 * t3_mac_enable - enable the MAC in the given directions
533 * @mac: the MAC to configure
534 * @which: bitmap indicating which directions to enable
535 *
536 * Enables the MAC for operation in the given directions.
537 * %MAC_DIRECTION_TX enables the Tx direction, and %MAC_DIRECTION_RX
538 * enables the Rx one.
539 */
469int t3_mac_enable(struct cmac *mac, int which)
470{
471 int idx = macidx(mac);
472 adapter_t *adap = mac->adapter;
473 unsigned int oft = mac->offset;
474 struct mac_stats *s = &mac->stats;
475
476 if (mac->multiport)
477 return t3_vsc7323_enable(adap, mac->ext_port, which);
478
479 if (which & MAC_DIRECTION_TX) {
480 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
540int t3_mac_enable(struct cmac *mac, int which)
541{
542 int idx = macidx(mac);
543 adapter_t *adap = mac->adapter;
544 unsigned int oft = mac->offset;
545 struct mac_stats *s = &mac->stats;
546
547 if (mac->multiport)
548 return t3_vsc7323_enable(adap, mac->ext_port, which);
549
550 if (which & MAC_DIRECTION_TX) {
551 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
481 t3_write_reg(adap, A_TP_PIO_DATA, 0xc0ede401);
552 t3_write_reg(adap, A_TP_PIO_DATA,
553 adap->params.rev == T3_REV_C ?
554 0xc4ffff01 : 0xc0ede401);
482 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
555 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
483 t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
556 t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx,
557 adap->params.rev == T3_REV_C ?
558 0 : 1 << idx);
484
485 t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
486
487 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx);
488 mac->tx_mcnt = s->tx_frames;
489 mac->tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
490 A_TP_PIO_DATA)));
491 mac->tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,

--- 8 unchanged lines hidden (view full) ---

500 mac->txen = F_TXEN;
501 mac->toggle_cnt = 0;
502 }
503 if (which & MAC_DIRECTION_RX)
504 t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN);
505 return 0;
506}
507
559
560 t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
561
562 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx);
563 mac->tx_mcnt = s->tx_frames;
564 mac->tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
565 A_TP_PIO_DATA)));
566 mac->tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,

--- 8 unchanged lines hidden (view full) ---

575 mac->txen = F_TXEN;
576 mac->toggle_cnt = 0;
577 }
578 if (which & MAC_DIRECTION_RX)
579 t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN);
580 return 0;
581}
582
583/**
584 * t3_mac_disable - disable the MAC in the given directions
585 * @mac: the MAC to configure
586 * @which: bitmap indicating which directions to disable
587 *
588 * Disables the MAC in the given directions.
589 * %MAC_DIRECTION_TX disables the Tx direction, and %MAC_DIRECTION_RX
590 * disables the Rx one.
591 */
508int t3_mac_disable(struct cmac *mac, int which)
509{
510 adapter_t *adap = mac->adapter;
511
512 if (mac->multiport)
513 return t3_vsc7323_disable(adap, mac->ext_port, which);
514
515 if (which & MAC_DIRECTION_TX) {

--- 100 unchanged lines hidden (view full) ---

616 mac->toggle_cnt++;
617 } else if (status == 2) {
618 t3b2_mac_reset(mac);
619 mac->toggle_cnt = 0;
620 }
621 return status;
622}
623
592int t3_mac_disable(struct cmac *mac, int which)
593{
594 adapter_t *adap = mac->adapter;
595
596 if (mac->multiport)
597 return t3_vsc7323_disable(adap, mac->ext_port, which);
598
599 if (which & MAC_DIRECTION_TX) {

--- 100 unchanged lines hidden (view full) ---

700 mac->toggle_cnt++;
701 } else if (status == 2) {
702 t3b2_mac_reset(mac);
703 mac->toggle_cnt = 0;
704 }
705 return status;
706}
707
624/*
625 * This function is called periodically to accumulate the current values of the
626 * RMON counters into the port statistics. Since the packet counters are only
627 * 32 bits they can overflow in ~286 secs at 10G, so the function should be
628 * called more frequently than that. The byte counters are 45-bit wide, they
629 * would overflow in ~7.8 hours.
708/**
709 * t3_mac_update_stats - accumulate MAC statistics
710 * @mac: the MAC handle
711 *
712 * This function is called periodically to accumulate the current values
713 * of the RMON counters into the port statistics. Since the packet
714 * counters are only 32 bits they can overflow in ~286 secs at 10G, so the
715 * function should be called more frequently than that. The byte counters
716 * are 45-bit wide, they would overflow in ~7.8 hours.
630 */
631const struct mac_stats *t3_mac_update_stats(struct cmac *mac)
632{
633#define RMON_READ(mac, addr) t3_read_reg(mac->adapter, addr + mac->offset)
634#define RMON_UPDATE(mac, name, reg) \
635 (mac)->stats.name += (u64)RMON_READ(mac, A_XGM_STAT_##reg)
636#define RMON_UPDATE64(mac, name, reg_lo, reg_hi) \
637 (mac)->stats.name += RMON_READ(mac, A_XGM_STAT_##reg_lo) + \

--- 56 unchanged lines hidden ---
717 */
718const struct mac_stats *t3_mac_update_stats(struct cmac *mac)
719{
720#define RMON_READ(mac, addr) t3_read_reg(mac->adapter, addr + mac->offset)
721#define RMON_UPDATE(mac, name, reg) \
722 (mac)->stats.name += (u64)RMON_READ(mac, A_XGM_STAT_##reg)
723#define RMON_UPDATE64(mac, name, reg_lo, reg_hi) \
724 (mac)->stats.name += RMON_READ(mac, A_XGM_STAT_##reg_lo) + \

--- 56 unchanged lines hidden ---