diff options
author | Inaky Perez-Gonzalez <inaky@linux.intel.com> | 2009-02-28 18:42:54 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-02 06:10:28 -0500 |
commit | c747583d19d5d5147a9f0eae480c1fdbc84c4252 (patch) | |
tree | e0af269356987f4096eb44b659bb874431264294 /include/linux/wimax | |
parent | 61b8d2688a0cc9434b18144342c719f809691d72 (diff) |
wimax/i2400m: implement RX reorder support
Allow the device to give the driver RX data with reorder information.
When that is done, the device will indicate the driver if a packet has
to be held in a (sorted) queue. It will also tell the driver when held
packets have to be released to the OS.
This is done to improve the WiMAX-protocol level retransmission
support when missing frames are detected.
The code docs provide details about the implementation.
In general, this just hooks into the RX path in rx.c; if a packet with
the reorder bit in the RX header is detected, the reorder information
in the header is extracted and one of the four main reorder operations
are executed. In one case (queue) no packet will be delivered to the
networking stack, just queued, whereas in the others (reset, update_ws
and queue_update_ws), queued packet might be delivered depending on
the window start for the specific queue.
The modifications to files other than rx.c are:
- control.c: during device initialization, enable reordering support
if the rx_reorder_disabled module parameter is not enabled
- driver.c: expose a rx_reorder_disable module parameter and call
i2400m_rx_setup/release() to initialize/shutdown RX reorder
support.
- i2400m.h: introduce members in 'struct i2400m' needed for
implementing reorder support.
- linux/i2400m.h: introduce TLVs, commands and constant definitions
related to RX reorder
Last but not least, the rx reorder code includes an small circular log
where the last N reorder operations are recorded to be displayed in
case of inconsistency. Otherwise diagnosing issues would be almost
impossible.
Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/wimax')
-rw-r--r-- | include/linux/wimax/i2400m.h | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/include/linux/wimax/i2400m.h b/include/linux/wimax/i2400m.h index ad36e073a70c..d5148a7889a6 100644 --- a/include/linux/wimax/i2400m.h +++ b/include/linux/wimax/i2400m.h | |||
@@ -225,15 +225,16 @@ struct i2400m_pl_data_hdr { | |||
225 | /* | 225 | /* |
226 | * Payload for an extended data packet | 226 | * Payload for an extended data packet |
227 | * | 227 | * |
228 | * New in v1.4 | 228 | * New in fw v1.4 |
229 | * | 229 | * |
230 | * @reorder: if this payload has to be reorder or not (and how) | ||
230 | * @cs: the type of data in the packet, as defined per (802.16e | 231 | * @cs: the type of data in the packet, as defined per (802.16e |
231 | * T11.13.19.1). Currently only 2 (IPv4 packet) supported. | 232 | * T11.13.19.1). Currently only 2 (IPv4 packet) supported. |
232 | * | 233 | * |
233 | * This is prefixed to each and every INCOMING DATA packet. | 234 | * This is prefixed to each and every INCOMING DATA packet. |
234 | */ | 235 | */ |
235 | struct i2400m_pl_edata_hdr { | 236 | struct i2400m_pl_edata_hdr { |
236 | __le32 reorder; | 237 | __le32 reorder; /* bits defined in i2400m_ro */ |
237 | __u8 cs; | 238 | __u8 cs; |
238 | __u8 reserved[11]; | 239 | __u8 reserved[11]; |
239 | } __attribute__((packed)); | 240 | } __attribute__((packed)); |
@@ -243,8 +244,23 @@ enum i2400m_cs { | |||
243 | I2400M_CS_IPV4 = 2, | 244 | I2400M_CS_IPV4 = 2, |
244 | }; | 245 | }; |
245 | 246 | ||
246 | enum i2400m_reorder { | 247 | enum i2400m_ro { |
247 | I2400M_REORDER_NEEDED = 0x01, | 248 | I2400M_RO_NEEDED = 0x01, |
249 | I2400M_RO_TYPE = 0x03, | ||
250 | I2400M_RO_TYPE_SHIFT = 1, | ||
251 | I2400M_RO_CIN = 0x0f, | ||
252 | I2400M_RO_CIN_SHIFT = 4, | ||
253 | I2400M_RO_FBN = 0x07ff, | ||
254 | I2400M_RO_FBN_SHIFT = 8, | ||
255 | I2400M_RO_SN = 0x07ff, | ||
256 | I2400M_RO_SN_SHIFT = 21, | ||
257 | }; | ||
258 | |||
259 | enum i2400m_ro_type { | ||
260 | I2400M_RO_TYPE_RESET = 0, | ||
261 | I2400M_RO_TYPE_PACKET, | ||
262 | I2400M_RO_TYPE_WS, | ||
263 | I2400M_RO_TYPE_PACKET_WS, | ||
248 | }; | 264 | }; |
249 | 265 | ||
250 | 266 | ||
@@ -410,6 +426,7 @@ enum i2400m_tlv { | |||
410 | I2400M_TLV_CONFIG_IDLE_PARAMETERS = 601, | 426 | I2400M_TLV_CONFIG_IDLE_PARAMETERS = 601, |
411 | I2400M_TLV_CONFIG_IDLE_TIMEOUT = 611, | 427 | I2400M_TLV_CONFIG_IDLE_TIMEOUT = 611, |
412 | I2400M_TLV_CONFIG_D2H_DATA_FORMAT = 614, | 428 | I2400M_TLV_CONFIG_D2H_DATA_FORMAT = 614, |
429 | I2400M_TLV_CONFIG_DL_HOST_REORDER = 615, | ||
413 | }; | 430 | }; |
414 | 431 | ||
415 | 432 | ||
@@ -553,5 +570,12 @@ struct i2400m_tlv_config_d2h_data_format { | |||
553 | __u8 reserved[3]; | 570 | __u8 reserved[3]; |
554 | } __attribute__((packed)); | 571 | } __attribute__((packed)); |
555 | 572 | ||
573 | /* New in v1.4 */ | ||
574 | struct i2400m_tlv_config_dl_host_reorder { | ||
575 | struct i2400m_tlv_hdr hdr; | ||
576 | __u8 reorder; /* 0 disabled, 1 enabled */ | ||
577 | __u8 reserved[3]; | ||
578 | } __attribute__((packed)); | ||
579 | |||
556 | 580 | ||
557 | #endif /* #ifndef __LINUX__WIMAX__I2400M_H__ */ | 581 | #endif /* #ifndef __LINUX__WIMAX__I2400M_H__ */ |