int bcom_fec_tx_reset(struct bcom_task *tsk) { struct bcom_fec_priv *priv = tsk->priv; struct bcom_fec_tx_var *var; struct bcom_fec_tx_inc *inc; /* Shutdown the task */ bcom_disable_task(tsk->tasknum); /* Reset the microcode */ var = (struct bcom_fec_tx_var *) bcom_task_var(tsk->tasknum); inc = (struct bcom_fec_tx_inc *) bcom_task_inc(tsk->tasknum); if (bcom_load_image(tsk->tasknum, bcom_fec_tx_task)) return -1; var->enable = bcom_eng->regs_base + offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]); var->fifo = (u32) priv->fifo; var->DRD = bcom_sram_va2pa(self_modified_drd(tsk->tasknum)); var->bd_base = tsk->bd_pa; var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size); var->bd_start = tsk->bd_pa; inc->incr_bytes = -(s16)sizeof(u32); /* These should be in the */ inc->incr_src = sizeof(u32); /* task image, but we stick */ inc->incr_src_ma= sizeof(u8); /* to the official ones */ /* Reset the BDs */ tsk->index = 0; tsk->outdex = 0; memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); /* Configure some stuff */ bcom_set_task_pragma(tsk->tasknum, BCOM_FEC_TX_BD_PRAGMA); bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum); out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_FEC_TX], BCOM_IPR_FEC_TX); out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */ return 0; }
int bcom_gen_bd_tx_reset(struct bcom_task *tsk) { struct bcom_gen_bd_priv *priv = tsk->priv; struct bcom_gen_bd_tx_var *var; struct bcom_gen_bd_tx_inc *inc; /* Shutdown the task */ bcom_disable_task(tsk->tasknum); /* Reset the microcode */ var = (struct bcom_gen_bd_tx_var *) bcom_task_var(tsk->tasknum); inc = (struct bcom_gen_bd_tx_inc *) bcom_task_inc(tsk->tasknum); if (bcom_load_image(tsk->tasknum, bcom_gen_bd_tx_task)) return -1; var->enable = bcom_eng->regs_base + offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]); var->fifo = (u32) priv->fifo; var->bd_base = tsk->bd_pa; var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size); var->bd_start = tsk->bd_pa; inc->incr_bytes = -(s16)sizeof(u32); inc->incr_src = sizeof(u32); inc->incr_src_ma = sizeof(u8); /* Reset the BDs */ tsk->index = 0; tsk->outdex = 0; memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); /* Configure some stuff */ bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_TX_BD_PRAGMA); bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum); out_8(&bcom_eng->regs->ipr[priv->initiator], priv->ipr); bcom_set_initiator(tsk->tasknum, priv->initiator); out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */ return 0; }
int bcom_load_image(int task, u32 *task_image) { struct bcom_task_header *hdr = (struct bcom_task_header *)task_image; struct bcom_tdt *tdt; u32 *desc, *var, *inc; u32 *desc_src, *var_src, *inc_src; /* Safety checks */ if (hdr->magic != BCOM_TASK_MAGIC) { printk(KERN_ERR DRIVER_NAME ": Trying to load invalid microcode\n"); return -EINVAL; } if ((task < 0) || (task >= BCOM_MAX_TASKS)) { printk(KERN_ERR DRIVER_NAME ": Trying to load invalid task %d\n", task); return -EINVAL; } /* Initial load or reload */ tdt = &bcom_eng->tdt[task]; if (tdt->start) { desc = bcom_task_desc(task); if (hdr->desc_size != bcom_task_num_descs(task)) { printk(KERN_ERR DRIVER_NAME ": Trying to reload wrong task image " "(%d size %d/%d)!\n", task, hdr->desc_size, bcom_task_num_descs(task)); return -EINVAL; } } else { phys_addr_t start_pa; desc = bcom_sram_alloc(hdr->desc_size * sizeof(u32), 4, &start_pa); if (!desc) return -ENOMEM; tdt->start = start_pa; tdt->stop = start_pa + ((hdr->desc_size-1) * sizeof(u32)); } var = bcom_task_var(task); inc = bcom_task_inc(task); /* Clear & copy */ memset(var, 0x00, BCOM_VAR_SIZE); memset(inc, 0x00, BCOM_INC_SIZE); desc_src = (u32 *)(hdr + 1); var_src = desc_src + hdr->desc_size; inc_src = var_src + hdr->var_size; memcpy(desc, desc_src, hdr->desc_size * sizeof(u32)); memcpy(var + hdr->first_var, var_src, hdr->var_size * sizeof(u32)); memcpy(inc, inc_src, hdr->inc_size * sizeof(u32)); return 0; }