Commit e623d625 authored by chas williams - CONTRACTOR's avatar chas williams - CONTRACTOR Committed by David S. Miller

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: default avatarChas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1d927870
This diff is collapsed.
...@@ -198,26 +198,33 @@ struct he_hsp { ...@@ -198,26 +198,33 @@ struct he_hsp {
} group[HE_NUM_GROUPS]; } 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 { struct he_rbp {
volatile u32 phys; volatile u32 phys;
volatile u32 status; volatile u32 idx; /* virt */
}; };
/* NOTE: it is suggested that virt be the virtual address of the host #define RBP_IDX_OFFSET 6
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. * the he dma engine will try to hold an extra 16 buffers in its local
*/ * caches. and add a couple buffers for safety.
*/
#define RBP_INDEX_OFF 6 #define RBPL_TABLE_SIZE (CONFIG_RBPL_SIZE + 16 + 2)
#define RBP_INDEX(x) (((long)(x) >> RBP_INDEX_OFF) & 0xffff)
#define RBP_LOANED 0x80000000
#define RBP_SMALLBUF 0x40000000
struct he_virt { struct he_buff {
void *virt; struct list_head entry;
dma_addr_t mapping;
unsigned long len;
u8 data[];
}; };
#ifdef notyet #ifdef notyet
...@@ -286,10 +293,13 @@ struct he_dev { ...@@ -286,10 +293,13 @@ struct he_dev {
struct he_rbrq *rbrq_base, *rbrq_head; struct he_rbrq *rbrq_base, *rbrq_head;
int rbrq_peak; int rbrq_peak;
struct he_buff **rbpl_virt;
unsigned long *rbpl_table;
unsigned long rbpl_hint;
struct pci_pool *rbpl_pool; struct pci_pool *rbpl_pool;
dma_addr_t rbpl_phys; dma_addr_t rbpl_phys;
struct he_rbp *rbpl_base, *rbpl_tail; struct he_rbp *rbpl_base, *rbpl_tail;
struct he_virt *rbpl_virt; struct list_head rbpl_outstanding;
int rbpl_peak; int rbpl_peak;
dma_addr_t tbrq_phys; dma_addr_t tbrq_phys;
...@@ -304,20 +314,12 @@ struct he_dev { ...@@ -304,20 +314,12 @@ struct he_dev {
struct he_dev *next; struct he_dev *next;
}; };
struct he_iovec
{
u32 iov_base;
u32 iov_len;
};
#define HE_MAXIOV 20 #define HE_MAXIOV 20
struct he_vcc struct he_vcc
{ {
struct he_iovec iov_head[HE_MAXIOV]; struct list_head buffers;
struct he_iovec *iov_tail;
int pdu_len; int pdu_len;
int rc_index; int rc_index;
wait_queue_head_t rx_waitq; wait_queue_head_t rx_waitq;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment