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>
diff --git a/drivers/atm/he.h b/drivers/atm/he.h
index 8bf3264..110a27d 100644
--- a/drivers/atm/he.h
+++ b/drivers/atm/he.h
@@ -198,26 +198,33 @@
} 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_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 *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;