Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 150875
b: refs/heads/master
c: 2971a5b
h: refs/heads/master
i:
  150873: 8d340f4
  150871: 9e569e2
v: v3
  • Loading branch information
Inaky Perez-Gonzalez committed Jun 11, 2009
1 parent 5c9cb44 commit 7ba3fb8
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c56affafdd29eb9764b0e35e3434cc06f6bc3781
refs/heads/master: 2971a5bac8cab3cb56f19e9c494ecb3b120c5199
58 changes: 56 additions & 2 deletions trunk/drivers/net/wimax/i2400m/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,48 @@ enum {

#define TAIL_FULL ((void *)~(unsigned long)NULL)

/*
* Calculate how much tail room is available
*
* Note the trick here. This path is ONLY caleed for Case A (see
* i2400m_tx_fifo_push() below), where we have:
*
* Case A
* N ___________
* | tail room |
* | |
* |<- IN ->|
* | |
* | data |
* | |
* |<- OUT ->|
* | |
* | head room |
* 0 -----------
*
* When calculating the tail_room, tx_in might get to be zero if
* i2400m->tx_in is right at the end of the buffer (really full
* buffer) if there is no head room. In this case, tail_room would be
* I2400M_TX_BUF_SIZE, although it is actually zero. Hence the final
* mod (%) operation. However, when doing this kind of optimization,
* i2400m->tx_in being zero would fail, so we treat is an a special
* case.
*/
static inline
size_t __i2400m_tx_tail_room(struct i2400m *i2400m)
{
size_t tail_room;
size_t tx_in;

if (unlikely(i2400m->tx_in) == 0)
return I2400M_TX_BUF_SIZE;
tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE;
tail_room = I2400M_TX_BUF_SIZE - tx_in;
tail_room %= I2400M_TX_BUF_SIZE;
return tail_room;
}


/*
* Allocate @size bytes in the TX fifo, return a pointer to it
*
Expand Down Expand Up @@ -338,7 +380,7 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
return NULL;
}
/* Is there space at the tail? */
tail_room = I2400M_TX_BUF_SIZE - i2400m->tx_in % I2400M_TX_BUF_SIZE;
tail_room = __i2400m_tx_tail_room(i2400m);
if (tail_room < needed_size) {
if (i2400m->tx_out % I2400M_TX_BUF_SIZE
< i2400m->tx_in % I2400M_TX_BUF_SIZE) {
Expand Down Expand Up @@ -367,17 +409,29 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
* (I2400M_PL_PAD for the payloads, I2400M_TX_PLD_SIZE for the
* header).
*
* Tail room can get to be zero if a message was opened when there was
* space only for a header. _tx_close() will mark it as to-skip (as it
* will have no payloads) and there will be no more space to flush, so
* nothing has to be done here. This is probably cheaper than ensuring
* in _tx_new() that there is some space for payloads...as we could
* always possibly hit the same problem if the payload wouldn't fit.
*
* Note:
*
* Assumes i2400m->tx_lock is taken, and we use that as a barrier
*
* This path is only taken for Case A FIFO situations [see
* i2400m_tx_fifo_push()]
*/
static
void i2400m_tx_skip_tail(struct i2400m *i2400m)
{
struct device *dev = i2400m_dev(i2400m);
size_t tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE;
size_t tail_room = I2400M_TX_BUF_SIZE - tx_in;
size_t tail_room = __i2400m_tx_tail_room(i2400m);
struct i2400m_msg_hdr *msg = i2400m->tx_buf + tx_in;
if (unlikely(tail_room == 0))
return;
BUG_ON(tail_room < sizeof(*msg));
msg->size = tail_room | I2400M_TX_SKIP;
d_printf(2, dev, "skip tail: skipping %zu bytes @%zu\n",
Expand Down

0 comments on commit 7ba3fb8

Please sign in to comment.