drivers/net/fddi/skfp/hwmtm.c

Source file repositories/reference/linux-study-clean/drivers/net/fddi/skfp/hwmtm.c

File Facts

System
Linux kernel
Corpus path
drivers/net/fddi/skfp/hwmtm.c
Extension
.c
Size
56012 bytes
Lines
2171
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!mb->sm_use_count) {
			DB_GEN(3, "free SMbuf: mb = %p", mb);
#ifndef	COMMON_MB_POOL
			mb->sm_next = smc->os.hwm.mbuf_pool.mb_free ;
			smc->os.hwm.mbuf_pool.mb_free = mb ;
#else
			mb->sm_next = mb_free ;
			mb_free = mb ;
#endif
		}
	}
	else
		SMT_PANIC(smc,HWM_E0003,HWM_E0003_MSG) ;
}


/*
 *	BEGIN_MANUAL_ENTRY(mac_drv_repair_descr)
 *	void mac_drv_repair_descr(smc)
 *
 * function	called from SMT	(HWM / hwmtm.c)
 *		The BMU is idle when this function is called.
 *		Mac_drv_repair_descr sets up the physical address
 *		for all receive and transmit queues where the BMU
 *		should continue.
 *		It may be that the BMU was reseted during a fragmented
 *		transfer. In this case there are some fragments which will
 *		never completed by the BMU. The OWN bit of this fragments
 *		must be switched to be owned by the host.
 *
 *		Give a start command to the receive BMU.
 *		Start the transmit BMUs if transmit frames pending.
 *
 *	END_MANUAL_ENTRY
 */
void mac_drv_repair_descr(struct s_smc *smc)
{
	u_long	phys ;

	if (smc->hw.hw_state != STOPPED) {
		SK_BREAK() ;
		SMT_PANIC(smc,HWM_E0013,HWM_E0013_MSG) ;
		return ;
	}

	/*
	 * repair tx queues: don't start
	 */
	phys = repair_txd_ring(smc,smc->hw.fp.tx[QUEUE_A0]) ;
	outpd(ADDR(B5_XA_DA),phys) ;
	if (smc->hw.fp.tx_q[QUEUE_A0].tx_used) {
		outpd(ADDR(B0_XA_CSR),CSR_START) ;
	}
	phys = repair_txd_ring(smc,smc->hw.fp.tx[QUEUE_S]) ;
	outpd(ADDR(B5_XS_DA),phys) ;
	if (smc->hw.fp.tx_q[QUEUE_S].tx_used) {
		outpd(ADDR(B0_XS_CSR),CSR_START) ;
	}

	/*
	 * repair rx queues
	 */
	phys = repair_rxd_ring(smc,smc->hw.fp.rx[QUEUE_R1]) ;
	outpd(ADDR(B4_R1_DA),phys) ;
	outpd(ADDR(B0_R1_CSR),CSR_START) ;
}

static u_long repair_txd_ring(struct s_smc *smc, struct s_smt_tx_queue *queue)
{
	int i ;
	int tx_used ;
	u_long phys ;
	u_long tbctrl ;
	struct s_smt_fp_txd volatile *t ;

	SK_UNUSED(smc) ;

	t = queue->tx_curr_get ;
	tx_used = queue->tx_used ;
	for (i = tx_used+queue->tx_free-1 ; i ; i-- ) {
		t = t->txd_next ;
	}
	phys = le32_to_cpu(t->txd_ntdadr) ;

	t = queue->tx_curr_get ;
	while (tx_used) {
		DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORCPU) ;
		tbctrl = le32_to_cpu(t->txd_tbctrl) ;

		if (tbctrl & BMU_OWN) {

Annotation

Implementation Notes