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

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

Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parents 8206ceb0 b209a368
...@@ -139,6 +139,7 @@ void opa_vnic_release_mac_tbl(struct opa_vnic_adapter *adapter) ...@@ -139,6 +139,7 @@ void opa_vnic_release_mac_tbl(struct opa_vnic_adapter *adapter)
rcu_assign_pointer(adapter->mactbl, NULL); rcu_assign_pointer(adapter->mactbl, NULL);
synchronize_rcu(); synchronize_rcu();
opa_vnic_free_mac_tbl(mactbl); opa_vnic_free_mac_tbl(mactbl);
adapter->info.vport.mac_tbl_digest = 0;
mutex_unlock(&adapter->mactbl_lock); mutex_unlock(&adapter->mactbl_lock);
} }
...@@ -405,6 +406,42 @@ u8 opa_vnic_get_vl(struct opa_vnic_adapter *adapter, struct sk_buff *skb) ...@@ -405,6 +406,42 @@ u8 opa_vnic_get_vl(struct opa_vnic_adapter *adapter, struct sk_buff *skb)
return vl; 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 */ /* opa_vnic_calc_entropy - calculate the packet entropy */
u8 opa_vnic_calc_entropy(struct opa_vnic_adapter *adapter, struct sk_buff *skb) 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) ...@@ -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_veswport_info *info = &adapter->info;
struct opa_vnic_skb_mdata *mdata; struct opa_vnic_skb_mdata *mdata;
u8 def_port, sc, entropy, *hdr; u8 def_port, sc, rc, entropy, *hdr;
u16 len, l4_hdr; u16 len, l4_hdr;
u32 dlid; u32 dlid;
...@@ -458,6 +495,7 @@ void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb) ...@@ -458,6 +495,7 @@ void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb)
len = opa_vnic_wire_length(skb); len = opa_vnic_wire_length(skb);
dlid = opa_vnic_get_dlid(adapter, skb, def_port); dlid = opa_vnic_get_dlid(adapter, skb, def_port);
sc = opa_vnic_get_sc(info, skb); sc = opa_vnic_get_sc(info, skb);
rc = opa_vnic_get_rc(info, skb);
l4_hdr = info->vesw.vesw_id; l4_hdr = info->vesw.vesw_id;
mdata = skb_push(skb, sizeof(*mdata)); mdata = skb_push(skb, sizeof(*mdata));
...@@ -470,6 +508,6 @@ void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb) ...@@ -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, 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); OPA_VNIC_L4_ETHR, l4_hdr);
} }
...@@ -103,6 +103,17 @@ ...@@ -103,6 +103,17 @@
#define OPA_VNIC_ETH_LINK_UP 1 #define OPA_VNIC_ETH_LINK_UP 1
#define OPA_VNIC_ETH_LINK_DOWN 2 #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 * struct opa_vesw_info - OPA vnic switch information
* @fabric_id: 10-bit fabric id * @fabric_id: 10-bit fabric id
...@@ -111,8 +122,8 @@ ...@@ -111,8 +122,8 @@
* @pkey: partition key * @pkey: partition key
* @u_mcast_dlid: unknown multicast dlid * @u_mcast_dlid: unknown multicast dlid
* @u_ucast_dlid: array of unknown unicast dlids * @u_ucast_dlid: array of unknown unicast dlids
* @eth_mtu: MTUs for each vlan PCP * @rc: routing control
* @eth_mtu_non_vlan: MTU for non vlan packets * @eth_mtu: Ethernet MTU
*/ */
struct opa_vesw_info { struct opa_vesw_info {
__be16 fabric_id; __be16 fabric_id;
...@@ -128,9 +139,10 @@ struct opa_vesw_info { ...@@ -128,9 +139,10 @@ struct opa_vesw_info {
__be32 u_mcast_dlid; __be32 u_mcast_dlid;
__be32 u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT]; __be32 u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT];
u8 rsvd3[44]; __be32 rc;
__be16 eth_mtu[OPA_VNIC_MAX_NUM_PCP];
__be16 eth_mtu_non_vlan; u8 rsvd3[56];
__be16 eth_mtu;
u8 rsvd4[2]; u8 rsvd4[2];
} __packed; } __packed;
......
...@@ -89,9 +89,10 @@ struct __opa_vesw_info { ...@@ -89,9 +89,10 @@ struct __opa_vesw_info {
u32 u_mcast_dlid; u32 u_mcast_dlid;
u32 u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT]; u32 u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT];
u8 rsvd3[44]; u32 rc;
u16 eth_mtu[OPA_VNIC_MAX_NUM_PCP];
u16 eth_mtu_non_vlan; u8 rsvd3[56];
u16 eth_mtu;
u8 rsvd4[2]; u8 rsvd4[2];
} __packed; } __packed;
......
...@@ -112,6 +112,27 @@ static u16 opa_vnic_select_queue(struct net_device *netdev, struct sk_buff *skb, ...@@ -112,6 +112,27 @@ static u16 opa_vnic_select_queue(struct net_device *netdev, struct sk_buff *skb,
return rc; 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 */ /* opa_vnic_process_vema_config - process vema configuration updates */
void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter) 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) ...@@ -130,7 +151,7 @@ void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter)
memcpy(saddr.sa_data, info->vport.base_mac_addr, memcpy(saddr.sa_data, info->vport.base_mac_addr,
ARRAY_SIZE(info->vport.base_mac_addr)); ARRAY_SIZE(info->vport.base_mac_addr));
mutex_lock(&adapter->lock); mutex_lock(&adapter->lock);
eth_mac_addr(netdev, &saddr); eth_commit_mac_addr_change(netdev, &saddr);
memcpy(adapter->vema_mac_addr, memcpy(adapter->vema_mac_addr,
info->vport.base_mac_addr, ETH_ALEN); info->vport.base_mac_addr, ETH_ALEN);
mutex_unlock(&adapter->lock); mutex_unlock(&adapter->lock);
...@@ -140,7 +161,7 @@ void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter) ...@@ -140,7 +161,7 @@ void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter)
/* Handle MTU limit change */ /* Handle MTU limit change */
rtnl_lock(); 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); netdev->min_mtu);
if (netdev->mtu > netdev->max_mtu) if (netdev->mtu > netdev->max_mtu)
dev_set_mtu(netdev, 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) ...@@ -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] : adapter->flow_tbl[i] = port_count ? port_num[i % port_count] :
OPA_VNIC_INVALID_PORT; OPA_VNIC_INVALID_PORT;
/* Operational state can only be DROP_ALL or FORWARDING */ /* update state */
if (info->vport.config_state == OPA_VNIC_STATE_FORWARDING) { opa_vnic_update_state(adapter, !!(netdev->flags & IFF_UP));
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);
}
} }
/* /*
...@@ -183,6 +198,7 @@ static inline void opa_vnic_set_pod_values(struct opa_vnic_adapter *adapter) ...@@ -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.max_smac_ent = OPA_VNIC_MAX_SMAC_LIMIT;
adapter->info.vport.config_state = OPA_VNIC_STATE_DROP_ALL; adapter->info.vport.config_state = OPA_VNIC_STATE_DROP_ALL;
adapter->info.vport.eth_link_status = OPA_VNIC_ETH_LINK_DOWN; 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 */ /* opa_vnic_set_mac_addr - change mac address */
...@@ -268,8 +284,8 @@ static int opa_netdev_open(struct net_device *netdev) ...@@ -268,8 +284,8 @@ static int opa_netdev_open(struct net_device *netdev)
return rc; return rc;
} }
/* Update eth link status and send trap */ /* Update status and send trap */
adapter->info.vport.eth_link_status = OPA_VNIC_ETH_LINK_UP; opa_vnic_update_state(adapter, true);
opa_vnic_vema_report_event(adapter, opa_vnic_vema_report_event(adapter,
OPA_VESWPORT_TRAP_ETH_LINK_STATUS_CHANGE); OPA_VESWPORT_TRAP_ETH_LINK_STATUS_CHANGE);
return 0; return 0;
...@@ -287,8 +303,8 @@ static int opa_netdev_close(struct net_device *netdev) ...@@ -287,8 +303,8 @@ static int opa_netdev_close(struct net_device *netdev)
return rc; return rc;
} }
/* Update eth link status and send trap */ /* Update status and send trap */
adapter->info.vport.eth_link_status = OPA_VNIC_ETH_LINK_DOWN; opa_vnic_update_state(adapter, false);
opa_vnic_vema_report_event(adapter, opa_vnic_vema_report_event(adapter,
OPA_VESWPORT_TRAP_ETH_LINK_STATUS_CHANGE); OPA_VESWPORT_TRAP_ETH_LINK_STATUS_CHANGE);
return 0; return 0;
......
...@@ -186,6 +186,7 @@ static inline void vema_get_pod_values(struct opa_veswport_info *port_info) ...@@ -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); cpu_to_be16(OPA_VNIC_MAX_SMAC_LIMIT);
port_info->vport.oper_state = OPA_VNIC_STATE_DROP_ALL; port_info->vport.oper_state = OPA_VNIC_STATE_DROP_ALL;
port_info->vport.config_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);
} }
/** /**
......
...@@ -176,11 +176,10 @@ void opa_vnic_get_vesw_info(struct opa_vnic_adapter *adapter, ...@@ -176,11 +176,10 @@ void opa_vnic_get_vesw_info(struct opa_vnic_adapter *adapter,
for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++) for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++)
info->u_ucast_dlid[i] = cpu_to_be32(src->u_ucast_dlid[i]); info->u_ucast_dlid[i] = cpu_to_be32(src->u_ucast_dlid[i]);
memcpy(info->rsvd3, src->rsvd3, ARRAY_SIZE(src->rsvd3)); info->rc = cpu_to_be32(src->rc);
for (i = 0; i < OPA_VNIC_MAX_NUM_PCP; i++)
info->eth_mtu[i] = cpu_to_be16(src->eth_mtu[i]);
info->eth_mtu_non_vlan = cpu_to_be16(src->eth_mtu_non_vlan); memcpy(info->rsvd3, src->rsvd3, ARRAY_SIZE(src->rsvd3));
info->eth_mtu = cpu_to_be16(src->eth_mtu);
memcpy(info->rsvd4, src->rsvd4, ARRAY_SIZE(src->rsvd4)); memcpy(info->rsvd4, src->rsvd4, ARRAY_SIZE(src->rsvd4));
} }
...@@ -211,11 +210,10 @@ void opa_vnic_set_vesw_info(struct opa_vnic_adapter *adapter, ...@@ -211,11 +210,10 @@ void opa_vnic_set_vesw_info(struct opa_vnic_adapter *adapter,
for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++) for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++)
dst->u_ucast_dlid[i] = be32_to_cpu(info->u_ucast_dlid[i]); dst->u_ucast_dlid[i] = be32_to_cpu(info->u_ucast_dlid[i]);
memcpy(dst->rsvd3, info->rsvd3, ARRAY_SIZE(info->rsvd3)); dst->rc = be32_to_cpu(info->rc);
for (i = 0; i < OPA_VNIC_MAX_NUM_PCP; i++)
dst->eth_mtu[i] = be16_to_cpu(info->eth_mtu[i]);
dst->eth_mtu_non_vlan = be16_to_cpu(info->eth_mtu_non_vlan); memcpy(dst->rsvd3, info->rsvd3, ARRAY_SIZE(info->rsvd3));
dst->eth_mtu = be16_to_cpu(info->eth_mtu);
memcpy(dst->rsvd4, info->rsvd4, ARRAY_SIZE(info->rsvd4)); memcpy(dst->rsvd4, info->rsvd4, ARRAY_SIZE(info->rsvd4));
} }
...@@ -348,7 +346,7 @@ void opa_vnic_query_mcast_macs(struct opa_vnic_adapter *adapter, ...@@ -348,7 +346,7 @@ void opa_vnic_query_mcast_macs(struct opa_vnic_adapter *adapter,
void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter, void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter,
struct opa_veswport_iface_macs *macs) struct opa_veswport_iface_macs *macs)
{ {
u16 start_idx, tot_macs, num_macs, idx = 0, count = 0; u16 start_idx, tot_macs, num_macs, idx = 0, count = 0, em_macs = 0;
struct netdev_hw_addr *ha; struct netdev_hw_addr *ha;
start_idx = be16_to_cpu(macs->start_idx); start_idx = be16_to_cpu(macs->start_idx);
...@@ -359,8 +357,10 @@ void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter, ...@@ -359,8 +357,10 @@ void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter,
/* Do not include EM specified MAC address */ /* Do not include EM specified MAC address */
if (!memcmp(adapter->info.vport.base_mac_addr, ha->addr, if (!memcmp(adapter->info.vport.base_mac_addr, ha->addr,
ARRAY_SIZE(adapter->info.vport.base_mac_addr))) ARRAY_SIZE(adapter->info.vport.base_mac_addr))) {
em_macs++;
continue; continue;
}
if (start_idx > idx++) if (start_idx > idx++)
continue; continue;
...@@ -383,7 +383,7 @@ void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter, ...@@ -383,7 +383,7 @@ void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter,
} }
tot_macs = netdev_hw_addr_list_count(&adapter->netdev->dev_addrs) + tot_macs = netdev_hw_addr_list_count(&adapter->netdev->dev_addrs) +
netdev_uc_count(adapter->netdev); netdev_uc_count(adapter->netdev) - em_macs;
macs->tot_macs_in_lst = cpu_to_be16(tot_macs); macs->tot_macs_in_lst = cpu_to_be16(tot_macs);
macs->num_macs_in_msg = cpu_to_be16(count); macs->num_macs_in_msg = cpu_to_be16(count);
macs->gen_count = cpu_to_be16(adapter->info.vport.uc_macs_gen_count); macs->gen_count = cpu_to_be16(adapter->info.vport.uc_macs_gen_count);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment