atm: [he] rewrite buffer handling in receive path
Instead of a fixed list of buffers, use the buffer pool correctly and keep track of the outstanding buffer indexes using a fixed table. Resolves reported HBUF_ERR's -- failures due to lack of receive buffers. Signed-off-by: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
1d927870e5
commit
e623d62512
@@ -198,26 +198,33 @@ struct he_hsp {
|
||||
} group[HE_NUM_GROUPS];
|
||||
};
|
||||
|
||||
/* figure 2.9 receive buffer pools */
|
||||
/*
|
||||
* figure 2.9 receive buffer pools
|
||||
*
|
||||
* since a virtual address might be more than 32 bits, we store an index
|
||||
* in the virt member of he_rbp. NOTE: the lower six bits in the rbrq
|
||||
* addr member are used for buffer status further limiting us to 26 bits.
|
||||
*/
|
||||
|
||||
struct he_rbp {
|
||||
volatile u32 phys;
|
||||
volatile u32 status;
|
||||
volatile u32 idx; /* virt */
|
||||
};
|
||||
|
||||
/* NOTE: it is suggested that virt be the virtual address of the host
|
||||
buffer. on a 64-bit machine, this would not work. Instead, we
|
||||
store the real virtual address in another list, and store an index
|
||||
(and buffer status) in the virt member.
|
||||
*/
|
||||
#define RBP_IDX_OFFSET 6
|
||||
|
||||
#define RBP_INDEX_OFF 6
|
||||
#define RBP_INDEX(x) (((long)(x) >> RBP_INDEX_OFF) & 0xffff)
|
||||
#define RBP_LOANED 0x80000000
|
||||
#define RBP_SMALLBUF 0x40000000
|
||||
/*
|
||||
* the he dma engine will try to hold an extra 16 buffers in its local
|
||||
* caches. and add a couple buffers for safety.
|
||||
*/
|
||||
|
||||
struct he_virt {
|
||||
void *virt;
|
||||
#define RBPL_TABLE_SIZE (CONFIG_RBPL_SIZE + 16 + 2)
|
||||
|
||||
struct he_buff {
|
||||
struct list_head entry;
|
||||
dma_addr_t mapping;
|
||||
unsigned long len;
|
||||
u8 data[];
|
||||
};
|
||||
|
||||
#ifdef notyet
|
||||
@@ -286,10 +293,13 @@ struct he_dev {
|
||||
struct he_rbrq *rbrq_base, *rbrq_head;
|
||||
int rbrq_peak;
|
||||
|
||||
struct he_buff **rbpl_virt;
|
||||
unsigned long *rbpl_table;
|
||||
unsigned long rbpl_hint;
|
||||
struct pci_pool *rbpl_pool;
|
||||
dma_addr_t rbpl_phys;
|
||||
struct he_rbp *rbpl_base, *rbpl_tail;
|
||||
struct he_virt *rbpl_virt;
|
||||
struct list_head rbpl_outstanding;
|
||||
int rbpl_peak;
|
||||
|
||||
dma_addr_t tbrq_phys;
|
||||
@@ -304,20 +314,12 @@ struct he_dev {
|
||||
struct he_dev *next;
|
||||
};
|
||||
|
||||
struct he_iovec
|
||||
{
|
||||
u32 iov_base;
|
||||
u32 iov_len;
|
||||
};
|
||||
|
||||
#define HE_MAXIOV 20
|
||||
|
||||
struct he_vcc
|
||||
{
|
||||
struct he_iovec iov_head[HE_MAXIOV];
|
||||
struct he_iovec *iov_tail;
|
||||
struct list_head buffers;
|
||||
int pdu_len;
|
||||
|
||||
int rc_index;
|
||||
|
||||
wait_queue_head_t rx_waitq;
|
||||
|
||||
Reference in New Issue
Block a user