예제 #1
0
파일: ah.c 프로젝트: mansr/linux-tangox
static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
				    struct mlx4_ib_ah *ah)
{
	struct mlx4_ib_dev *ibdev = to_mdev(pd->device);
	struct mlx4_dev *dev = ibdev->dev;
	int is_mcast = 0;
	struct in6_addr in6;
	u16 vlan_tag = 0xffff;
	union ib_gid sgid;
	struct ib_gid_attr gid_attr;
	int ret;

	memcpy(&in6, ah_attr->grh.dgid.raw, sizeof(in6));
	if (rdma_is_multicast_addr(&in6)) {
		is_mcast = 1;
		rdma_get_mcast_mac(&in6, ah->av.eth.mac);
	} else {
		memcpy(ah->av.eth.mac, ah_attr->dmac, ETH_ALEN);
	}
	ret = ib_get_cached_gid(pd->device, ah_attr->port_num,
				ah_attr->grh.sgid_index, &sgid, &gid_attr);
	if (ret)
		return ERR_PTR(ret);
	eth_zero_addr(ah->av.eth.s_mac);
	if (gid_attr.ndev) {
		if (is_vlan_dev(gid_attr.ndev))
			vlan_tag = vlan_dev_vlan_id(gid_attr.ndev);
		memcpy(ah->av.eth.s_mac, gid_attr.ndev->dev_addr, ETH_ALEN);
		dev_put(gid_attr.ndev);
	}
	if (vlan_tag < 0x1000)
		vlan_tag |= (ah_attr->sl & 7) << 13;
	ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
	ret = mlx4_ib_gid_index_to_real_index(ibdev, ah_attr->port_num, ah_attr->grh.sgid_index);
	if (ret < 0)
		return ERR_PTR(ret);
	ah->av.eth.gid_index = ret;
	ah->av.eth.vlan = cpu_to_be16(vlan_tag);
	ah->av.eth.hop_limit = ah_attr->grh.hop_limit;
	if (ah_attr->static_rate) {
		ah->av.eth.stat_rate = ah_attr->static_rate + MLX4_STAT_RATE_OFFSET;
		while (ah->av.eth.stat_rate > IB_RATE_2_5_GBPS + MLX4_STAT_RATE_OFFSET &&
		       !(1 << ah->av.eth.stat_rate & dev->caps.stat_rate_support))
			--ah->av.eth.stat_rate;
	}

	/*
	 * HW requires multicast LID so we just choose one.
	 */
	if (is_mcast)
		ah->av.ib.dlid = cpu_to_be16(0xc000);

	memcpy(ah->av.eth.dgid, ah_attr->grh.dgid.raw, 16);
	ah->av.eth.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 29);

	return &ah->ibah;
}
예제 #2
0
파일: ah.c 프로젝트: Cai900205/test
int mlx4_ib_resolve_grh(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah_attr,
			u8 *mac, int *is_mcast, u8 port)
{
	struct in6_addr in6;

	*is_mcast = 0;

	memcpy(&in6, ah_attr->grh.dgid.raw, sizeof in6);
	if (rdma_link_local_addr(&in6))
		rdma_get_ll_mac(&in6, mac);
	else if (rdma_is_multicast_addr(&in6)) {
		rdma_get_mcast_mac(&in6, mac);
		*is_mcast = 1;
	} else
		return -EINVAL;

	return 0;
}
예제 #3
0
파일: ah.c 프로젝트: jgroen/rtt_tests
static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
                                    struct mlx4_ib_ah *ah)
{
    struct mlx4_ib_dev *ibdev = to_mdev(pd->device);
    struct mlx4_dev *dev = ibdev->dev;
    int is_mcast;
    struct in6_addr in6;
    u16 vlan_tag;

    memcpy(&in6, ah_attr->grh.dgid.raw, sizeof(in6));
    if (rdma_is_multicast_addr(&in6)) {
        is_mcast = 1;
        rdma_get_mcast_mac(&in6, ah->av.eth.mac);
    } else {
        memcpy(ah->av.eth.mac, ah_attr->dmac, ETH_ALEN);
    }
    vlan_tag = ah_attr->vlan_id;
    if (vlan_tag < 0x1000)
        vlan_tag |= (ah_attr->sl & 7) << 13;
    ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
    ah->av.eth.gid_index = ah_attr->grh.sgid_index;
    ah->av.eth.vlan = cpu_to_be16(vlan_tag);
    if (ah_attr->static_rate) {
        ah->av.eth.stat_rate = ah_attr->static_rate + MLX4_STAT_RATE_OFFSET;
        while (ah->av.eth.stat_rate > IB_RATE_2_5_GBPS + MLX4_STAT_RATE_OFFSET &&
                !(1 << ah->av.eth.stat_rate & dev->caps.stat_rate_support))
            --ah->av.eth.stat_rate;
    }

    /*
     * HW requires multicast LID so we just choose one.
     */
    if (is_mcast)
        ah->av.ib.dlid = cpu_to_be16(0xc000);

    memcpy(ah->av.eth.dgid, ah_attr->grh.dgid.raw, 16);
    ah->av.eth.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 29);

    return &ah->ibah;
}