Esempio n. 1
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
 *
 *	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;

	if (duplex >= 0 && duplex != DUPLEX_FULL)
		return -EINVAL;
	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)) /* T302 */
			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;
}
Esempio n. 2
0
File: xgmac.c Progetto: 020gzh/linux
int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc)
{
	u32 val;
	struct adapter *adap = mac->adapter;
	unsigned int oft = mac->offset;

	if (duplex >= 0 && duplex != DUPLEX_FULL)
		return -EINVAL;
	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;

		t3_set_reg_field(adap, A_XGM_PORT_CFG + oft,
				 V_PORTSPEED(M_PORTSPEED), val);
	}

	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;
}