1. 12 5月, 2010 17 次提交
    • P
      wimax/i2400m: fix incorrect handling of type 2 and 3 RX messages · 0809a7bb
      Prasanna S. Panchamukhi 提交于
      According to Intel Wimax i3200, i5x50 and i6x60 device specification documents,
      the host driver must not reset the device if the normalized sequence numbers
      are greater than 1023 for type 2 and type 3 RX messages.
      This patch removes the code that incorrectly used to reset the device.
      Signed-off-by: NPrasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
      0809a7bb
    • P
      wimax i2400m: fix race condition while accessing rx_roq by using kref count · d11a6e44
      Prasanna S. Panchamukhi 提交于
      This patch fixes the race condition when one thread tries to destroy
      the memory allocated for rx_roq, while another thread still happen
      to access rx_roq.
      Such a race condition occurs when i2400m-sdio kernel module gets
      unloaded, destroying the memory allocated for rx_roq while rx_roq
      is accessed by i2400m_rx_edata(), as explained below:
      $thread1                                $thread2
      $ void i2400m_rx_edata()                $
      $Access rx_roq[]                        $
      $roq = &i2400m->rx_roq[ro_cin]          $
      $ i2400m_roq_[reset/queue/update_ws]    $
      $                                       $ void i2400m_rx_release();
      $                                       $kfree(rx->roq);
      $                                       $rx->roq = NULL;
      $Oops! rx_roq is NULL
      
      This patch fixes the race condition using refcount approach.
      Signed-off-by: NPrasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
      d11a6e44
    • P
      wimax/i2400m: increase tx queue length from 5 to 20 [v1] · ded0fd62
      Prasanna S. Panchamukhi 提交于
      This patch increases the tx_queue_len to 20 so as to
      minimize the jitter in the throughput.
      Signed-off-by: NPrasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
      ded0fd62
    • P
      wimax/i2400m: fix system freeze caused by an infinite loop [v1] · 85a19e07
      Prasanna S. Panchamukhi 提交于
      This patch fixes an infinite loop caused by i2400m_tx_fifo_push() due
      to a corner case where there is no tail space in the TX FIFO.
      Please refer the documentation in the code for details.
      Signed-off-by: NPrasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
      85a19e07
    • P
      wimax/i2400m: modify i2400m_tx_fifo_push() to check for head room space in the TX FIFO [v1] · 9e6e3bd5
      Prasanna S. Panchamukhi 提交于
      This fixes i2400m_tx_fifo_push(); the check for having enough
      space in the TX FIFO's tail was obscure and broken in certain
      corner cases. The new check works in all cases and is way
      clearer. Please refer the documentation in the code for details.
      Signed-off-by: NPrasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
      9e6e3bd5
    • P
      wimax/i2400m: fix BUILD_BUG_ON() to use the maximum message size constant [v1] · 718e9490
      Prasanna S. Panchamukhi 提交于
      The older method of computing the maximum PDU size relied
      on a method that doesn't work when we prop the maximum
      number of payloads up to the physical limit, and thus we kill
      the whole computation and just verify that the constants are
      congruent.
      Signed-off-by: NPrasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
      718e9490
    • P
      wimax/i2400m: limit the message size upto 16KiB [v1] · a40242f2
      Prasanna S. Panchamukhi 提交于
      According to Intel Wimax i3200, i5x50 and i6x50 specification
      documents, the maximum size of each TX message can be upto 16KiB.
      This patch modifies the i2400m_tx() routine to check that the
      message size does not exceed the 16KiB limit.
      Please refer the documentation in the code for details.
      Signed-off-by: NPrasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
      a40242f2
    • P
      wimax/i2400m: increase the maximum number of payloads per message to 60 [v1] · e6dd789a
      Prasanna S. Panchamukhi 提交于
      According to Intel Wimax i3200, i5x50 and i6x50 device specification
      documents, the maximum number of payloads per message can be up to 60.
      
      Increasing the number of payloads to 60 per message helps to
      accommodate smaller payloads in a single transaction. This patch
      increases the maximum number of payloads from 12 to 60 per message.
      Signed-off-by: NPrasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
      e6dd789a
    • C
      wimax/i2400m: Reset the TX FIFO indices when allocating the TX FIFO in tx_setup() · d9440174
      Cindy H Kao 提交于
      This patch makes sure whenever tx_setup() is invoked during driver
      initialization or device reset where TX FIFO is released and re-allocated,
      the indices tx_in, tx_out, tx_msg_size, tx_sequence, tx_msg are properly
      initialized.
      
      When a device reset happens and the TX FIFO is released/re-allocated,
      a new block of memory may be allocated for the TX FIFO, therefore tx_msg
      should be cleared so that no any TX threads (tx_worker, tx) would access
      to the out-of-date addresses.
      
      Also, the TX threads use tx_in and tx_out to decide where to put the new
      host-to-device messages and from where to copy them to the device HW FIFO,
      these indices have to be cleared so after the TX FIFO is re-allocated during
      the reset, the indices both refer to the head of the FIFO, ie. a new start.
      The same rational applies to tx_msg_size and tx_sequence.
      
      To protect the indices from being accessed by multiple threads simultaneously,
      the lock tx_lock has to be obtained before the initializations and released
      afterwards.
      Signed-off-by: NCindy H Kao <cindy.h.kao@intel.com>
      d9440174
    • C
      wimax/i2400m: Correct the error path handlers order in i2400m_post_reset() · 2354161d
      Cindy H Kao 提交于
      When bus_setup fails in i2400m_post_reset(), it falls to the error path handler
      "error_bus_setup:" which includes unlock the mutext. However, we didn't ever
      try to the obtain the lock when running bus_setup.
      
      The patch is to fix the misplaced error path handler "error_bus_setup:".
      Signed-off-by: NCindy H Kao <cindy.h.kao@intel.com>
      2354161d
    • C
      wimax/i2400m: add the error recovery mechanism on TX path · 599e5953
      Cindy H Kao 提交于
      This patch adds an error recovery mechanism on TX path.
      The intention is to bring back the device to some known state
      whenever TX sees -110 (-ETIMEOUT) on copying the data to the HW FIFO.
      
      The TX failure could mean a device bus stuck or function stuck, so
      the current error recovery implementation is to trigger a bus reset
      and expect this can bring back the device.
      
      Since the TX work is done in a thread context, there may be a queue of TX works
      already that all hit the -ETIMEOUT error condition because the device has
      somewhat stuck already. We don't want any consecutive bus resets simply because
      multiple TX works in the queue all hit the same device erratum, the flag
      "error_recovery" is introduced to denote if we are ready for taking any
      error recovery. See @error_recovery doc in i2400m.h.
      Signed-off-by: NCindy H Kao <cindy.h.kao@intel.com>
      599e5953
    • C
      wimax/i2400m: fix for missed reset events if triggered by dev_reset_handle() · f4e41345
      Cindy H Kao 提交于
      The problem is only seen on SDIO interface since on USB, a bus reset would
      really re-probe the driver, but on SDIO interface, a bus reset will not
      re-enumerate the SDIO bus, so no driver re-probe is happening. Therefore,
      on SDIO interface, the reset event should be still detected and handled by
      dev_reset_handle().
      
      Problem description:
      Whenever a reboot barker is received during operational mode (i2400m->boot_mode == 0),
      dev_reset_handle() is invoked to handle that function reset event.
      dev_reset_handle() then sets the flag i2400m->boot_mode to 1 indicating the device is
      back to bootmode before proceeding to dev_stop() and dev_start().
      If dev_start() returns failure, a bus reset is triggered by dev_reset_handle().
      
      The flag i2400m->boot_mode then remains 1 when the second reboot barker arrives.
      However the interrupt service routine i2400ms_rx() instead of invoking dev_reset_handle()
      to handle that reset event, it filters out that boot event to bootmode because it sees
      the flag i2400m->boot_mode equal to 1.
      
      The fix:
      Maintain the flag i2400m->boot_mode within dev_reset_handle() and set the flag
      i2400m->boot_mode to 1 when entering dev_reset_handle(). It remains 1
      until the dev_reset_handle() issues a bus reset. ie: the bus reset is
      taking place just like it happens for the first time during operational mode.
      
      To denote the actual device state and the state we expect, a flag i2400m->alive
      is introduced in addition to the existing flag i2400m->updown.
      It's maintained with the same way for i2400m->updown but instead of reflecting
      the actual state like i2400m->updown does, i2400m->alive maintains the state
      we expect. i2400m->alive is set 1 just like whenever i2400m->updown is set 1.
      Yet i2400m->alive remains 1 since we expect the device to be up all the time
      until the driver is removed. See the doc for @alive in i2400m.h.
      
      An enumeration I2400M_BUS_RESET_RETRIES is added to define the maximum number of
      bus resets that a device reboot can retry.
      
      A counter i2400m->bus_reset_retries is added to track how many bus resets
      have been retried in one device reboot. If I2400M_BUS_RESET_RETRIES bus resets
      were retried in this boot, we give up any further retrying so the device would enter
      low power state. The counter i2400m->bus_reset_retries is incremented whenever
      dev_reset_handle() is issuing a bus reset and is cleared to 0 when dev_start() is
      successfully done, ie: a successful reboot.
      Signed-off-by: NCindy H Kao <cindy.h.kao@intel.com>
      f4e41345
    • C
      wimax/i2400m: correct the error path handlers in dev_start() · 49d72df3
      Cindy H Kao 提交于
      This fix is to correct order of the handlers in the error path
      of dev_start(). When i2400m_firmware_check fails, all the works done
      before it should be released or cleared.
      Signed-off-by: NCindy H Kao <cindy.h.kao@intel.com>
      49d72df3
    • C
      wimax/i2400m: fix the race condition for accessing TX queue · f22cf689
      Cindy H Kao 提交于
      The race condition happens when the TX queue is accessed by
      the TX work while the same TX queue is being destroyed because
      a bus reset is triggered either by debugfs entry or simply
      by failing waking up the device from WiMAX IDLE mode.
      
      This fix is to prevent the TX queue from being accessed by
      multiple threads
      Signed-off-by: NCindy H Kao <cindy.h.kao@intel.com>
      f22cf689
    • P
      wimax/i2400m: fix insufficient size of Tx buffer for 12 payload of 1400 MTU. · 570eb0ea
      Prasanna S. Panchamukhi 提交于
      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: NPrasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
      Signed-off-by: NInaky Perez-Gonzalez <inaky@linux.intel.com>
      570eb0ea
    • P
      wimax/i2400m: move I2400M_MAX_MTU enum from netdev.c to i2400m.h · 080de04e
      Prasanna S. Panchamukhi 提交于
      This patch moves I2400M_MAX_MTU enum defined in netdev.c to i2400m.h.
      Follow up changes will make use of this value in other location,
      thus requiring it to be moved to a global header file i2400m.h.
      Signed-off-by: NPrasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
      Signed-off-by: NInaky Perez-Gonzalez <inaky@linux.intel.com>
      080de04e
    • P
      wimax/i2400m: fix incorrect return -ESHUTDOWN when there is no Tx buffer available · 4818d14d
      Prasanna S.Panchamukhi 提交于
      i2400m_tx() routine was returning -ESHUTDOWN even when there was no Tx buffer
      available. This patch fixes the i2400m_tx() to return -ESHUTDOWN only when
      the device is down(i2400m->tx_buf is NULL) and also to return -ENOSPC
      when there is no Tx buffer. Error seen in the kernel log.
      kernel: i2400m_sdio mmc0:0001:1: can't send message 0x5606: -108
      kernel: i2400m_sdio mmc0:0001:1: Failed to issue 'Enter power save'command: -108
      Signed-off-by: NPrasanna S.Panchamukhi <prasannax.s.panchamukhi@intel.com>
      4818d14d
  2. 10 5月, 2010 23 次提交