aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wimax/i2400m/sdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wimax/i2400m/sdio.c')
-rw-r--r--drivers/net/wimax/i2400m/sdio.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c
index 777c981676fc..2538825d1c66 100644
--- a/drivers/net/wimax/i2400m/sdio.c
+++ b/drivers/net/wimax/i2400m/sdio.c
@@ -78,6 +78,14 @@ static const char *i2400ms_bus_fw_names[] = {
78}; 78};
79 79
80 80
81static const struct i2400m_poke_table i2400ms_pokes[] = {
82 I2400M_FW_POKE(0x6BE260, 0x00000088),
83 I2400M_FW_POKE(0x080550, 0x00000005),
84 I2400M_FW_POKE(0xAE0000, 0x00000000),
85 I2400M_FW_POKE(0x000000, 0x00000000), /* MUST be 0 terminated or bad
86 * things will happen */
87};
88
81/* 89/*
82 * Enable the SDIO function 90 * Enable the SDIO function
83 * 91 *
@@ -148,19 +156,14 @@ int i2400ms_bus_dev_start(struct i2400m *i2400m)
148 156
149 d_fnstart(3, dev, "(i2400m %p)\n", i2400m); 157 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
150 msleep(200); 158 msleep(200);
151 result = i2400ms_rx_setup(i2400ms);
152 if (result < 0)
153 goto error_rx_setup;
154 result = i2400ms_tx_setup(i2400ms); 159 result = i2400ms_tx_setup(i2400ms);
155 if (result < 0) 160 if (result < 0)
156 goto error_tx_setup; 161 goto error_tx_setup;
157 d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); 162 d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
158 return result; 163 return result;
159 164
160 i2400ms_tx_release(i2400ms);
161error_tx_setup: 165error_tx_setup:
162 i2400ms_rx_release(i2400ms); 166 i2400ms_tx_release(i2400ms);
163error_rx_setup:
164 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); 167 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
165 return result; 168 return result;
166} 169}
@@ -174,7 +177,6 @@ void i2400ms_bus_dev_stop(struct i2400m *i2400m)
174 struct device *dev = &func->dev; 177 struct device *dev = &func->dev;
175 178
176 d_fnstart(3, dev, "(i2400m %p)\n", i2400m); 179 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
177 i2400ms_rx_release(i2400ms);
178 i2400ms_tx_release(i2400ms); 180 i2400ms_tx_release(i2400ms);
179 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); 181 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
180} 182}
@@ -255,7 +257,7 @@ error_kzalloc:
255static 257static
256int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) 258int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
257{ 259{
258 int result; 260 int result = 0;
259 struct i2400ms *i2400ms = 261 struct i2400ms *i2400ms =
260 container_of(i2400m, struct i2400ms, i2400m); 262 container_of(i2400m, struct i2400ms, i2400m);
261 struct device *dev = i2400m_dev(i2400m); 263 struct device *dev = i2400m_dev(i2400m);
@@ -280,8 +282,25 @@ int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
280 sizeof(i2400m_COLD_BOOT_BARKER)); 282 sizeof(i2400m_COLD_BOOT_BARKER));
281 else if (rt == I2400M_RT_BUS) { 283 else if (rt == I2400M_RT_BUS) {
282do_bus_reset: 284do_bus_reset:
283 dev_err(dev, "FIXME: SDIO bus reset not implemented\n"); 285 /* call netif_tx_disable() before sending IOE disable,
284 result = rt == I2400M_RT_WARM ? -ENODEV : -ENOSYS; 286 * so that all the tx from network layer are stopped
287 * while IOE is being reset. Make sure it is called
288 * only after register_netdev() was issued.
289 */
290 if (i2400m->wimax_dev.net_dev->reg_state == NETREG_REGISTERED)
291 netif_tx_disable(i2400m->wimax_dev.net_dev);
292
293 i2400ms_rx_release(i2400ms);
294 sdio_claim_host(i2400ms->func);
295 sdio_disable_func(i2400ms->func);
296 sdio_release_host(i2400ms->func);
297
298 /* Wait for the device to settle */
299 msleep(40);
300
301 result = i2400ms_enable_function(i2400ms->func);
302 if (result >= 0)
303 i2400ms_rx_setup(i2400ms);
285 } else 304 } else
286 BUG(); 305 BUG();
287 if (result < 0 && rt != I2400M_RT_BUS) { 306 if (result < 0 && rt != I2400M_RT_BUS) {
@@ -404,10 +423,14 @@ int i2400ms_probe(struct sdio_func *func,
404 i2400m->bus_dev_stop = i2400ms_bus_dev_stop; 423 i2400m->bus_dev_stop = i2400ms_bus_dev_stop;
405 i2400m->bus_tx_kick = i2400ms_bus_tx_kick; 424 i2400m->bus_tx_kick = i2400ms_bus_tx_kick;
406 i2400m->bus_reset = i2400ms_bus_reset; 425 i2400m->bus_reset = i2400ms_bus_reset;
426 /* The iwmc3200-wimax sometimes requires the driver to try
427 * hard when we paint it into a corner. */
428 i2400m->bus_bm_retries = I3200_BOOT_RETRIES;
407 i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send; 429 i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send;
408 i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack; 430 i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack;
409 i2400m->bus_fw_names = i2400ms_bus_fw_names; 431 i2400m->bus_fw_names = i2400ms_bus_fw_names;
410 i2400m->bus_bm_mac_addr_impaired = 1; 432 i2400m->bus_bm_mac_addr_impaired = 1;
433 i2400m->bus_bm_pokes_table = &i2400ms_pokes[0];
411 434
412 sdio_claim_host(func); 435 sdio_claim_host(func);
413 result = sdio_set_block_size(func, I2400MS_BLK_SIZE); 436 result = sdio_set_block_size(func, I2400MS_BLK_SIZE);
@@ -423,6 +446,10 @@ int i2400ms_probe(struct sdio_func *func,
423 goto error_func_enable; 446 goto error_func_enable;
424 } 447 }
425 448
449 result = i2400ms_rx_setup(i2400ms);
450 if (result < 0)
451 goto error_rx_setup;
452
426 result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT); 453 result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT);
427 if (result < 0) { 454 if (result < 0) {
428 dev_err(dev, "cannot setup device: %d\n", result); 455 dev_err(dev, "cannot setup device: %d\n", result);
@@ -440,6 +467,8 @@ int i2400ms_probe(struct sdio_func *func,
440error_debugfs_add: 467error_debugfs_add:
441 i2400m_release(i2400m); 468 i2400m_release(i2400m);
442error_setup: 469error_setup:
470 i2400ms_rx_release(i2400ms);
471error_rx_setup:
443 sdio_claim_host(func); 472 sdio_claim_host(func);
444 sdio_disable_func(func); 473 sdio_disable_func(func);
445 sdio_release_host(func); 474 sdio_release_host(func);
@@ -462,6 +491,7 @@ void i2400ms_remove(struct sdio_func *func)
462 491
463 d_fnstart(3, dev, "SDIO func %p\n", func); 492 d_fnstart(3, dev, "SDIO func %p\n", func);
464 debugfs_remove_recursive(i2400ms->debugfs_dentry); 493 debugfs_remove_recursive(i2400ms->debugfs_dentry);
494 i2400ms_rx_release(i2400ms);
465 i2400m_release(i2400m); 495 i2400m_release(i2400m);
466 sdio_set_drvdata(func, NULL); 496 sdio_set_drvdata(func, NULL);
467 sdio_claim_host(func); 497 sdio_claim_host(func);