aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wimax/i2400m/sdio-rx.c
diff options
context:
space:
mode:
authorInaky Perez-Gonzalez <inaky@linux.intel.com>2009-09-03 18:14:29 -0400
committerInaky Perez-Gonzalez <inaky@linux.intel.com>2009-10-19 02:55:53 -0400
commitaba3792ac2d7c808a2d2fd2adf89531e083bdb90 (patch)
treefdf901fe2d666805ad27a421b076cce2bfed7352 /drivers/net/wimax/i2400m/sdio-rx.c
parent32742e6158657f19ad31653705bef56d983508e7 (diff)
wimax/i2400m: rework bootrom initialization to be more flexible
This modifies the bootrom initialization code of the i2400m driver so it can more easily support upcoming hardware. Currently, the code detects two types of barkers (magic numbers) sent by the device to indicate the types of firmware it would take (signed vs non-signed). This schema is extended so that multiple reboot barkers are recognized; upcoming hw will expose more types barkers which will have to match a header in the firmware image before we can load it. For that, a barker database is introduced; the first time the device sends a barker, it is matched in the database. That gives the driver the information needed to decide how to upload the firmware and which types of firmware to use. The database can be populated from module parameters. The execution flow is not altered; a new function (i2400m_is_boot_barker) is introduced to determine in the RX path if the device has sent a boot barker. This function is becoming heavier, so it is put away from the hot reception path [this is why there is some reorganization in sdio-rx.c:i2400ms_rx and usb-notifc.c:i2400mu_notification_grok()]. The documentation on the process has also been updated. All these modifications are heavily based on previous work by Dirk Brandewie <dirk.brandewie@intel.com>. Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Diffstat (limited to 'drivers/net/wimax/i2400m/sdio-rx.c')
-rw-r--r--drivers/net/wimax/i2400m/sdio-rx.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/drivers/net/wimax/i2400m/sdio-rx.c b/drivers/net/wimax/i2400m/sdio-rx.c
index 1c9046914bd1..87263be4eedb 100644
--- a/drivers/net/wimax/i2400m/sdio-rx.c
+++ b/drivers/net/wimax/i2400m/sdio-rx.c
@@ -53,6 +53,7 @@
53 * i2400ms_irq() 53 * i2400ms_irq()
54 * i2400ms_rx() 54 * i2400ms_rx()
55 * __i2400ms_rx_get_size() 55 * __i2400ms_rx_get_size()
56 * i2400m_is_boot_barker()
56 * i2400m_rx() 57 * i2400m_rx()
57 * 58 *
58 * i2400ms_rx_setup() 59 * i2400ms_rx_setup()
@@ -158,7 +159,7 @@ void i2400ms_rx(struct i2400ms *i2400ms)
158 } 159 }
159 160
160 rmb(); /* make sure we get boot_mode from dev_reset_handle */ 161 rmb(); /* make sure we get boot_mode from dev_reset_handle */
161 if (i2400m->boot_mode == 1) { 162 if (unlikely(i2400m->boot_mode == 1)) {
162 spin_lock(&i2400m->rx_lock); 163 spin_lock(&i2400m->rx_lock);
163 i2400ms->bm_ack_size = rx_size; 164 i2400ms->bm_ack_size = rx_size;
164 spin_unlock(&i2400m->rx_lock); 165 spin_unlock(&i2400m->rx_lock);
@@ -166,17 +167,26 @@ void i2400ms_rx(struct i2400ms *i2400ms)
166 wake_up(&i2400ms->bm_wfa_wq); 167 wake_up(&i2400ms->bm_wfa_wq);
167 dev_err(dev, "RX: SDIO boot mode message\n"); 168 dev_err(dev, "RX: SDIO boot mode message\n");
168 kfree_skb(skb); 169 kfree_skb(skb);
169 } else if (unlikely(!memcmp(skb->data, i2400m_NBOOT_BARKER, 170 goto out;
170 sizeof(i2400m_NBOOT_BARKER)) 171 }
171 || !memcmp(skb->data, i2400m_SBOOT_BARKER, 172 ret = -EIO;
172 sizeof(i2400m_SBOOT_BARKER)))) { 173 if (unlikely(rx_size < sizeof(__le32))) {
174 dev_err(dev, "HW BUG? only %zu bytes received\n", rx_size);
175 goto error_bad_size;
176 }
177 if (likely(i2400m_is_d2h_barker(skb->data))) {
178 skb_put(skb, rx_size);
179 i2400m_rx(i2400m, skb);
180 } else if (unlikely(i2400m_is_boot_barker(i2400m,
181 skb->data, rx_size))) {
173 ret = i2400m_dev_reset_handle(i2400m); 182 ret = i2400m_dev_reset_handle(i2400m);
174 dev_err(dev, "RX: SDIO reboot barker\n"); 183 dev_err(dev, "RX: SDIO reboot barker\n");
175 kfree_skb(skb); 184 kfree_skb(skb);
176 } else { 185 } else {
177 skb_put(skb, rx_size); 186 i2400m_unknown_barker(i2400m, skb->data, rx_size);
178 i2400m_rx(i2400m, skb); 187 kfree_skb(skb);
179 } 188 }
189out:
180 d_fnend(7, dev, "(i2400ms %p) = void\n", i2400ms); 190 d_fnend(7, dev, "(i2400ms %p) = void\n", i2400ms);
181 return; 191 return;
182 192
@@ -184,6 +194,7 @@ error_memcpy_fromio:
184 kfree_skb(skb); 194 kfree_skb(skb);
185error_alloc_skb: 195error_alloc_skb:
186error_get_size: 196error_get_size:
197error_bad_size:
187 d_fnend(7, dev, "(i2400ms %p) = %d\n", i2400ms, ret); 198 d_fnend(7, dev, "(i2400ms %p) = %d\n", i2400ms, ret);
188 return; 199 return;
189} 200}