Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ff4b7e6 authored by Doug Ledford's avatar Doug Ledford
Browse files

Merge branch 'vnic' into k.o/for-next

parents 8206ceb0 b209a368
Loading
Loading
Loading
Loading
+40 −2
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ void opa_vnic_release_mac_tbl(struct opa_vnic_adapter *adapter)
	rcu_assign_pointer(adapter->mactbl, NULL);
	synchronize_rcu();
	opa_vnic_free_mac_tbl(mactbl);
	adapter->info.vport.mac_tbl_digest = 0;
	mutex_unlock(&adapter->mactbl_lock);
}

@@ -405,6 +406,42 @@ u8 opa_vnic_get_vl(struct opa_vnic_adapter *adapter, struct sk_buff *skb)
	return vl;
}

/* opa_vnic_get_rc - return the routing control */
static u8 opa_vnic_get_rc(struct __opa_veswport_info *info,
			  struct sk_buff *skb)
{
	u8 proto, rout_ctrl;

	switch (vlan_get_protocol(skb)) {
	case htons(ETH_P_IPV6):
		proto = ipv6_hdr(skb)->nexthdr;
		if (proto == IPPROTO_TCP)
			rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc,
							  IPV6_TCP);
		else if (proto == IPPROTO_UDP)
			rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc,
							  IPV6_UDP);
		else
			rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, IPV6);
		break;
	case htons(ETH_P_IP):
		proto = ip_hdr(skb)->protocol;
		if (proto == IPPROTO_TCP)
			rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc,
							  IPV4_TCP);
		else if (proto == IPPROTO_UDP)
			rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc,
							  IPV4_UDP);
		else
			rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, IPV4);
		break;
	default:
		rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, DEFAULT);
	}

	return rout_ctrl;
}

/* opa_vnic_calc_entropy - calculate the packet entropy */
u8 opa_vnic_calc_entropy(struct opa_vnic_adapter *adapter, struct sk_buff *skb)
{
@@ -447,7 +484,7 @@ void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb)
{
	struct __opa_veswport_info *info = &adapter->info;
	struct opa_vnic_skb_mdata *mdata;
	u8 def_port, sc, entropy, *hdr;
	u8 def_port, sc, rc, entropy, *hdr;
	u16 len, l4_hdr;
	u32 dlid;

@@ -458,6 +495,7 @@ void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb)
	len = opa_vnic_wire_length(skb);
	dlid = opa_vnic_get_dlid(adapter, skb, def_port);
	sc = opa_vnic_get_sc(info, skb);
	rc = opa_vnic_get_rc(info, skb);
	l4_hdr = info->vesw.vesw_id;

	mdata = skb_push(skb, sizeof(*mdata));
@@ -470,6 +508,6 @@ void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb)
	}

	opa_vnic_make_header(hdr, info->vport.encap_slid, dlid, len,
			     info->vesw.pkey, entropy, sc, 0,
			     info->vesw.pkey, entropy, sc, rc,
			     OPA_VNIC_L4_ETHR, l4_hdr);
}
+17 −5
Original line number Diff line number Diff line
@@ -103,6 +103,17 @@
#define OPA_VNIC_ETH_LINK_UP     1
#define OPA_VNIC_ETH_LINK_DOWN   2

/* routing control */
#define OPA_VNIC_ENCAP_RC_DEFAULT   0
#define OPA_VNIC_ENCAP_RC_IPV4      4
#define OPA_VNIC_ENCAP_RC_IPV4_UDP  8
#define OPA_VNIC_ENCAP_RC_IPV4_TCP  12
#define OPA_VNIC_ENCAP_RC_IPV6      16
#define OPA_VNIC_ENCAP_RC_IPV6_TCP  20
#define OPA_VNIC_ENCAP_RC_IPV6_UDP  24

#define OPA_VNIC_ENCAP_RC_EXT(w, b) (((w) >> OPA_VNIC_ENCAP_RC_ ## b) & 0x7)

/**
 * struct opa_vesw_info - OPA vnic switch information
 * @fabric_id: 10-bit fabric id
@@ -111,8 +122,8 @@
 * @pkey: partition key
 * @u_mcast_dlid: unknown multicast dlid
 * @u_ucast_dlid: array of unknown unicast dlids
 * @eth_mtu: MTUs for each vlan PCP
 * @eth_mtu_non_vlan: MTU for non vlan packets
 * @rc: routing control
 * @eth_mtu: Ethernet MTU
 */
struct opa_vesw_info {
	__be16  fabric_id;
@@ -128,9 +139,10 @@ struct opa_vesw_info {
	__be32  u_mcast_dlid;
	__be32  u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT];

	u8      rsvd3[44];
	__be16  eth_mtu[OPA_VNIC_MAX_NUM_PCP];
	__be16  eth_mtu_non_vlan;
	__be32  rc;

	u8      rsvd3[56];
	__be16  eth_mtu;
	u8      rsvd4[2];
} __packed;

+4 −3
Original line number Diff line number Diff line
@@ -89,9 +89,10 @@ struct __opa_vesw_info {
	u32  u_mcast_dlid;
	u32  u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT];

	u8   rsvd3[44];
	u16  eth_mtu[OPA_VNIC_MAX_NUM_PCP];
	u16  eth_mtu_non_vlan;
	u32  rc;

	u8   rsvd3[56];
	u16  eth_mtu;
	u8   rsvd4[2];
} __packed;

+30 −14
Original line number Diff line number Diff line
@@ -112,6 +112,27 @@ static u16 opa_vnic_select_queue(struct net_device *netdev, struct sk_buff *skb,
	return rc;
}

static void opa_vnic_update_state(struct opa_vnic_adapter *adapter, bool up)
{
	struct __opa_veswport_info *info = &adapter->info;

	mutex_lock(&adapter->lock);
	/* Operational state can only be DROP_ALL or FORWARDING */
	if ((info->vport.config_state == OPA_VNIC_STATE_FORWARDING) && up) {
		info->vport.oper_state = OPA_VNIC_STATE_FORWARDING;
		info->vport.eth_link_status = OPA_VNIC_ETH_LINK_UP;
	} else {
		info->vport.oper_state = OPA_VNIC_STATE_DROP_ALL;
		info->vport.eth_link_status = OPA_VNIC_ETH_LINK_DOWN;
	}

	if (info->vport.config_state == OPA_VNIC_STATE_FORWARDING)
		netif_dormant_off(adapter->netdev);
	else
		netif_dormant_on(adapter->netdev);
	mutex_unlock(&adapter->lock);
}

/* opa_vnic_process_vema_config - process vema configuration updates */
void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter)
{
@@ -130,7 +151,7 @@ void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter)
		memcpy(saddr.sa_data, info->vport.base_mac_addr,
		       ARRAY_SIZE(info->vport.base_mac_addr));
		mutex_lock(&adapter->lock);
		eth_mac_addr(netdev, &saddr);
		eth_commit_mac_addr_change(netdev, &saddr);
		memcpy(adapter->vema_mac_addr,
		       info->vport.base_mac_addr, ETH_ALEN);
		mutex_unlock(&adapter->lock);
@@ -140,7 +161,7 @@ void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter)

	/* Handle MTU limit change */
	rtnl_lock();
	netdev->max_mtu = max_t(unsigned int, info->vesw.eth_mtu_non_vlan,
	netdev->max_mtu = max_t(unsigned int, info->vesw.eth_mtu,
				netdev->min_mtu);
	if (netdev->mtu > netdev->max_mtu)
		dev_set_mtu(netdev, netdev->max_mtu);
@@ -164,14 +185,8 @@ void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter)
		adapter->flow_tbl[i] = port_count ? port_num[i % port_count] :
						    OPA_VNIC_INVALID_PORT;

	/* Operational state can only be DROP_ALL or FORWARDING */
	if (info->vport.config_state == OPA_VNIC_STATE_FORWARDING) {
		info->vport.oper_state = OPA_VNIC_STATE_FORWARDING;
		netif_dormant_off(netdev);
	} else {
		info->vport.oper_state = OPA_VNIC_STATE_DROP_ALL;
		netif_dormant_on(netdev);
	}
	/* update state */
	opa_vnic_update_state(adapter, !!(netdev->flags & IFF_UP));
}

/*
@@ -183,6 +198,7 @@ static inline void opa_vnic_set_pod_values(struct opa_vnic_adapter *adapter)
	adapter->info.vport.max_smac_ent = OPA_VNIC_MAX_SMAC_LIMIT;
	adapter->info.vport.config_state = OPA_VNIC_STATE_DROP_ALL;
	adapter->info.vport.eth_link_status = OPA_VNIC_ETH_LINK_DOWN;
	adapter->info.vesw.eth_mtu = ETH_DATA_LEN;
}

/* opa_vnic_set_mac_addr - change mac address */
@@ -268,8 +284,8 @@ static int opa_netdev_open(struct net_device *netdev)
		return rc;
	}

	/* Update eth link status and send trap */
	adapter->info.vport.eth_link_status = OPA_VNIC_ETH_LINK_UP;
	/* Update status and send trap */
	opa_vnic_update_state(adapter, true);
	opa_vnic_vema_report_event(adapter,
				   OPA_VESWPORT_TRAP_ETH_LINK_STATUS_CHANGE);
	return 0;
@@ -287,8 +303,8 @@ static int opa_netdev_close(struct net_device *netdev)
		return rc;
	}

	/* Update eth link status and send trap */
	adapter->info.vport.eth_link_status = OPA_VNIC_ETH_LINK_DOWN;
	/* Update status and send trap */
	opa_vnic_update_state(adapter, false);
	opa_vnic_vema_report_event(adapter,
				   OPA_VESWPORT_TRAP_ETH_LINK_STATUS_CHANGE);
	return 0;
+1 −0
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@ static inline void vema_get_pod_values(struct opa_veswport_info *port_info)
		cpu_to_be16(OPA_VNIC_MAX_SMAC_LIMIT);
	port_info->vport.oper_state = OPA_VNIC_STATE_DROP_ALL;
	port_info->vport.config_state = OPA_VNIC_STATE_DROP_ALL;
	port_info->vesw.eth_mtu = cpu_to_be16(ETH_DATA_LEN);
}

/**
Loading