FreeBSD/sys/dev/cxgb/common/cxgb_xgmac.c
/**
 *	t3_mac_set_speed_duplex_fc - set MAC speed, duplex and flow control
 *	@mac: the MAC to configure
 *	@speed: the desired speed (10/100/1000/10000)
 *	@duplex: the desired duplex
 *	@fc: desired Tx/Rx PAUSE configuration
 *
 *	Set the MAC speed, duplex (actually only full-duplex is supported), and
 *	flow control.  If a parameter value is negative the corresponding
 *	MAC setting is left at its current value.
 */
set MAC speed, duplex and flow control
@mac: the MAC to configure
@speed: the desired speed (10/100/1000/10000)
@duplex: the desired duplex
@fc: desired Tx/Rx PAUSE configuration

Set the MAC speed, duplex (actually only full-duplex is supported), and
flow control.  If a parameter value is negative the corresponding
MAC setting is left at its current value.
set MAC speed duplex and flow control @mac : the MAC to configure @speed : the desired speed ( 10 / 100 / 1000 / 10000 ) @duplex : the desired duplex @fc : desired Tx / Rx PAUSE configuration Set the MAC speed duplex ( actually only full - duplex is supported ) and flow control . If a parameter value is negative the corresponding MAC setting is left at its current value .
int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc)
{
	u32 val;
	adapter_t *adap = mac->adapter;
	unsigned int oft = mac->offset;
	unsigned int pause_bits;
	if (duplex >= 0 && duplex != DUPLEX_FULL)
		return -EINVAL;
	pause_bits = MAC_RXFIFO_SIZE * 4 * 8;
	t3_write_reg(adap, A_XGM_TX_PAUSE_QUANTA + mac->offset,
		     pause_bits / 512);
	t3_write_reg(adap, A_XGM_PAUSE_TIMER + mac->offset,
		     (pause_bits >> (adap->params.rev == T3_REV_C ? 10 : 7)));
	if (mac->multiport) {
		u32 rx_max_pkt_size =
		    G_RXMAXPKTSIZE(t3_read_reg(adap,
					       A_XGM_RX_MAX_PKT_SIZE + oft));
		val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft);
		val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM);
		val |= V_RXFIFOPAUSEHWM(rx_fifo_hwm(rx_max_pkt_size) / 8);
		t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val);
		t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
			  		F_TXPAUSEEN);
		return t3_vsc7323_set_speed_fc(adap, speed, fc, mac->ext_port);
	}
	if (speed >= 0) {
		if (speed == SPEED_10)
			val = V_PORTSPEED(0);
		else if (speed == SPEED_100)
			val = V_PORTSPEED(1);
		else if (speed == SPEED_1000)
			val = V_PORTSPEED(2);
		else if (speed == SPEED_10000)
			val = V_PORTSPEED(3);
		else
			return -EINVAL;
		if (!uses_xaui(adap)) 
			t3_set_reg_field(adap, A_XGM_PORT_CFG + oft,
			    V_PORTSPEED(M_PORTSPEED), val);
		else {
			u32 old = t3_read_reg(adap, A_XGM_PORT_CFG + oft);
			if ((old & V_PORTSPEED(M_PORTSPEED)) != val) {
				t3_mac_reset(mac, val);
				mac->was_reset = 1;
			}
		}
	}
	val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft);
	val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM);
	if (fc & PAUSE_TX) {
		u32 rx_max_pkt_size =
		    G_RXMAXPKTSIZE(t3_read_reg(adap,
					       A_XGM_RX_MAX_PKT_SIZE + oft));
		val |= V_RXFIFOPAUSEHWM(rx_fifo_hwm(rx_max_pkt_size) / 8);
	}
	t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val);
	t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
			(fc & PAUSE_RX) ? F_TXPAUSEEN : 0);
	return 0;
}
int t3_mac_set_speed_duplex_fc ( struct cmac * mac , int speed , int duplex , int fc ) { u32 val ; adapter_t * adap = mac -> adapter ; unsigned int oft = mac -> offset ; unsigned int pause_bits ; if ( duplex >= 0 && duplex != DUPLEX_FULL ) return - EINVAL ; pause_bits = MAC_RXFIFO_SIZE * 4 * 8 ; t3_write_reg ( adap , A_XGM_TX_PAUSE_QUANTA + mac -> offset , pause_bits / 512 ) ; t3_write_reg ( adap , A_XGM_PAUSE_TIMER + mac -> offset , ( pause_bits >> ( adap -> params . rev == T3_REV_C ? 10 : 7 ) ) ) ; if ( mac -> multiport ) { u32 rx_max_pkt_size = G_RXMAXPKTSIZE ( t3_read_reg ( adap , A_XGM_RX_MAX_PKT_SIZE + oft ) ) ; val = t3_read_reg ( adap , A_XGM_RXFIFO_CFG + oft ) ; val &= ~ V_RXFIFOPAUSEHWM ( M_RXFIFOPAUSEHWM ) ; val |= V_RXFIFOPAUSEHWM ( rx_fifo_hwm ( rx_max_pkt_size ) / 8 ) ; t3_write_reg ( adap , A_XGM_RXFIFO_CFG + oft , val ) ; t3_set_reg_field ( adap , A_XGM_TX_CFG + oft , F_TXPAUSEEN , F_TXPAUSEEN ) ; return t3_vsc7323_set_speed_fc ( adap , speed , fc , mac -> ext_port ) ; } if ( speed >= 0 ) { if ( speed == SPEED_10 ) val = V_PORTSPEED ( 0 ) ; else if ( speed == SPEED_100 ) val = V_PORTSPEED ( 1 ) ; else if ( speed == SPEED_1000 ) val = V_PORTSPEED ( 2 ) ; else if ( speed == SPEED_10000 ) val = V_PORTSPEED ( 3 ) ; else return - EINVAL ; if ( ! uses_xaui ( adap ) ) t3_set_reg_field ( adap , A_XGM_PORT_CFG + oft , V_PORTSPEED ( M_PORTSPEED ) , val ) ; else { u32 old = t3_read_reg ( adap , A_XGM_PORT_CFG + oft ) ; if ( ( old & V_PORTSPEED ( M_PORTSPEED ) ) != val ) { t3_mac_reset ( mac , val ) ; mac -> was_reset = 1 ; } } } val = t3_read_reg ( adap , A_XGM_RXFIFO_CFG + oft ) ; val &= ~ V_RXFIFOPAUSEHWM ( M_RXFIFOPAUSEHWM ) ; if ( fc & PAUSE_TX ) { u32 rx_max_pkt_size = G_RXMAXPKTSIZE ( t3_read_reg ( adap , A_XGM_RX_MAX_PKT_SIZE + oft ) ) ; val |= V_RXFIFOPAUSEHWM ( rx_fifo_hwm ( rx_max_pkt_size ) / 8 ) ; } t3_write_reg ( adap , A_XGM_RXFIFO_CFG + oft , val ) ; t3_set_reg_field ( adap , A_XGM_TX_CFG + oft , F_TXPAUSEEN , ( fc & PAUSE_RX ) ? F_TXPAUSEEN : 0 ) ; return 0 ; }
t3_mac_set_speed_duplex_fc - set MAC speed, duplex and flow control
      @mac: the MAC to configure
      @speed: the desired speed (10/100/1000/10000)
      @duplex: the desired duplex
      @fc: desired Tx/Rx PAUSE configuration
t3_mac_set_speed_duplex_fc - set MAC speed duplex and flow control @mac : the MAC to configure @speed : the desired speed ( 10 / 100 / 1000 / 10000 ) @duplex : the desired duplex @fc : desired Tx / Rx PAUSE configuration
/* T302 */