aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wimax
diff options
context:
space:
mode:
authorPrasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>2010-01-26 21:44:45 -0500
committerInaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>2010-05-11 17:03:52 -0400
commit570eb0ea65db625e0b11ca97f4ae857bc1193250 (patch)
tree15f97dda1d474fe08beb3013c7d51701e70e1531 /drivers/net/wimax
parent080de04e6229c49be41b811f5d5429afd6ed736d (diff)
wimax/i2400m: fix insufficient size of Tx buffer for 12 payload of 1400 MTU.
This patch increases the Tx buffer size so as to accommodate 12 payloads of 1408 (1400 MTU 16 bytes aligned). Currently Tx buffer is 32 KiB which is insufficient to accommodate 12 payloads of 1408 size. This patch - increases I2400M_TX_BUF_SIZE from 32KiB to 64KiB - Adds a BUILD_BUG_ON if the calculated buffer size based on the given MTU exceeds the I2400M_TX_BUF_SIZE. Below is how we calculate the size of the Tx buffer. Payload + 4 bytes prefix for each payload (1400 MTU 16 bytes boundary aligned) = (1408 + sizeof(struct i2400m_pl_data_hdr)) * I2400M_TX_PLD_MAX Adding 16 byte message header = + sizeof(struct i2400m_msg_hdr) Aligning to 256 byte boundary Total Tx buffer = (((((1408 + sizeof(struct i2400m_pl_data_hdr)) * I2400M_TX_PLD_MAX )+ sizeof(struct i2400m_msg_hdr)) / 256) + 1) * 256 * 2 Signed-off-by: Prasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com> Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Diffstat (limited to 'drivers/net/wimax')
-rw-r--r--drivers/net/wimax/i2400m/tx.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c
index fab27e4a4cb3..8561c0766535 100644
--- a/drivers/net/wimax/i2400m/tx.c
+++ b/drivers/net/wimax/i2400m/tx.c
@@ -258,8 +258,10 @@ enum {
258 * Doc says maximum transaction is 16KiB. If we had 16KiB en 258 * Doc says maximum transaction is 16KiB. If we had 16KiB en
259 * route and 16KiB being queued, it boils down to needing 259 * route and 16KiB being queued, it boils down to needing
260 * 32KiB. 260 * 32KiB.
261 * 32KiB is insufficient for 1400 MTU, hence increasing
262 * tx buffer size to 64KiB.
261 */ 263 */
262 I2400M_TX_BUF_SIZE = 32768, 264 I2400M_TX_BUF_SIZE = 65536,
263 /** 265 /**
264 * Message header and payload descriptors have to be 16 266 * Message header and payload descriptors have to be 16
265 * aligned (16 + 4 * N = 16 * M). If we take that average sent 267 * aligned (16 + 4 * N = 16 * M). If we take that average sent
@@ -274,6 +276,19 @@ enum {
274 I2400M_TX_PLD_SIZE = sizeof(struct i2400m_msg_hdr) 276 I2400M_TX_PLD_SIZE = sizeof(struct i2400m_msg_hdr)
275 + I2400M_TX_PLD_MAX * sizeof(struct i2400m_pld), 277 + I2400M_TX_PLD_MAX * sizeof(struct i2400m_pld),
276 I2400M_TX_SKIP = 0x80000000, 278 I2400M_TX_SKIP = 0x80000000,
279 /*
280 * 16 byte aligned MAX_MTU + 4 byte payload prefix.
281 */
282 I2400M_MAX_MTU_ALIGN = 16,
283 I2400M_TX_PDU_SIZE = I2400M_MAX_MTU % I2400M_MAX_MTU_ALIGN
284 + I2400M_MAX_MTU + sizeof(struct i2400m_pl_data_hdr),
285 /*
286 * 256 byte aligned toal size of 12 PDUs including msg header,
287 */
288 I2400M_TX_PDU_ALIGN = 256,
289 I2400M_TX_PDU_TOTAL_SIZE = ((I2400M_TX_PDU_SIZE * I2400M_TX_PLD_MAX
290 + sizeof(struct i2400m_msg_hdr))/I2400M_TX_PDU_ALIGN + 1)
291 * I2400M_TX_PDU_ALIGN * 2,
277}; 292};
278 293
279#define TAIL_FULL ((void *)~(unsigned long)NULL) 294#define TAIL_FULL ((void *)~(unsigned long)NULL)
@@ -874,6 +889,8 @@ int i2400m_tx_setup(struct i2400m *i2400m)
874 INIT_WORK(&i2400m->wake_tx_ws, i2400m_wake_tx_work); 889 INIT_WORK(&i2400m->wake_tx_ws, i2400m_wake_tx_work);
875 890
876 i2400m->tx_sequence = 0; 891 i2400m->tx_sequence = 0;
892 /* Warn if the calculated buffer size exceeds I2400M_TX_BUF_SIZE. */
893 BUILD_BUG_ON(I2400M_TX_PDU_TOTAL_SIZE > I2400M_TX_BUF_SIZE);
877 i2400m->tx_buf = kmalloc(I2400M_TX_BUF_SIZE, GFP_KERNEL); 894 i2400m->tx_buf = kmalloc(I2400M_TX_BUF_SIZE, GFP_KERNEL);
878 if (i2400m->tx_buf == NULL) 895 if (i2400m->tx_buf == NULL)
879 result = -ENOMEM; 896 result = -ENOMEM;