Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59b47d8a authored by Michael Chan's avatar Michael Chan Committed by David S. Miller
Browse files

[BNX2]: Add 5709 init code.



Add basic support to initialize the 5709 chip.

Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9052a840
Loading
Loading
Loading
Loading
+130 −37
Original line number Diff line number Diff line
@@ -236,9 +236,24 @@ static void
bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
{
	offset += cid_addr;
	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
		int i;

		REG_WR(bp, BNX2_CTX_CTX_DATA, val);
		REG_WR(bp, BNX2_CTX_CTX_CTRL,
		       offset | BNX2_CTX_CTX_CTRL_WRITE_REQ);
		for (i = 0; i < 5; i++) {
			u32 val;
			val = REG_RD(bp, BNX2_CTX_CTX_CTRL);
			if ((val & BNX2_CTX_CTX_CTRL_WRITE_REQ) == 0)
				break;
			udelay(5);
		}
	} else {
		REG_WR(bp, BNX2_CTX_DATA_ADR, offset);
		REG_WR(bp, BNX2_CTX_DATA, val);
	}
}

static int
bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
@@ -403,6 +418,14 @@ bnx2_free_mem(struct bnx2 *bp)
{
	int i;

	for (i = 0; i < bp->ctx_pages; i++) {
		if (bp->ctx_blk[i]) {
			pci_free_consistent(bp->pdev, BCM_PAGE_SIZE,
					    bp->ctx_blk[i],
					    bp->ctx_blk_mapping[i]);
			bp->ctx_blk[i] = NULL;
		}
	}
	if (bp->status_blk) {
		pci_free_consistent(bp->pdev, bp->status_stats_size,
				    bp->status_blk, bp->status_blk_mapping);
@@ -481,6 +504,18 @@ bnx2_alloc_mem(struct bnx2 *bp)

	bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size;

	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
		bp->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
		if (bp->ctx_pages == 0)
			bp->ctx_pages = 1;
		for (i = 0; i < bp->ctx_pages; i++) {
			bp->ctx_blk[i] = pci_alloc_consistent(bp->pdev,
						BCM_PAGE_SIZE,
						&bp->ctx_blk_mapping[i]);
			if (bp->ctx_blk[i] == NULL)
				goto alloc_mem_err;
		}
	}
	return 0;

alloc_mem_err:
@@ -803,13 +838,13 @@ bnx2_set_mac_link(struct bnx2 *bp)

	val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
		BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
		BNX2_EMAC_MODE_25G);
		BNX2_EMAC_MODE_25G_MODE);

	if (bp->link_up) {
		switch (bp->line_speed) {
			case SPEED_10:
				if (CHIP_NUM(bp) == CHIP_NUM_5708) {
					val |= BNX2_EMAC_MODE_PORT_MII_10;
				if (CHIP_NUM(bp) != CHIP_NUM_5706) {
					val |= BNX2_EMAC_MODE_PORT_MII_10M;
					break;
				}
				/* fall through */
@@ -817,7 +852,7 @@ bnx2_set_mac_link(struct bnx2 *bp)
				val |= BNX2_EMAC_MODE_PORT_MII;
				break;
			case SPEED_2500:
				val |= BNX2_EMAC_MODE_25G;
				val |= BNX2_EMAC_MODE_25G_MODE;
				/* fall through */
			case SPEED_1000:
				val |= BNX2_EMAC_MODE_PORT_GMII;
@@ -1263,9 +1298,8 @@ bnx2_init_5706s_phy(struct bnx2 *bp)
{
	bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;

	if (CHIP_NUM(bp) == CHIP_NUM_5706) {
        	REG_WR(bp, BNX2_MISC_UNUSED0, 0x300);
	}
	if (CHIP_NUM(bp) == CHIP_NUM_5706)
        	REG_WR(bp, BNX2_MISC_GP_HW_CTL0, 0x300);

	if (bp->dev->mtu > 1500) {
		u32 val;
@@ -1408,7 +1442,7 @@ bnx2_set_phy_loopback(struct bnx2 *bp)
	mac_mode = REG_RD(bp, BNX2_EMAC_MODE);
	mac_mode &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
		      BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
		      BNX2_EMAC_MODE_25G);
		      BNX2_EMAC_MODE_25G_MODE);

	mac_mode |= BNX2_EMAC_MODE_PORT_GMII;
	REG_WR(bp, BNX2_EMAC_MODE, mac_mode);
@@ -1459,6 +1493,40 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
	return 0;
}

static int
bnx2_init_5709_context(struct bnx2 *bp)
{
	int i, ret = 0;
	u32 val;

	val = BNX2_CTX_COMMAND_ENABLED | BNX2_CTX_COMMAND_MEM_INIT | (1 << 12);
	val |= (BCM_PAGE_BITS - 8) << 16;
	REG_WR(bp, BNX2_CTX_COMMAND, val);
	for (i = 0; i < bp->ctx_pages; i++) {
		int j;

		REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA0,
		       (bp->ctx_blk_mapping[i] & 0xffffffff) |
		       BNX2_CTX_HOST_PAGE_TBL_DATA0_VALID);
		REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA1,
		       (u64) bp->ctx_blk_mapping[i] >> 32);
		REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_CTRL, i |
		       BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
		for (j = 0; j < 10; j++) {

			val = REG_RD(bp, BNX2_CTX_HOST_PAGE_TBL_CTRL);
			if (!(val & BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ))
				break;
			udelay(5);
		}
		if (val & BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) {
			ret = -EBUSY;
			break;
		}
	}
	return ret;
}

static void
bnx2_init_context(struct bnx2 *bp)
{
@@ -1581,9 +1649,8 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index)
		return -ENOMEM;
	}

	if (unlikely((align = (unsigned long) skb->data & 0x7))) {
		skb_reserve(skb, 8 - align);
	}
	if (unlikely((align = (unsigned long) skb->data & (BNX2_RX_ALIGN - 1))))
		skb_reserve(skb, BNX2_RX_ALIGN - align);

	mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size,
		PCI_DMA_FROMDEVICE);
@@ -3282,6 +3349,9 @@ bnx2_init_chip(struct bnx2 *bp)

	/* Initialize context mapping and zero out the quick contexts.  The
	 * context block must have already been enabled. */
	if (CHIP_NUM(bp) == CHIP_NUM_5709)
		bnx2_init_5709_context(bp);
	else
		bnx2_init_context(bp);

	if ((rc = bnx2_init_cpus(bp)) != 0)
@@ -3393,12 +3463,40 @@ bnx2_init_chip(struct bnx2 *bp)
	return rc;
}

static void
bnx2_init_tx_context(struct bnx2 *bp, u32 cid)
{
	u32 val, offset0, offset1, offset2, offset3;

	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
		offset0 = BNX2_L2CTX_TYPE_XI;
		offset1 = BNX2_L2CTX_CMD_TYPE_XI;
		offset2 = BNX2_L2CTX_TBDR_BHADDR_HI_XI;
		offset3 = BNX2_L2CTX_TBDR_BHADDR_LO_XI;
	} else {
		offset0 = BNX2_L2CTX_TYPE;
		offset1 = BNX2_L2CTX_CMD_TYPE;
		offset2 = BNX2_L2CTX_TBDR_BHADDR_HI;
		offset3 = BNX2_L2CTX_TBDR_BHADDR_LO;
	}
	val = BNX2_L2CTX_TYPE_TYPE_L2 | BNX2_L2CTX_TYPE_SIZE_L2;
	CTX_WR(bp, GET_CID_ADDR(cid), offset0, val);

	val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
	CTX_WR(bp, GET_CID_ADDR(cid), offset1, val);

	val = (u64) bp->tx_desc_mapping >> 32;
	CTX_WR(bp, GET_CID_ADDR(cid), offset2, val);

	val = (u64) bp->tx_desc_mapping & 0xffffffff;
	CTX_WR(bp, GET_CID_ADDR(cid), offset3, val);
}

static void
bnx2_init_tx_ring(struct bnx2 *bp)
{
	struct tx_bd *txbd;
	u32 val;
	u32 cid;

	bp->tx_wake_thresh = bp->tx_ring_size / 2;

@@ -3412,19 +3510,11 @@ bnx2_init_tx_ring(struct bnx2 *bp)
	bp->hw_tx_cons = 0;
	bp->tx_prod_bseq = 0;

	val = BNX2_L2CTX_TYPE_TYPE_L2;
	val |= BNX2_L2CTX_TYPE_SIZE_L2;
	CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TYPE, val);

	val = BNX2_L2CTX_CMD_TYPE_TYPE_L2;
	val |= 8 << 16;
	CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_CMD_TYPE, val);

	val = (u64) bp->tx_desc_mapping >> 32;
	CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_HI, val);
	cid = TX_CID;
	bp->tx_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BIDX;
	bp->tx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BSEQ;

	val = (u64) bp->tx_desc_mapping & 0xffffffff;
	CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_LO, val);
	bnx2_init_tx_context(bp, cid);
}

static void
@@ -3437,8 +3527,8 @@ bnx2_init_rx_ring(struct bnx2 *bp)

	/* 8 for CRC and VLAN */
	bp->rx_buf_use_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8;
	/* 8 for alignment */
	bp->rx_buf_size = bp->rx_buf_use_size + 8;
	/* hw alignment */
	bp->rx_buf_size = bp->rx_buf_use_size + BNX2_RX_ALIGN;

	ring_prod = prod = bp->rx_prod = 0;
	bp->rx_cons = 0;
@@ -5542,13 +5632,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
		goto err_out_release;
	}

	bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
	if (bp->pcix_cap == 0) {
		dev_err(&pdev->dev, "Cannot find PCIX capability, aborting.\n");
		rc = -EIO;
		goto err_out_release;
	}

	if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
		bp->flags |= USING_DAC_FLAG;
		if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
@@ -5571,7 +5654,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
	INIT_WORK(&bp->reset_task, bnx2_reset_task, bp);

	dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0);
	mem_len = MB_GET_CID_ADDR(17);
	mem_len = MB_GET_CID_ADDR(TX_TSS_CID + 1);
	dev->mem_end = dev->mem_start + mem_len;
	dev->irq = pdev->irq;

@@ -5595,6 +5678,16 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)

	bp->chip_id = REG_RD(bp, BNX2_MISC_ID);

	if (CHIP_NUM(bp) != CHIP_NUM_5709) {
		bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
		if (bp->pcix_cap == 0) {
			dev_err(&pdev->dev,
				"Cannot find PCIX capability, aborting.\n");
			rc = -EIO;
			goto err_out_unmap;
		}
	}

	/* Get bus information. */
	reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS);
	if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {