static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth) { struct fm_port_global_pram *pram; u32 pram_page_offset; void *tx_bd_ring_base; struct fm_port_bd *txbd; struct fm_port_qd *txqd; struct fm_bmi_tx_port *bmi_tx_port = fm_eth->tx_port; int i; /* alloc global parameter ram at MURAM */ pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index, FM_PRAM_SIZE, FM_PRAM_ALIGN); fm_eth->tx_pram = pram; /* parameter page offset to MURAM */ pram_page_offset = (u32)pram - fm_muram_base(fm_eth->fm_index); /* enable global mode- snooping data buffers and BDs */ pram->mode = PRAM_MODE_GLOBAL; /* init the Tx queue descriptor pionter */ pram->txqd_ptr = pram_page_offset + 0x40; /* alloc Tx buffer descriptors from main memory */ tx_bd_ring_base = malloc(sizeof(struct fm_port_bd) * TX_BD_RING_SIZE); if (!tx_bd_ring_base) return 0; memset(tx_bd_ring_base, 0, sizeof(struct fm_port_bd) * TX_BD_RING_SIZE); /* save it to fm_eth */ fm_eth->tx_bd_ring = tx_bd_ring_base; fm_eth->cur_txbd = tx_bd_ring_base; /* init Tx BDs ring */ txbd = (struct fm_port_bd *)tx_bd_ring_base; for (i = 0; i < TX_BD_RING_SIZE; i++) { txbd->status = TxBD_LAST; txbd->len = 0; txbd->buf_ptr_hi = 0; txbd->buf_ptr_lo = 0; } /* set the Tx queue decriptor */ txqd = &pram->txqd; muram_writew(&txqd->bd_ring_base_hi, 0); txqd->bd_ring_base_lo = (u32)tx_bd_ring_base; muram_writew(&txqd->bd_ring_size, sizeof(struct fm_port_bd) * TX_BD_RING_SIZE); muram_writew(&txqd->offset_in, 0); muram_writew(&txqd->offset_out, 0); /* set IM parameter ram pointer to Tx Confirmation Frame Queue ID */ out_be32(&bmi_tx_port->fmbm_tcfqid, pram_page_offset); return 1; }
static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth) { struct fm_port_global_pram *pram; u32 pram_page_offset; void *rx_bd_ring_base; void *rx_buf_pool; struct fm_port_bd *rxbd; struct fm_port_qd *rxqd; struct fm_bmi_rx_port *bmi_rx_port = fm_eth->rx_port; int i; /* alloc global parameter ram at MURAM */ pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index, FM_PRAM_SIZE, FM_PRAM_ALIGN); fm_eth->rx_pram = pram; /* parameter page offset to MURAM */ pram_page_offset = (u32)pram - fm_muram_base(fm_eth->fm_index); /* enable global mode- snooping data buffers and BDs */ pram->mode = PRAM_MODE_GLOBAL; /* init the Rx queue descriptor pionter */ pram->rxqd_ptr = pram_page_offset + 0x20; /* set the max receive buffer length, power of 2 */ muram_writew(&pram->mrblr, MAX_RXBUF_LOG2); /* alloc Rx buffer descriptors from main memory */ rx_bd_ring_base = malloc(sizeof(struct fm_port_bd) * RX_BD_RING_SIZE); if (!rx_bd_ring_base) return 0; memset(rx_bd_ring_base, 0, sizeof(struct fm_port_bd) * RX_BD_RING_SIZE); /* alloc Rx buffer from main memory */ rx_buf_pool = malloc(MAX_RXBUF_LEN * RX_BD_RING_SIZE); if (!rx_buf_pool) return 0; memset(rx_buf_pool, 0, MAX_RXBUF_LEN * RX_BD_RING_SIZE); /* save them to fm_eth */ fm_eth->rx_bd_ring = rx_bd_ring_base; fm_eth->cur_rxbd = rx_bd_ring_base; fm_eth->rx_buf = rx_buf_pool; /* init Rx BDs ring */ rxbd = (struct fm_port_bd *)rx_bd_ring_base; for (i = 0; i < RX_BD_RING_SIZE; i++) { rxbd->status = RxBD_EMPTY; rxbd->len = 0; rxbd->buf_ptr_hi = 0; rxbd->buf_ptr_lo = (u32)rx_buf_pool + i * MAX_RXBUF_LEN; rxbd++; } /* set the Rx queue descriptor */ rxqd = &pram->rxqd; muram_writew(&rxqd->gen, 0); muram_writew(&rxqd->bd_ring_base_hi, 0); rxqd->bd_ring_base_lo = (u32)rx_bd_ring_base; muram_writew(&rxqd->bd_ring_size, sizeof(struct fm_port_bd) * RX_BD_RING_SIZE); muram_writew(&rxqd->offset_in, 0); muram_writew(&rxqd->offset_out, 0); /* set IM parameter ram pointer to Rx Frame Queue ID */ out_be32(&bmi_rx_port->fmbm_rfqid, pram_page_offset); return 1; }
static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth) { struct fm_port_global_pram *pram; u32 pram_page_offset; void *rx_bd_ring_base; void *rx_buf_pool; u32 bd_ring_base_lo, bd_ring_base_hi; u32 buf_lo, buf_hi; struct fm_port_bd *rxbd; struct fm_port_qd *rxqd; struct fm_bmi_rx_port *bmi_rx_port = fm_eth->rx_port; int i; /* alloc global parameter ram at MURAM */ pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index, FM_PRAM_SIZE, FM_PRAM_ALIGN); if (!pram) { printf("%s: No muram for Rx global parameter\n", __func__); return -ENOMEM; } fm_eth->rx_pram = pram; /* parameter page offset to MURAM */ pram_page_offset = (void *)pram - fm_muram_base(fm_eth->fm_index); /* enable global mode- snooping data buffers and BDs */ out_be32(&pram->mode, PRAM_MODE_GLOBAL); /* init the Rx queue descriptor pionter */ out_be32(&pram->rxqd_ptr, pram_page_offset + 0x20); /* set the max receive buffer length, power of 2 */ muram_writew(&pram->mrblr, MAX_RXBUF_LOG2); /* alloc Rx buffer descriptors from main memory */ rx_bd_ring_base = malloc(sizeof(struct fm_port_bd) * RX_BD_RING_SIZE); if (!rx_bd_ring_base) return -ENOMEM; memset(rx_bd_ring_base, 0, sizeof(struct fm_port_bd) * RX_BD_RING_SIZE); /* alloc Rx buffer from main memory */ rx_buf_pool = malloc(MAX_RXBUF_LEN * RX_BD_RING_SIZE); if (!rx_buf_pool) return -ENOMEM; memset(rx_buf_pool, 0, MAX_RXBUF_LEN * RX_BD_RING_SIZE); debug("%s: rx_buf_pool = %p\n", __func__, rx_buf_pool); /* save them to fm_eth */ fm_eth->rx_bd_ring = rx_bd_ring_base; fm_eth->cur_rxbd = rx_bd_ring_base; fm_eth->rx_buf = rx_buf_pool; /* init Rx BDs ring */ rxbd = (struct fm_port_bd *)rx_bd_ring_base; for (i = 0; i < RX_BD_RING_SIZE; i++) { muram_writew(&rxbd->status, RxBD_EMPTY); muram_writew(&rxbd->len, 0); buf_hi = upper_32_bits(virt_to_phys(rx_buf_pool + i * MAX_RXBUF_LEN)); buf_lo = lower_32_bits(virt_to_phys(rx_buf_pool + i * MAX_RXBUF_LEN)); muram_writew(&rxbd->buf_ptr_hi, (u16)buf_hi); out_be32(&rxbd->buf_ptr_lo, buf_lo); rxbd++; } /* set the Rx queue descriptor */ rxqd = &pram->rxqd; muram_writew(&rxqd->gen, 0); bd_ring_base_hi = upper_32_bits(virt_to_phys(rx_bd_ring_base)); bd_ring_base_lo = lower_32_bits(virt_to_phys(rx_bd_ring_base)); muram_writew(&rxqd->bd_ring_base_hi, (u16)bd_ring_base_hi); out_be32(&rxqd->bd_ring_base_lo, bd_ring_base_lo); muram_writew(&rxqd->bd_ring_size, sizeof(struct fm_port_bd) * RX_BD_RING_SIZE); muram_writew(&rxqd->offset_in, 0); muram_writew(&rxqd->offset_out, 0); /* set IM parameter ram pointer to Rx Frame Queue ID */ out_be32(&bmi_rx_port->fmbm_rfqid, pram_page_offset); return 0; }
static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth) { struct fm_port_global_pram *pram; u32 pram_page_offset; void *tx_bd_ring_base; u32 bd_ring_base_lo, bd_ring_base_hi; struct fm_port_bd *txbd; struct fm_port_qd *txqd; struct fm_bmi_tx_port *bmi_tx_port = fm_eth->tx_port; int i; /* alloc global parameter ram at MURAM */ pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index, FM_PRAM_SIZE, FM_PRAM_ALIGN); if (!pram) { printf("%s: No muram for Tx global parameter\n", __func__); return -ENOMEM; } fm_eth->tx_pram = pram; /* parameter page offset to MURAM */ pram_page_offset = (void *)pram - fm_muram_base(fm_eth->fm_index); /* enable global mode- snooping data buffers and BDs */ out_be32(&pram->mode, PRAM_MODE_GLOBAL); /* init the Tx queue descriptor pionter */ out_be32(&pram->txqd_ptr, pram_page_offset + 0x40); /* alloc Tx buffer descriptors from main memory */ tx_bd_ring_base = malloc(sizeof(struct fm_port_bd) * TX_BD_RING_SIZE); if (!tx_bd_ring_base) return -ENOMEM; memset(tx_bd_ring_base, 0, sizeof(struct fm_port_bd) * TX_BD_RING_SIZE); /* save it to fm_eth */ fm_eth->tx_bd_ring = tx_bd_ring_base; fm_eth->cur_txbd = tx_bd_ring_base; /* init Tx BDs ring */ txbd = (struct fm_port_bd *)tx_bd_ring_base; for (i = 0; i < TX_BD_RING_SIZE; i++) { muram_writew(&txbd->status, TxBD_LAST); muram_writew(&txbd->len, 0); muram_writew(&txbd->buf_ptr_hi, 0); out_be32(&txbd->buf_ptr_lo, 0); txbd++; } /* set the Tx queue decriptor */ txqd = &pram->txqd; bd_ring_base_hi = upper_32_bits(virt_to_phys(tx_bd_ring_base)); bd_ring_base_lo = lower_32_bits(virt_to_phys(tx_bd_ring_base)); muram_writew(&txqd->bd_ring_base_hi, (u16)bd_ring_base_hi); out_be32(&txqd->bd_ring_base_lo, bd_ring_base_lo); muram_writew(&txqd->bd_ring_size, sizeof(struct fm_port_bd) * TX_BD_RING_SIZE); muram_writew(&txqd->offset_in, 0); muram_writew(&txqd->offset_out, 0); /* set IM parameter ram pointer to Tx Confirmation Frame Queue ID */ out_be32(&bmi_tx_port->fmbm_tcfqid, pram_page_offset); return 0; }
static int fm_init_bmi(int fm_idx, struct fm_bmi_common *bmi) { int blk, i, port_id; u32 val, offset, base; /* alloc free buffer pool in MURAM */ base = fm_muram_alloc(fm_idx, FM_FREE_POOL_SIZE, FM_FREE_POOL_ALIGN); if (!base) { printf("%s: no muram for free buffer pool\n", __func__); return -ENOMEM; } offset = base - fm_muram_base(fm_idx); /* Need 128KB total free buffer pool size */ val = offset / 256; blk = FM_FREE_POOL_SIZE / 256; /* in IM, we must not begin from offset 0 in MURAM */ val |= ((blk - 1) << FMBM_CFG1_FBPS_SHIFT); out_be32(&bmi->fmbm_cfg1, val); /* disable all BMI interrupt */ out_be32(&bmi->fmbm_ier, FMBM_IER_DISABLE_ALL); /* clear all events */ out_be32(&bmi->fmbm_ievr, FMBM_IEVR_CLEAR_ALL); /* * set port parameters - FMBM_PP_x * max tasks 10G Rx/Tx=12, 1G Rx/Tx 4, others is 1 * max dma 10G Rx/Tx=3, others is 1 * set port FIFO size - FMBM_PFS_x * 4KB for all Rx and Tx ports */ /* offline/parser port */ for (i = 0; i < MAX_NUM_OH_PORT; i++) { port_id = OH_PORT_ID_BASE + i - 1; /* max tasks=1, max dma=1, no extra */ out_be32(&bmi->fmbm_pp[port_id], 0); /* port FIFO size - 256 bytes, no extra */ out_be32(&bmi->fmbm_pfs[port_id], 0); } /* Rx 1G port */ for (i = 0; i < MAX_NUM_RX_PORT_1G; i++) { port_id = RX_PORT_1G_BASE + i - 1; /* max tasks=4, max dma=1, no extra */ out_be32(&bmi->fmbm_pp[port_id], FMBM_PP_MXT(4)); /* FIFO size - 4KB, no extra */ out_be32(&bmi->fmbm_pfs[port_id], FMBM_PFS_IFSZ(0xf)); } /* Tx 1G port FIFO size - 4KB, no extra */ for (i = 0; i < MAX_NUM_TX_PORT_1G; i++) { port_id = TX_PORT_1G_BASE + i - 1; /* max tasks=4, max dma=1, no extra */ out_be32(&bmi->fmbm_pp[port_id], FMBM_PP_MXT(4)); /* FIFO size - 4KB, no extra */ out_be32(&bmi->fmbm_pfs[port_id], FMBM_PFS_IFSZ(0xf)); } /* Rx 10G port */ port_id = RX_PORT_10G_BASE - 1; /* max tasks=12, max dma=3, no extra */ out_be32(&bmi->fmbm_pp[port_id], FMBM_PP_MXT(12) | FMBM_PP_MXD(3)); /* FIFO size - 4KB, no extra */ out_be32(&bmi->fmbm_pfs[port_id], FMBM_PFS_IFSZ(0xf)); /* Tx 10G port */ port_id = TX_PORT_10G_BASE - 1; /* max tasks=12, max dma=3, no extra */ out_be32(&bmi->fmbm_pp[port_id], FMBM_PP_MXT(12) | FMBM_PP_MXD(3)); /* FIFO size - 4KB, no extra */ out_be32(&bmi->fmbm_pfs[port_id], FMBM_PFS_IFSZ(0xf)); /* initialize internal buffers data base (linked list) */ out_be32(&bmi->fmbm_init, FMBM_INIT_START); return 0; }