Deleted Added
sdiff udiff text old ( 172096 ) new ( 176472 )
full compact
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 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
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 */
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 */
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);
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 }
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;
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
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 */
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
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.
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 */
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 */
388int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
389{
390 int hwm, lwm, divisor;
391 int ipg;
392 unsigned int thres, v, reg;
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
407 if (adap->params.rev >= T3_REV_B2 &&
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
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)) {
420 t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
421 enable_exact_filters(mac);
422 return -EIO;
423 }
424 t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
425 V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
426 V_RXMAXPKTSIZE(mtu));
427 t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
428 enable_exact_filters(mac);
429 } else
430 t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
431 V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
432 V_RXMAXPKTSIZE(mtu));
433
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;
457 t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + mac->offset,
458 V_TXFIFOTHRESH(M_TXFIFOTHRESH) | V_TXIPG(M_TXIPG),
459 V_TXFIFOTHRESH(thres) | V_TXIPG(ipg));
460
461 /* Assuming a minimum drain rate of 2.5Gbps...
462 */
463 if (adap->params.rev > 0) {
464 divisor = (adap->params.rev == T3_REV_C) ? 64 : 8;
465 t3_write_reg(adap, A_XGM_PAUSE_TIMER + mac->offset,
466 (hwm - lwm) * 4 / divisor);
467 }
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 */
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 */
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);
552 t3_write_reg(adap, A_TP_PIO_DATA,
553 adap->params.rev == T3_REV_C ?
554 0xc4ffff01 : 0xc0ede401);
555 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
556 t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx,
557 adap->params.rev == T3_REV_C ?
558 0 : 1 << idx);
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 */
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
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.
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 ---