FreeBSD/sys/dev/iwn/if_iwn.c
/*
 * This function is called after the initialization or runtime firmware
 * notifies us of its readiness (called in a process context).
 */
This function is called after the initialization or runtime firmware
notifies us of its readiness (called in a process context).
This function is called after the initialization or runtime firmware notifies us of its readiness ( called in a process context ) .
static int
iwn5000_post_alive(struct iwn_softc *sc)
{
	int error, qid;
	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
	iwn5000_ict_reset(sc);
	if ((error = iwn_nic_lock(sc)) != 0){
		DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end in error\n", __func__);
		return error;
	}
	sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
	iwn_mem_set_region_4(sc, sc->sched_base + IWN5000_SCHED_CTX_OFF, 0,
	    IWN5000_SCHED_CTX_LEN / sizeof (uint32_t));
	iwn_prph_write(sc, IWN5000_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
	IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
	if (sc->sc_flags & IWN_FLAG_PAN_SUPPORT)
		iwn_prph_write(sc, IWN5000_SCHED_QCHAIN_SEL, 0xfffdf);
	else
		iwn_prph_write(sc, IWN5000_SCHED_QCHAIN_SEL, 0xfffef);
	iwn_prph_write(sc, IWN5000_SCHED_AGGR_SEL, 0);
	for (qid = 0; qid < IWN5000_NTXQUEUES; qid++) {
		iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), 0);
		IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | 0);
		iwn_mem_write(sc, sc->sched_base +
		    IWN5000_SCHED_QUEUE_OFFSET(qid), 0);
		iwn_mem_write(sc, sc->sched_base +
		    IWN5000_SCHED_QUEUE_OFFSET(qid) + 4,
		    IWN_SCHED_LIMIT << 16 | IWN_SCHED_WINSZ);
	}
	iwn_prph_write(sc, IWN5000_SCHED_INTR_MASK, 0xfffff);
	iwn_prph_write(sc, IWN5000_SCHED_TXFACT, 0xff);
	if (sc->sc_flags & IWN_FLAG_PAN_SUPPORT) {
		for (qid = 0; qid < 11; qid++) {
			static uint8_t qid2fifo[] = { 3, 2, 1, 0, 0, 4, 2, 5, 4, 7, 5 };
			iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
			    IWN5000_TXQ_STATUS_ACTIVE | qid2fifo[qid]);
		}
	} else {
		for (qid = 0; qid < 7; qid++) {
			static uint8_t qid2fifo[] = { 3, 2, 1, 0, 7, 5, 6 };
			iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
			    IWN5000_TXQ_STATUS_ACTIVE | qid2fifo[qid]);
		}
	}
	iwn_nic_unlock(sc);
	error = iwn5000_send_wimax_coex(sc);
	if (error != 0) {
		device_printf(sc->sc_dev,
		    "%s: could not configure WiMAX coexistence, error %d\n",
		    __func__, error);
		return error;
	}
	if (sc->hw_type != IWN_HW_REV_TYPE_5150) {
		error = iwn5000_crystal_calib(sc);
		if (error != 0) {
			device_printf(sc->sc_dev,
			    "%s: crystal calibration failed, error %d\n",
			    __func__, error);
			return error;
		}
	}
	if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE)) {
		if ((error = iwn5000_query_calibration(sc)) != 0) {
			device_printf(sc->sc_dev,
			    "%s: could not query calibration, error %d\n",
			    __func__, error);
			return error;
		}
		iwn_hw_stop(sc);
		error = iwn_hw_init(sc);
	} else {
		error = iwn5000_send_calibration(sc);
	}
	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__);
	return error;
}
static int iwn5000_post_alive ( struct iwn_softc * sc ) { int error , qid ; DPRINTF ( sc , IWN_DEBUG_TRACE , " \n " , __func__ ) ; iwn5000_ict_reset ( sc ) ; if ( ( error = iwn_nic_lock ( sc ) ) != 0 ) { DPRINTF ( sc , IWN_DEBUG_TRACE , " \n " , __func__ ) ; return error ; } sc -> sched_base = iwn_prph_read ( sc , IWN_SCHED_SRAM_ADDR ) ; iwn_mem_set_region_4 ( sc , sc -> sched_base + IWN5000_SCHED_CTX_OFF , 0 , IWN5000_SCHED_CTX_LEN / sizeof ( uint32_t ) ) ; iwn_prph_write ( sc , IWN5000_SCHED_DRAM_ADDR , sc -> sched_dma . paddr >> 10 ) ; IWN_SETBITS ( sc , IWN_FH_TX_CHICKEN , IWN_FH_TX_CHICKEN_SCHED_RETRY ) ; if ( sc -> sc_flags & IWN_FLAG_PAN_SUPPORT ) iwn_prph_write ( sc , IWN5000_SCHED_QCHAIN_SEL , 0xfffdf ) ; else iwn_prph_write ( sc , IWN5000_SCHED_QCHAIN_SEL , 0xfffef ) ; iwn_prph_write ( sc , IWN5000_SCHED_AGGR_SEL , 0 ) ; for ( qid = 0 ; qid < IWN5000_NTXQUEUES ; qid ++ ) { iwn_prph_write ( sc , IWN5000_SCHED_QUEUE_RDPTR ( qid ) , 0 ) ; IWN_WRITE ( sc , IWN_HBUS_TARG_WRPTR , qid << 8 | 0 ) ; iwn_mem_write ( sc , sc -> sched_base + IWN5000_SCHED_QUEUE_OFFSET ( qid ) , 0 ) ; iwn_mem_write ( sc , sc -> sched_base + IWN5000_SCHED_QUEUE_OFFSET ( qid ) + 4 , IWN_SCHED_LIMIT << 16 | IWN_SCHED_WINSZ ) ; } iwn_prph_write ( sc , IWN5000_SCHED_INTR_MASK , 0xfffff ) ; iwn_prph_write ( sc , IWN5000_SCHED_TXFACT , 0xff ) ; if ( sc -> sc_flags & IWN_FLAG_PAN_SUPPORT ) { for ( qid = 0 ; qid < 11 ; qid ++ ) { static uint8_t qid2fifo [ ] = { 3 , 2 , 1 , 0 , 0 , 4 , 2 , 5 , 4 , 7 , 5 } ; iwn_prph_write ( sc , IWN5000_SCHED_QUEUE_STATUS ( qid ) , IWN5000_TXQ_STATUS_ACTIVE | qid2fifo [ qid ] ) ; } } else { for ( qid = 0 ; qid < 7 ; qid ++ ) { static uint8_t qid2fifo [ ] = { 3 , 2 , 1 , 0 , 7 , 5 , 6 } ; iwn_prph_write ( sc , IWN5000_SCHED_QUEUE_STATUS ( qid ) , IWN5000_TXQ_STATUS_ACTIVE | qid2fifo [ qid ] ) ; } } iwn_nic_unlock ( sc ) ; error = iwn5000_send_wimax_coex ( sc ) ; if ( error != 0 ) { device_printf ( sc -> sc_dev , " \n " , __func__ , error ) ; return error ; } if ( sc -> hw_type != IWN_HW_REV_TYPE_5150 ) { error = iwn5000_crystal_calib ( sc ) ; if ( error != 0 ) { device_printf ( sc -> sc_dev , " \n " , __func__ , error ) ; return error ; } } if ( ! ( sc -> sc_flags & IWN_FLAG_CALIB_DONE ) ) { if ( ( error = iwn5000_query_calibration ( sc ) ) != 0 ) { device_printf ( sc -> sc_dev , " \n " , __func__ , error ) ; return error ; } iwn_hw_stop ( sc ) ; error = iwn_hw_init ( sc ) ; } else { error = iwn5000_send_calibration ( sc ) ; } DPRINTF ( sc , IWN_DEBUG_TRACE , " \n " , __func__ ) ; return error ; }
This function is called after the initialization or runtime firmware
 notifies us of its readiness (called in a process context).
This function is called after the initialization or runtime firmware notifies us of its readiness ( called in a process context ) .
/* Switch to using ICT interrupt mode. */ /* Clear TX scheduler state in SRAM. */ /* Set physical address of TX scheduler rings (1KB aligned). */ /* Enable chain mode for all queues, except command queue. */ /* Set scheduler window size and frame limit. */ /* Enable interrupts for all our 20 queues. */ /* Identify TX FIFO rings (0-7). */ /* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */ /* Mark TX rings as active. */ /* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */ /* Configure WiMAX coexistence for combo adapters. */ /* Perform crystal calibration. */ /* Query calibration from the initialization firmware. */ /*
		 * We have the calibration results now, reboot with the
		 * runtime firmware (call ourselves recursively!)
		 */ /* Send calibration results to runtime firmware. */