d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/*******************************************************************************
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi* bd_chain.h - bd chain interface
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi*******************************************************************************/
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#ifndef _BD_CHAIN_H
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#define _BD_CHAIN_H
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* The number of bd's per page including the last bd which is used as
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * a pointer to the next bd page. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#define BD_PER_PAGE(bd_size) (LM_PAGE_SIZE/(bd_size))
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* Number of bds that are used for the 'next' prt. The next ptr is constant size (sizeof lm_bd_chain_next). however,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * we will always work with 'full' bds. So if the bd-size is smaller than the next-ptr, we will use several, if it is
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * larger, we will use a full one (no partial bds...) The equation 1+((next_bd_size-1)/bd_size) gives us the number of bds
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * we need for this purpose. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#define NUM_BDS_USED_FOR_NEXT_PTR(bd_size,is_chain_mode) ((is_chain_mode)? (1 + ((sizeof(lm_bd_chain_next)-1) / (bd_size))): 0)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* The number of useable bd's per page. This number does not include the bds at the end of the page used for the 'next-bd' */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#define USABLE_BDS_PER_PAGE(bd_size,is_chain_mode) ((u32_t) (BD_PER_PAGE(bd_size)-NUM_BDS_USED_FOR_NEXT_PTR(bd_size,is_chain_mode)))
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* return number of available bds, i.e. _usable_ not produced bds */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static u16_t lm_bd_chain_avail_bds(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return bd_chain->bd_left;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* return the cyclic prod idx */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static u16_t lm_bd_chain_prod_idx(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return bd_chain->prod_idx;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* return the cyclic cons idx */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static u16_t lm_bd_chain_cons_idx(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return bd_chain->cons_idx;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* return the usable_bds_per_page */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static u16_t lm_bd_chain_usable_bds_per_page(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return bd_chain->usable_bds_per_page;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* return the page_cnt */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static u16_t lm_bd_chain_page_cnt(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return bd_chain->page_cnt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* return the bds_per_page */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static u16_t lm_bd_chain_bds_per_page(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return bd_chain->bds_per_page;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* return the bds_per_page_mask */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static u16_t lm_bd_chain_bds_per_page_mask(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return bd_chain->bds_per_page_mask;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* return the bds_skip_eop */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static u16_t lm_bd_chain_bds_skip_eop(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return bd_chain->bds_skip_eop;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* return empty state */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static u8_t lm_bd_chain_is_empty(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return (bd_chain->bd_left == 0);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* return full state */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static u8_t lm_bd_chain_is_full(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return (bd_chain->bd_left == bd_chain->capacity);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* returns the phys addr of the page of given page_idx. (page_idx >= 0) */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static lm_address_t lm_bd_chain_phys_addr(lm_bd_chain_t* bd_chain, u8_t page_idx)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_address_t mem_phys = bd_chain->bd_chain_phy;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t idx;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi page_idx = page_idx % bd_chain->page_cnt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (bd_chain->b_is_chain_mode)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* TODO: assumption that memory is contiguous.. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi for(idx = 0; idx < page_idx; idx++)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Increment mem_phy to the next page. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi LM_INC64(&mem_phys, LM_PAGE_SIZE);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi else
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi mem_phys = bd_chain->pbl_phys_addr_table[page_idx];
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return mem_phys;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/*******************************************************************************
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Description:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * afrer allocating the ring, this func fixes the last BD pointers at the
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * end of a page to point to the first BD in the next page.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Return:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ******************************************************************************/
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void lm_bd_chain_set_next_ptrs(lm_bd_chain_t * bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_address_t start_mem_phy;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_address_t mem_phy;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_chain_next * next_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t *start_mem_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t *mem_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u16_t idx;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi mem_virt = bd_chain->bd_chain_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi mem_phy = bd_chain->bd_chain_phy;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIf(
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ((u32_t) PTR_SUB(mem_virt, 0) & LM_PAGE_MASK) !=
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi (mem_phy.as_u32.low & LM_PAGE_MASK));
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIf(!bd_chain->b_is_chain_mode);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* make sure all known bds structure equals to lm_bd_chain_next structure before */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* tx bd */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC(OFFSETOF(struct eth_tx_next_bd, addr_hi) == OFFSETOF(lm_bd_chain_next, addr_hi)) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC(OFFSETOF(struct eth_tx_next_bd, addr_lo) == OFFSETOF(lm_bd_chain_next, addr_lo)) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC(OFFSETOF(struct eth_tx_next_bd, reserved)== OFFSETOF(lm_bd_chain_next, reserved) ) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* rx bd */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC(OFFSETOF(struct eth_rx_bd_next_page, addr_hi) == OFFSETOF(lm_bd_chain_next, addr_hi)) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC(OFFSETOF(struct eth_rx_bd_next_page, addr_lo) == OFFSETOF(lm_bd_chain_next, addr_lo)) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC(OFFSETOF(struct eth_rx_bd_next_page, reserved)== OFFSETOF(lm_bd_chain_next, reserved) ) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* rcq */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC(OFFSETOF(struct eth_rx_cqe_next_page, addr_hi) == OFFSETOF(lm_bd_chain_next, addr_hi)) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC(OFFSETOF(struct eth_rx_cqe_next_page, addr_lo) == OFFSETOF(lm_bd_chain_next, addr_lo)) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC(OFFSETOF(struct eth_rx_cqe_next_page, reserved)== OFFSETOF(lm_bd_chain_next, reserved) ) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Toe stuff */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC(OFFSETOF(struct toe_page_addr_bd, addr_hi) == OFFSETOF(lm_bd_chain_next, addr_hi)) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC(OFFSETOF(struct toe_page_addr_bd, addr_lo) == OFFSETOF(lm_bd_chain_next, addr_lo)) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC(OFFSETOF(struct toe_page_addr_bd, reserved)== OFFSETOF(lm_bd_chain_next, reserved) ) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi start_mem_phy = mem_phy;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi start_mem_virt = mem_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi for(idx = 0; idx < bd_chain->page_cnt-1; idx++)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if CHK_NULL(mem_virt)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIfAll(!mem_virt) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Increment mem_phy to the next page. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi LM_INC64(&mem_phy, LM_PAGE_SIZE);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Initialize the physical address of the next bd chain. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd = (lm_bd_chain_next *)(mem_virt + (bd_chain->bd_size) * (bd_chain->usable_bds_per_page));
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd->addr_hi = mm_cpu_to_le32(mem_phy.as_u32.high);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd->addr_lo = mm_cpu_to_le32(mem_phy.as_u32.low);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Initialize the virtual address of the next bd chain. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *((u8_t **) next_bd->reserved) = mem_virt + LM_PAGE_SIZE;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Move to the next bd chain. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi mem_virt += LM_PAGE_SIZE;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd = (lm_bd_chain_next *)(mem_virt + (bd_chain->bd_size) * (bd_chain->usable_bds_per_page));
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd->addr_hi = mm_cpu_to_le32(start_mem_phy.as_u32.high);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd->addr_lo = mm_cpu_to_le32(start_mem_phy.as_u32.low);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *((u8_t **) next_bd->reserved) = start_mem_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi} /* lm_bd_chain_set_next_ptrs */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* setup bd chain.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * - currently only physically contiguous chain format is supported
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * - */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchiunsigned long log2_align(unsigned long n);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static lm_status_t lm_bd_chain_add_page(
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi struct _lm_device_t *pdev,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_chain_t* bd_chain,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi void *mem_virt, /* ptr to caller pre-allocated buffer */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_address_t mem_phys, /* phys addr of buffer */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t bd_size, /* currently only 8 and 16 bytes are possible */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t is_chain_mode) /* Is the next pointer the last entry*/
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_chain_next * next_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi UNREFERENCED_PARAMETER_(pdev);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIf((bd_chain->page_cnt + 1) * BD_PER_PAGE(bd_size) > 0xffff);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (is_chain_mode)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (bd_chain->page_cnt) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u16_t page_index;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIf(bd_chain->bd_size != bd_size);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd = (lm_bd_chain_next *)((u8_t*)bd_chain->bd_chain_virt + (bd_chain->bd_size) * (bd_chain->usable_bds_per_page));
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi for (page_index = 0; page_index < bd_chain->page_cnt - 1; page_index++) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd = (lm_bd_chain_next *)((u8_t*)(*(void **)(next_bd->reserved)) + (bd_chain->bd_size) * (bd_chain->usable_bds_per_page));
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd->addr_hi = mm_cpu_to_le32(mem_phys.as_u32.high);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd->addr_lo = mm_cpu_to_le32(mem_phys.as_u32.low);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *((u8_t **) next_bd->reserved) = mem_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd = (lm_bd_chain_next *)((u8_t*)mem_virt + (bd_chain->bd_size) * (bd_chain->usable_bds_per_page));
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd->addr_hi = mm_cpu_to_le32(bd_chain->bd_chain_phy.as_u32.high);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd->addr_lo = mm_cpu_to_le32(bd_chain->bd_chain_phy.as_u32.low);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *((u8_t **) next_bd->reserved) = bd_chain->bd_chain_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi } else {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_chain_phy = mem_phys;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_chain_virt = mem_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_size = bd_size;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bds_skip_eop = NUM_BDS_USED_FOR_NEXT_PTR(bd_size,is_chain_mode);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->usable_bds_per_page = USABLE_BDS_PER_PAGE(bd_size,is_chain_mode);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bds_per_page = BD_PER_PAGE(bd_size);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->b_is_chain_mode = TRUE;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->num_bd_to_sub = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->usable_bds_mask = bd_chain->usable_bds_per_page;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* we assume power of 2 for bd_chain->bds_per_page */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIf(bd_chain->bds_per_page != log2_align((u32_t)bd_chain->bds_per_page));
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bds_per_page_mask = bd_chain->bds_per_page - 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->cons_idx = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->prod_idx = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->next_bd = bd_chain->bd_chain_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Initialize the physical address of the next bd chain. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd = (lm_bd_chain_next *)((u8_t*)mem_virt + (bd_chain->bd_size) * (bd_chain->usable_bds_per_page));
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd->addr_hi = mm_cpu_to_le32(mem_phys.as_u32.high);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bd->addr_lo = mm_cpu_to_le32(mem_phys.as_u32.low);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Initialize the virtual address of the next bd chain. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *((u8_t **) next_bd->reserved) = mem_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi else
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi //TODO: currently TOE only, implement for PBL
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // add the physical address of the page to the next pbl_page_idx
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // ensure that the pbl_virt in this case is valid..
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreak();
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->page_cnt++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->capacity = bd_chain->page_cnt * bd_chain->usable_bds_per_page;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_left = bd_chain->capacity;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return LM_STATUS_SUCCESS;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static lm_status_t lm_bd_chain_setup(
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi struct _lm_device_t *pdev,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_chain_t* bd_chain,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi void *mem_virt, /* ptr to caller pre-allocated buffer */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_address_t mem_phys, /* phys addr of buffer */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u16_t page_cnt, /* #pages in given buffer */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t bd_size, /* currently only 8 and 16 bytes are possible */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t is_full, /* chain initial state (full or empty) */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t is_chain_mode) /* Is the next pointer the last entry*/
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIf(page_cnt * BD_PER_PAGE(bd_size) > 0xffff);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi UNREFERENCED_PARAMETER_(pdev);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_chain_phy = mem_phys;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_chain_virt = mem_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_size = bd_size;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bds_skip_eop = NUM_BDS_USED_FOR_NEXT_PTR(bd_size,is_chain_mode);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->usable_bds_per_page = USABLE_BDS_PER_PAGE(bd_size,is_chain_mode);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bds_per_page = BD_PER_PAGE(bd_size);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* we assume power of 2 for bd_chain->bds_per_page */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIf(bd_chain->bds_per_page != log2_align((u32_t)bd_chain->bds_per_page));
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bds_per_page_mask = bd_chain->bds_per_page - 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#ifdef __SunOS
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /*
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * This minor code change fixes a compiler error in SunStudio 12u1. The
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * bug is that an "imulw $-0x80,..." is generated which wrecks the capacity
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * value specifically when initializing the FCoE EQ chain. Shifting code
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * around and/or removing the deep inline access to this function will fix
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * the issue but would be a kludge. Note that I've created this ifdef to
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * ensure someone doesn't come in later and merge these two lines together
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * thereby reverting it to what it was before.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->capacity = page_cnt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->capacity *= bd_chain->usable_bds_per_page;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#else
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->capacity = page_cnt * bd_chain->usable_bds_per_page;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#endif
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->page_cnt = page_cnt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->next_bd = bd_chain->bd_chain_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->cons_idx = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if(is_full) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->prod_idx = page_cnt * bd_chain->bds_per_page;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_left = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi } else {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->prod_idx = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Don't count the last bd of a BD page. A full BD chain must
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * have at least one empty entry. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_left = bd_chain->capacity;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if(is_chain_mode)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->b_is_chain_mode = TRUE;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->num_bd_to_sub = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->usable_bds_mask = bd_chain->usable_bds_per_page;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_chain_set_next_ptrs(bd_chain);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return LM_STATUS_SUCCESS;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static lm_status_t lm_bd_chain_pbl_set_ptrs(
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi IN void *buf_base_virt, /* ptr to caller pre-allocated buffer */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi IN lm_address_t buf_base_phy, /* phys addr of the pre-allocated buffer */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi IN lm_address_t *pbl_phys_table, /* ptr to caller pre-allocated buffer of phys pbl */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi IN void *pbl_virt_table, /* ptr to caller pre-allocated buffer of virt pbl */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi IN u32_t pbl_entries /* #pages in given buffer */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi )
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u32_t i;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (CHK_NULL(buf_base_virt) ||
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi CHK_NULL(pbl_phys_table) ||
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi CHK_NULL(pbl_virt_table) ||
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi (pbl_entries == 0))
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return LM_STATUS_INVALID_PARAMETER;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* fill page table elements */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi for (i = 0; i < pbl_entries; i++)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#ifdef BIG_ENDIAN
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi pbl_phys_table[i].as_u32.low = mm_cpu_to_le32(buf_base_phy.as_u32.high);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi pbl_phys_table[i].as_u32.high = mm_cpu_to_le32(buf_base_phy.as_u32.low);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#else // LITTLE_ENDIAN
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi pbl_phys_table[i].as_u64 = buf_base_phy.as_u64;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#endif
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *(void **)(((u8_t *)pbl_virt_table + (sizeof(void *) * i))) = buf_base_virt;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* Increment mem_phy to the next page. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* TODO: assumption that memory is contiguous.. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi LM_INC64(&buf_base_phy, LM_PAGE_SIZE);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi buf_base_virt = (u8_t *)buf_base_virt + LM_PAGE_SIZE;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return LM_STATUS_SUCCESS;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static lm_status_t lm_bd_chain_pbl_setup(
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi struct _lm_device_t *pdev,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_chain_t* bd_chain,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi void *mem_virt, /* ptr to caller pre-allocated buffer */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_address_t mem_phys, /* phys addr of buffer */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi void *pbl_virt_table, /* ptr to caller pre-allocated buffer of virt pbl */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_address_t *pbl_phys_table, /* ptr to caller pre-allocated buffer of phys pbl */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u16_t page_cnt, /* #pages in given buffer */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t bd_size, /* currently only 8 and 16 bytes are possible */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t is_full) /* chain initial state (full or empty) */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_status_t lm_status;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_status = lm_bd_chain_setup(pdev,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi mem_virt,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi mem_phys,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi page_cnt,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_size,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi is_full,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi FALSE);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (lm_status != LM_STATUS_SUCCESS)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return lm_status;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi //assign additional pbl members
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->pbl_phys_addr_table = pbl_phys_table;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->pbl_virt_addr_table = pbl_virt_table;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->b_is_chain_mode = FALSE;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->num_bd_to_sub = 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->usable_bds_mask = bd_chain->usable_bds_per_page - 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // Upon first be consume or produce, page will be advanced,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi // so set the initial page index to the last one
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->pbe_idx = page_cnt - 1;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_status = lm_bd_chain_pbl_set_ptrs(mem_virt,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi mem_phys,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->pbl_phys_addr_table,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->pbl_virt_addr_table,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi page_cnt);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (lm_status != LM_STATUS_SUCCESS)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return lm_status;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return LM_STATUS_SUCCESS;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/** Description
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Function resets a bd chain: initializes the bds to 'all zeros'
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * chain remains valid though, (last bd points to the next page of the bd chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void lm_bd_chain_reset(struct _lm_device_t * pdev, lm_bd_chain_t * bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIf(!bd_chain->bd_chain_virt);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* FIXME: assumption that memory is contiguous.. */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi mm_memset(bd_chain->bd_chain_virt, 0, bd_chain->page_cnt * LM_PAGE_SIZE);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (bd_chain->b_is_chain_mode)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_chain_setup(pdev,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_chain_virt,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_chain_phy,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->page_cnt,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_size,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi FALSE,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->b_is_chain_mode);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi else
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_chain_pbl_setup(pdev,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_chain_virt,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_chain_phy,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->pbl_virt_addr_table,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->pbl_phys_addr_table,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->page_cnt,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_size,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi FALSE);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* Receives a bd_idx, pointer to bd and increases them.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * the physical address is the physical address of the base of the page
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Assumptions:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * - virt is initialized with the virtual address of the current bd
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * - phys is initialized with the physical address of the current page
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void lm_bd_chain_incr_bd(
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_chain_t * bd_chain,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_address_t * phys,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi void ** virt,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u16_t * bd_idx)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi (*bd_idx)++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *virt = ((char *)*virt) + bd_chain->bd_size;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if((*bd_idx & bd_chain->usable_bds_per_page) == bd_chain->usable_bds_per_page) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (bd_chain->b_is_chain_mode) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_chain_next *next_bd = (lm_bd_chain_next *)(*virt);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi (*bd_idx) += bd_chain->bds_skip_eop;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *virt = *(void **)(next_bd->reserved);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi phys->as_u32.high = next_bd->addr_hi;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi phys->as_u32.low = next_bd->addr_lo;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi } else {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi //TODO: currently TOE only, implement for PBL
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreak();
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void lm_bd_advance_page(lm_bd_chain_t* bd_chain, u16_t *idx_to_inc)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (bd_chain->b_is_chain_mode)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_chain_next *next_bd = (lm_bd_chain_next *)bd_chain->next_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->next_bd = *(void **)(next_bd->reserved);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi *idx_to_inc += bd_chain->bds_skip_eop;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi else
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->pbe_idx++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if (bd_chain->pbe_idx == bd_chain->page_cnt) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->pbe_idx = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->next_bd = *(void **)((u8_t *)bd_chain->pbl_virt_addr_table + (sizeof(void *) * bd_chain->pbe_idx));
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/*******************************************************************************
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi* API For a bd-chain that the driver "Produces"
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi*******************************************************************************/
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* update bds availabily.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * - nbds - number of _usable_ consumed bds
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * - NOTE: the chain consumer idx+pointer are not maintained! */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void lm_bd_chain_bds_consumed(lm_bd_chain_t* bd_chain, u16_t nbds)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_left += nbds;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIfFastPath(bd_chain->bd_left > bd_chain->capacity);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* returns ptr to next _usable_ bd to be produced,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * decreases bds availability by 1, and updates prod idx.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * NOTE: special case for TOE: prod idx jumps to the next page only when the first bd of the next page is produced */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void *lm_toe_bd_chain_produce_bd(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi void *ret_bd = NULL;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u16_t prod_idx = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIf(!bd_chain->bd_left);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi prod_idx = bd_chain->prod_idx - bd_chain->num_bd_to_sub;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if((prod_idx & bd_chain->usable_bds_mask) == bd_chain->usable_bds_mask) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_advance_page(bd_chain, &bd_chain->prod_idx);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ret_bd = bd_chain->next_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_left--;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->prod_idx++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->next_bd += bd_chain->bd_size;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return ret_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* returns ptr to next _usable_ bd to be produced,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * decreases bds availability by 1, and updates prod idx.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void *lm_bd_chain_produce_bd(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi void *ret_bd = NULL;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u16_t prod_idx = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIfFastPath(!bd_chain->bd_left);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ret_bd = bd_chain->next_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_left--;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->prod_idx++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->next_bd += bd_chain->bd_size;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi prod_idx = bd_chain->prod_idx - bd_chain->num_bd_to_sub;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if((prod_idx & bd_chain->usable_bds_mask) == bd_chain->usable_bds_mask) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_advance_page(bd_chain, &bd_chain->prod_idx);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return ret_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/*******************************************************************************
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi* API For a bd-chain that the driver "Consumes"
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi*******************************************************************************/
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* returns ptr to next _usable_ bd to be consume,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * increases bds availability by 1, and updates cons idx.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * NOTE: cons idx jumps to the next page only when the first bd of the next page is consumed */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void *lm_toe_bd_chain_consume_bd(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi void *ret_bd = NULL;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u16_t cons_idx = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIf(bd_chain->bd_left == bd_chain->capacity);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi cons_idx = bd_chain->cons_idx - bd_chain->num_bd_to_sub;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if((cons_idx & bd_chain->usable_bds_mask) == bd_chain->usable_bds_mask) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_advance_page(bd_chain, &bd_chain->cons_idx);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ret_bd = bd_chain->next_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_left++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->cons_idx++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->next_bd += bd_chain->bd_size;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return ret_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void *lm_bd_chain_consume_bd(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi void *ret_bd = NULL;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u16_t cons_idx = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIfFastPath(bd_chain->bd_left == bd_chain->capacity);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ret_bd = bd_chain->next_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_left++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->cons_idx++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->next_bd += bd_chain->bd_size;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi cons_idx = bd_chain->cons_idx - bd_chain->num_bd_to_sub;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if((cons_idx & bd_chain->usable_bds_mask) == bd_chain->usable_bds_mask) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_advance_page(bd_chain, &bd_chain->cons_idx);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return ret_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* returns a bd only if it is contiguous to the previously requested bd... otherwise NULL.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * The algorithm is based on the fact that we don't double-increase a consumer if we've reached the
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * end of the page. we have one call that is called when the next_bd points to the last_bd, in which case
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * we recognize that the next_bd is no longer contiguous, return NULL and move forward. The next call will
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * return the next bd...
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void *lm_bd_chain_consume_bd_contiguous(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi void *ret_bd = NULL;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u16_t cons_idx = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIf(bd_chain->bd_left == bd_chain->capacity);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi cons_idx = bd_chain->cons_idx - bd_chain->num_bd_to_sub;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if((cons_idx & bd_chain->usable_bds_mask) == bd_chain->usable_bds_mask) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_advance_page(bd_chain, &bd_chain->cons_idx);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return NULL; /* we've just skipped the last bd... */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ret_bd = bd_chain->next_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_left++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->cons_idx++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->next_bd += bd_chain->bd_size;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return ret_bd;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* update bds availabily and prod idx.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * - nbds - number of _usable_ produced bds
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * Special case for TOE, they need producer increased only if we've moved to the next page... */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void lm_toe_bd_chain_bds_produced(lm_bd_chain_t* bd_chain, u16_t nbds)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u16_t nbds_mod_usable_bds;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t next_bds = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIfFastPath(bd_chain->bd_left < nbds);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_left -= nbds;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* perform the operation "nbds % bd_chain->usable_bds_per_page" manually
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi (in order to avoid explicit modulo instruction that lead to very
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi expensive IDIV asm instruction) */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi nbds_mod_usable_bds = nbds;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi while (nbds_mod_usable_bds >= bd_chain->usable_bds_per_page)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi nbds_mod_usable_bds -= bd_chain->usable_bds_per_page;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* calculate the number of _next_ bds passed */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bds += nbds / bd_chain->usable_bds_per_page;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if(next_bds && ((bd_chain->prod_idx & bd_chain->bds_per_page_mask) == 0)) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bds--; /* special care here, this next bd will be counted only next time bds are produced */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if((bd_chain->prod_idx & bd_chain->bds_per_page_mask) + nbds_mod_usable_bds > bd_chain->usable_bds_per_page) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bds++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* update prod idx */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->prod_idx += nbds + next_bds * bd_chain->bds_skip_eop;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIfFastPath((bd_chain->prod_idx & bd_chain->bds_per_page_mask) > bd_chain->usable_bds_per_page); /* assertion relevant to 8b bd chain */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIfFastPath((bd_chain->prod_idx & bd_chain->bds_per_page_mask) == 0); /* GilR 5/13/2006 - this is currently the agreement with FW */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* update bds availabily and prod idx.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi * - nbds - number of _usable_ produced bds */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void lm_bd_chain_bds_produced(lm_bd_chain_t* bd_chain, u16_t nbds)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u16_t nbds_mod_usable_bds;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t next_bds = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIfFastPath(bd_chain->bd_left < nbds);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_left -= nbds;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* perform the operation "nbds % bd_chain->usable_bds_per_page" manually
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi (in order to avoid explicit modulo instruction that lead to very
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi expensive IDIV asm instruction) */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi nbds_mod_usable_bds = nbds;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi while (nbds_mod_usable_bds >= bd_chain->usable_bds_per_page)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi nbds_mod_usable_bds -= bd_chain->usable_bds_per_page;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* calculate the number of _next_ bds passed */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bds += nbds / bd_chain->usable_bds_per_page;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if((bd_chain->prod_idx & bd_chain->bds_per_page_mask) + nbds_mod_usable_bds > bd_chain->usable_bds_per_page) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi next_bds++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* update prod idx */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->prod_idx += nbds + next_bds * bd_chain->bds_skip_eop;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* lm_bd_chain_bd_produced -
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi a performance optimated version of lm_bd_chain_bds_produced:
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi update bds availabily and prod idx, when only one bd is produced.
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static void lm_bd_chain_bd_produced(lm_bd_chain_t* bd_chain)
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi DbgBreakIfFastPath(bd_chain->bd_left < 1);
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->bd_left--;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* if we passed a _next_ bd, increase prod_idx accordingly */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi if((bd_chain->prod_idx & bd_chain->bds_per_page_mask) + 1 > bd_chain->usable_bds_per_page) {
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->prod_idx += bd_chain->bds_skip_eop;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi }
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi /* update prod idx for the produced bd */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi bd_chain->prod_idx++;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi/* TRUE if all params in bd_chains are equal but the pointers */
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi__inline static u8_t lm_bd_chains_are_consistent( lm_bd_chain_t* bd_chain,
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi lm_bd_chain_t* bd_chain2 )
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi{
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi const u32_t cmp_size = OFFSETOF(lm_bd_chain_t, reserved) - OFFSETOF(lm_bd_chain_t, page_cnt) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi u8_t b_ret = 0;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi ASSERT_STATIC( OFFSETOF(lm_bd_chain_t, page_cnt) < OFFSETOF(lm_bd_chain_t, reserved)) ;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi b_ret = mm_memcmp( (u8_t*)bd_chain + OFFSETOF(lm_bd_chain_t, page_cnt),
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi (u8_t*)bd_chain2 + OFFSETOF(lm_bd_chain_t, page_cnt),
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi cmp_size );
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi return b_ret;
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi}
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi
d14abf155341d55053c76eeec58b787a456b753bRobert Mustacchi#endif /* _BD_CHAIN_H */