/** * Free a work queue entry received in a intercept callback. * * @param work_queue_entry * Work queue entry to free * @return Zero on success, Negative on failure. */ int cvm_oct_free_work(void *work_queue_entry) { cvmx_wqe_t *work = work_queue_entry; int segments = work->word2.s.bufs; cvmx_buf_ptr_t segment_ptr = work->packet_ptr; while (segments--) { cvmx_buf_ptr_t next_ptr = *(cvmx_buf_ptr_t *)cvmx_phys_to_ptr(segment_ptr.s.addr-8); if (__predict_false(!segment_ptr.s.i)) cvmx_fpa_free(cvm_oct_get_buffer_ptr(segment_ptr), segment_ptr.s.pool, DONT_WRITEBACK(CVMX_FPA_PACKET_POOL_SIZE/128)); segment_ptr = next_ptr; } cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1)); return 0; }
/** * Fill the supplied hardware pool with mbufs * * @param pool Pool to allocate an mbuf for * @param size Size of the buffer needed for the pool * @param elements Number of buffers to allocate */ int cvm_oct_mem_fill_fpa(int pool, int size, int elements) { int freed = elements; while (freed) { KASSERT(size <= MCLBYTES - 128, ("mbuf clusters are too small")); struct mbuf *m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (__predict_false(m == NULL)) { printf("Failed to allocate mbuf for hardware pool %d\n", pool); break; } m->m_data += 128 - (((uintptr_t)m->m_data) & 0x7f); *(struct mbuf **)(m->m_data - sizeof(void *)) = m; cvmx_fpa_free(m->m_data, pool, DONT_WRITEBACK(size/128)); freed--; } return (elements - freed); }
/** * Fill the supplied hardware pool with skbuffs * * @pool: Pool to allocate an skbuff for * @size: Size of the buffer needed for the pool * @elements: Number of buffers to allocate */ static int cvm_oct_fill_hw_skbuff(int pool, int size, int elements) { int freed = elements; while (freed) { struct sk_buff *skb = dev_alloc_skb(size + 128); if (unlikely(skb == NULL)) { pr_warning ("Failed to allocate skb for hardware pool %d\n", pool); break; } skb_reserve(skb, 128 - (((unsigned long)skb->data) & 0x7f)); *(struct sk_buff **)(skb->data - sizeof(void *)) = skb; cvmx_fpa_free(skb->data, pool, DONT_WRITEBACK(size / 128)); freed--; } return elements - freed; }