void falcon_reconfigure_xmac_core(struct efx_nic *efx)
{
	unsigned int max_frame_len;
	efx_oword_t reg;
	bool rx_fc = !!(efx->link_state.fc & EFX_FC_RX);
	bool tx_fc = !!(efx->link_state.fc & EFX_FC_TX);

	/* Configure MAC  - cut-thru mode is hard wired on */
	EFX_POPULATE_OWORD_3(reg,
			     FRF_AB_XM_RX_JUMBO_MODE, 1,
			     FRF_AB_XM_TX_STAT_EN, 1,
			     FRF_AB_XM_RX_STAT_EN, 1);
	efx_writeo(efx, &reg, FR_AB_XM_GLB_CFG);

	/* Configure TX */
	EFX_POPULATE_OWORD_6(reg,
			     FRF_AB_XM_TXEN, 1,
			     FRF_AB_XM_TX_PRMBL, 1,
			     FRF_AB_XM_AUTO_PAD, 1,
			     FRF_AB_XM_TXCRC, 1,
			     FRF_AB_XM_FCNTL, tx_fc,
			     FRF_AB_XM_IPG, 0x3);
	efx_writeo(efx, &reg, FR_AB_XM_TX_CFG);

	/* Configure RX */
	EFX_POPULATE_OWORD_5(reg,
			     FRF_AB_XM_RXEN, 1,
			     FRF_AB_XM_AUTO_DEPAD, 0,
			     FRF_AB_XM_ACPT_ALL_MCAST, 1,
			     FRF_AB_XM_ACPT_ALL_UCAST, efx->promiscuous,
			     FRF_AB_XM_PASS_CRC_ERR, 1);
	efx_writeo(efx, &reg, FR_AB_XM_RX_CFG);

	/* Set frame length */
	max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
	EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_MAX_RX_FRM_SIZE, max_frame_len);
	efx_writeo(efx, &reg, FR_AB_XM_RX_PARAM);
	EFX_POPULATE_OWORD_2(reg,
			     FRF_AB_XM_MAX_TX_FRM_SIZE, max_frame_len,
			     FRF_AB_XM_TX_JUMBO_MODE, 1);
	efx_writeo(efx, &reg, FR_AB_XM_TX_PARAM);

	EFX_POPULATE_OWORD_2(reg,
			     FRF_AB_XM_PAUSE_TIME, 0xfffe, /* MAX PAUSE TIME */
			     FRF_AB_XM_DIS_FCNTL, !rx_fc);
	efx_writeo(efx, &reg, FR_AB_XM_FC);

	/* Set MAC address */
	memcpy(&reg, &efx->net_dev->dev_addr[0], 4);
	efx_writeo(efx, &reg, FR_AB_XM_ADR_LO);
	memcpy(&reg, &efx->net_dev->dev_addr[4], 2);
	efx_writeo(efx, &reg, FR_AB_XM_ADR_HI);
}
Esempio n. 2
0
void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
{
	struct efx_link_state *link_state = &efx->link_state;
	efx_oword_t reg;
	int link_speed, isolate;

	isolate = !!ACCESS_ONCE(efx->reset_pending);

	switch (link_state->speed) {
	case 10000: link_speed = 3; break;
	case 1000:  link_speed = 2; break;
	case 100:   link_speed = 1; break;
	default:    link_speed = 0; break;
	}
	/* MAC_LINK_STATUS controls MAC backpressure but doesn't work
	 * as advertised.  Disable to ensure packets are not
	 * indefinitely held and TX queue can be flushed at any point
	 * while the link is down. */
	EFX_POPULATE_OWORD_5(reg,
			     FRF_AB_MAC_XOFF_VAL, 0xffff /* max pause time */,
			     FRF_AB_MAC_BCAD_ACPT, 1,
			     FRF_AB_MAC_UC_PROM, efx->promiscuous,
			     FRF_AB_MAC_LINK_STATUS, 1, /* always set */
			     FRF_AB_MAC_SPEED, link_speed);
	/* On B0, MAC backpressure can be disabled and packets get
	 * discarded. */
	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
		EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN,
				    !link_state->up || isolate);
	}

	efx_writeo(efx, &reg, FR_AB_MAC_CTRL);

	/* Restore the multicast hash registers. */
	falcon_push_multicast_hash(efx);

	efx_reado(efx, &reg, FR_AZ_RX_CFG);
	/* Enable XOFF signal from RX FIFO (we enabled it during NIC
	 * initialisation but it may read back as 0) */
	EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, 1);
	/* Unisolate the MAC -> RX */
	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0)
		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, !isolate);
	efx_writeo(efx, &reg, FR_AZ_RX_CFG);
}
void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
{
	struct efx_link_state *link_state = &efx->link_state;
	efx_oword_t reg;
	int link_speed, isolate;

	isolate = !!ACCESS_ONCE(efx->reset_pending);

	switch (link_state->speed) {
	case 10000: link_speed = 3; break;
	case 1000:  link_speed = 2; break;
	case 100:   link_speed = 1; break;
	default:    link_speed = 0; break;
	}
	EFX_POPULATE_OWORD_5(reg,
			     FRF_AB_MAC_XOFF_VAL, 0xffff ,
			     FRF_AB_MAC_BCAD_ACPT, 1,
			     FRF_AB_MAC_UC_PROM, efx->promiscuous,
			     FRF_AB_MAC_LINK_STATUS, 1, 
			     FRF_AB_MAC_SPEED, link_speed);
	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
		EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN,
				    !link_state->up || isolate);
	}

	efx_writeo(efx, &reg, FR_AB_MAC_CTRL);

	
	falcon_push_multicast_hash(efx);

	efx_reado(efx, &reg, FR_AZ_RX_CFG);
	EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, 1);
	
	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0)
		EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, !isolate);
	efx_writeo(efx, &reg, FR_AZ_RX_CFG);
}
Esempio n. 4
0
static void falcon_reconfigure_gmac(struct efx_nic *efx)
{
	bool loopback, tx_fc, rx_fc, bytemode;
	int if_mode;
	unsigned int max_frame_len;
	efx_oword_t reg;

	/* Configuration register 1 */
	tx_fc = (efx->link_fc & EFX_FC_TX) || !efx->link_fd;
	rx_fc = !!(efx->link_fc & EFX_FC_RX);
	loopback = (efx->loopback_mode == LOOPBACK_GMAC);
	bytemode = (efx->link_speed == 1000);

	EFX_POPULATE_OWORD_5(reg,
			     GM_LOOP, loopback,
			     GM_TX_EN, 1,
			     GM_TX_FC_EN, tx_fc,
			     GM_RX_EN, 1,
			     GM_RX_FC_EN, rx_fc);
	falcon_write(efx, &reg, GM_CFG1_REG);
	udelay(10);

	/* Configuration register 2 */
	if_mode = (bytemode) ? 2 : 1;
	EFX_POPULATE_OWORD_5(reg,
			     GM_IF_MODE, if_mode,
			     GM_PAD_CRC_EN, 1,
			     GM_LEN_CHK, 1,
			     GM_FD, efx->link_fd,
			     GM_PAMBL_LEN, 0x7/*datasheet recommended */);

	falcon_write(efx, &reg, GM_CFG2_REG);
	udelay(10);

	/* Max frame len register */
	max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu);
	EFX_POPULATE_OWORD_1(reg, GM_MAX_FLEN, max_frame_len);
	falcon_write(efx, &reg, GM_MAX_FLEN_REG);
	udelay(10);

	/* FIFO configuration register 0 */
	EFX_POPULATE_OWORD_5(reg,
			     GMF_FTFENREQ, 1,
			     GMF_STFENREQ, 1,
			     GMF_FRFENREQ, 1,
			     GMF_SRFENREQ, 1,
			     GMF_WTMENREQ, 1);
	falcon_write(efx, &reg, GMF_CFG0_REG);
	udelay(10);

	/* FIFO configuration register 1 */
	EFX_POPULATE_OWORD_2(reg,
			     GMF_CFGFRTH, 0x12,
			     GMF_CFGXOFFRTX, 0xffff);
	falcon_write(efx, &reg, GMF_CFG1_REG);
	udelay(10);

	/* FIFO configuration register 2 */
	EFX_POPULATE_OWORD_2(reg,
			     GMF_CFGHWM, 0x3f,
			     GMF_CFGLWM, 0xa);
	falcon_write(efx, &reg, GMF_CFG2_REG);
	udelay(10);

	/* FIFO configuration register 3 */
	EFX_POPULATE_OWORD_2(reg,
			     GMF_CFGHWMFT, 0x1c,
			     GMF_CFGFTTH, 0x08);
	falcon_write(efx, &reg, GMF_CFG3_REG);
	udelay(10);

	/* FIFO configuration register 4 */
	EFX_POPULATE_OWORD_1(reg, GMF_HSTFLTRFRM_PAUSE, 1);
	falcon_write(efx, &reg, GMF_CFG4_REG);
	udelay(10);

	/* FIFO configuration register 5 */
	falcon_read(efx, &reg, GMF_CFG5_REG);
	EFX_SET_OWORD_FIELD(reg, GMF_CFGBYTMODE, bytemode);
	EFX_SET_OWORD_FIELD(reg, GMF_CFGHDPLX, !efx->link_fd);
	EFX_SET_OWORD_FIELD(reg, GMF_HSTDRPLT64, !efx->link_fd);
	EFX_SET_OWORD_FIELD(reg, GMF_HSTFLTRFRMDC_PAUSE, 0);
	falcon_write(efx, &reg, GMF_CFG5_REG);
	udelay(10);

	/* MAC address */
	EFX_POPULATE_OWORD_4(reg,
			     GM_HWADDR_5, efx->net_dev->dev_addr[5],
			     GM_HWADDR_4, efx->net_dev->dev_addr[4],
			     GM_HWADDR_3, efx->net_dev->dev_addr[3],
			     GM_HWADDR_2, efx->net_dev->dev_addr[2]);
	falcon_write(efx, &reg, GM_ADR1_REG);
	udelay(10);
	EFX_POPULATE_OWORD_2(reg,
			     GM_HWADDR_1, efx->net_dev->dev_addr[1],
			     GM_HWADDR_0, efx->net_dev->dev_addr[0]);
	falcon_write(efx, &reg, GM_ADR2_REG);
	udelay(10);

	falcon_reconfigure_mac_wrapper(efx);
}