drivers/infiniband/hw/mthca/mthca_av.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/mthca/mthca_av.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/mthca/mthca_av.c
Extension
.c
Size
10019 bytes
Lines
377
Domain
Driver Families
Bucket
drivers/infiniband
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

struct mthca_av {
	__be32 port_pd;
	u8     reserved1;
	u8     g_slid;
	__be16 dlid;
	u8     reserved2;
	u8     gid_index;
	u8     msg_sr;
	u8     hop_limit;
	__be32 sl_tclass_flowlabel;
	__be32 dgid[4];
};

static enum ib_rate memfree_rate_to_ib(u8 mthca_rate, u8 port_rate)
{
	switch (mthca_rate) {
	case MTHCA_RATE_MEMFREE_EIGHTH:
		return mult_to_ib_rate(port_rate >> 3);
	case MTHCA_RATE_MEMFREE_QUARTER:
		return mult_to_ib_rate(port_rate >> 2);
	case MTHCA_RATE_MEMFREE_HALF:
		return mult_to_ib_rate(port_rate >> 1);
	case MTHCA_RATE_MEMFREE_FULL:
	default:
		return mult_to_ib_rate(port_rate);
	}
}

static enum ib_rate tavor_rate_to_ib(u8 mthca_rate, u8 port_rate)
{
	switch (mthca_rate) {
	case MTHCA_RATE_TAVOR_1X:     return IB_RATE_2_5_GBPS;
	case MTHCA_RATE_TAVOR_1X_DDR: return IB_RATE_5_GBPS;
	case MTHCA_RATE_TAVOR_4X:     return IB_RATE_10_GBPS;
	default:		      return mult_to_ib_rate(port_rate);
	}
}

enum ib_rate mthca_rate_to_ib(struct mthca_dev *dev, u8 mthca_rate, u32 port)
{
	if (mthca_is_memfree(dev)) {
		/* Handle old Arbel FW */
		if (dev->limits.stat_rate_support == 0x3 && mthca_rate)
			return IB_RATE_2_5_GBPS;

		return memfree_rate_to_ib(mthca_rate, dev->rate[port - 1]);
	} else
		return tavor_rate_to_ib(mthca_rate, dev->rate[port - 1]);
}

static u8 ib_rate_to_memfree(u8 req_rate, u8 cur_rate)
{
	if (cur_rate <= req_rate)
		return 0;

	/*
	 * Inter-packet delay (IPD) to get from rate X down to a rate
	 * no more than Y is (X - 1) / Y.
	 */
	switch ((cur_rate - 1) / req_rate) {
	case 0:	 return MTHCA_RATE_MEMFREE_FULL;
	case 1:	 return MTHCA_RATE_MEMFREE_HALF;
	case 2:
	case 3:	 return MTHCA_RATE_MEMFREE_QUARTER;
	default: return MTHCA_RATE_MEMFREE_EIGHTH;
	}
}

static u8 ib_rate_to_tavor(u8 static_rate)
{
	switch (static_rate) {
	case IB_RATE_2_5_GBPS: return MTHCA_RATE_TAVOR_1X;
	case IB_RATE_5_GBPS:   return MTHCA_RATE_TAVOR_1X_DDR;
	case IB_RATE_10_GBPS:  return MTHCA_RATE_TAVOR_4X;
	default:	       return MTHCA_RATE_TAVOR_FULL;
	}
}

u8 mthca_get_rate(struct mthca_dev *dev, int static_rate, u32 port)
{
	u8 rate;

	if (!static_rate || ib_rate_to_mult(static_rate) >= dev->rate[port - 1])
		return 0;

	if (mthca_is_memfree(dev))
		rate = ib_rate_to_memfree(ib_rate_to_mult(static_rate),
					  dev->rate[port - 1]);
	else
		rate = ib_rate_to_tavor(static_rate);

Annotation

Implementation Notes