mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-11 08:18:47 +00:00
RDMA/ocrdma: Fixed GID table for vlan and events
1. Fix reporting GID table addition events. 2. Enable vlan based GID entries only when VLAN is enabled at compile time (test CONFIG_VLAN_8021Q / CONFIG_VLAN_8021Q_MODULE). Signed-off-by: Parav Pandit <parav.pandit@emulex.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
parent
ae501be0f6
commit
6ab6827ee9
@ -97,13 +97,11 @@ static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr,
|
|||||||
sgid->raw[15] = mac_addr[5];
|
sgid->raw[15] = mac_addr[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
|
static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
|
||||||
bool is_vlan, u16 vlan_id)
|
bool is_vlan, u16 vlan_id)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool found = false;
|
|
||||||
union ib_gid new_sgid;
|
union ib_gid new_sgid;
|
||||||
int free_idx = OCRDMA_MAX_SGID;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid));
|
memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid));
|
||||||
@ -115,23 +113,19 @@ static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
|
|||||||
if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid,
|
if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid,
|
||||||
sizeof(union ib_gid))) {
|
sizeof(union ib_gid))) {
|
||||||
/* found free entry */
|
/* found free entry */
|
||||||
if (!found) {
|
memcpy(&dev->sgid_tbl[i], &new_sgid,
|
||||||
free_idx = i;
|
sizeof(union ib_gid));
|
||||||
found = true;
|
spin_unlock_irqrestore(&dev->sgid_lock, flags);
|
||||||
break;
|
return true;
|
||||||
}
|
|
||||||
} else if (!memcmp(&dev->sgid_tbl[i], &new_sgid,
|
} else if (!memcmp(&dev->sgid_tbl[i], &new_sgid,
|
||||||
sizeof(union ib_gid))) {
|
sizeof(union ib_gid))) {
|
||||||
/* entry already present, no addition is required. */
|
/* entry already present, no addition is required. */
|
||||||
spin_unlock_irqrestore(&dev->sgid_lock, flags);
|
spin_unlock_irqrestore(&dev->sgid_lock, flags);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* if entry doesn't exist and if table has some space, add entry */
|
|
||||||
if (found)
|
|
||||||
memcpy(&dev->sgid_tbl[free_idx], &new_sgid,
|
|
||||||
sizeof(union ib_gid));
|
|
||||||
spin_unlock_irqrestore(&dev->sgid_lock, flags);
|
spin_unlock_irqrestore(&dev->sgid_lock, flags);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
|
static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
|
||||||
@ -167,7 +161,8 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev)
|
|||||||
ocrdma_get_guid(dev, &sgid->raw[8]);
|
ocrdma_get_guid(dev, &sgid->raw[8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
|
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
|
||||||
|
static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev)
|
||||||
{
|
{
|
||||||
struct net_device *netdev, *tmp;
|
struct net_device *netdev, *tmp;
|
||||||
u16 vlan_id;
|
u16 vlan_id;
|
||||||
@ -175,8 +170,6 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
|
|||||||
|
|
||||||
netdev = dev->nic_info.netdev;
|
netdev = dev->nic_info.netdev;
|
||||||
|
|
||||||
ocrdma_add_default_sgid(dev);
|
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
for_each_netdev_rcu(&init_net, tmp) {
|
for_each_netdev_rcu(&init_net, tmp) {
|
||||||
if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) {
|
if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) {
|
||||||
@ -194,10 +187,23 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif /* VLAN */
|
||||||
|
|
||||||
|
static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
|
||||||
|
{
|
||||||
|
ocrdma_add_default_sgid(dev);
|
||||||
|
ocrdma_add_vlan_sgids(dev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) || \
|
||||||
|
defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
|
||||||
|
|
||||||
static int ocrdma_inet6addr_event(struct notifier_block *notifier,
|
static int ocrdma_inet6addr_event(struct notifier_block *notifier,
|
||||||
unsigned long event, void *ptr)
|
unsigned long event, void *ptr)
|
||||||
@ -208,6 +214,7 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier,
|
|||||||
struct ib_event gid_event;
|
struct ib_event gid_event;
|
||||||
struct ocrdma_dev *dev;
|
struct ocrdma_dev *dev;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
bool updated = false;
|
||||||
bool is_vlan = false;
|
bool is_vlan = false;
|
||||||
u16 vid = 0;
|
u16 vid = 0;
|
||||||
|
|
||||||
@ -233,23 +240,21 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier,
|
|||||||
mutex_lock(&dev->dev_lock);
|
mutex_lock(&dev->dev_lock);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case NETDEV_UP:
|
case NETDEV_UP:
|
||||||
ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid);
|
updated = ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid);
|
||||||
break;
|
break;
|
||||||
case NETDEV_DOWN:
|
case NETDEV_DOWN:
|
||||||
found = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid);
|
updated = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid);
|
||||||
if (found) {
|
|
||||||
/* found the matching entry, notify
|
|
||||||
* the consumers about it
|
|
||||||
*/
|
|
||||||
gid_event.device = &dev->ibdev;
|
|
||||||
gid_event.element.port_num = 1;
|
|
||||||
gid_event.event = IB_EVENT_GID_CHANGE;
|
|
||||||
ib_dispatch_event(&gid_event);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (updated) {
|
||||||
|
/* GID table updated, notify the consumers about it */
|
||||||
|
gid_event.device = &dev->ibdev;
|
||||||
|
gid_event.element.port_num = 1;
|
||||||
|
gid_event.event = IB_EVENT_GID_CHANGE;
|
||||||
|
ib_dispatch_event(&gid_event);
|
||||||
|
}
|
||||||
mutex_unlock(&dev->dev_lock);
|
mutex_unlock(&dev->dev_lock);
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
}
|
}
|
||||||
@ -258,7 +263,7 @@ static struct notifier_block ocrdma_inet6addr_notifier = {
|
|||||||
.notifier_call = ocrdma_inet6addr_event
|
.notifier_call = ocrdma_inet6addr_event
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* IPV6 */
|
#endif /* IPV6 and VLAN */
|
||||||
|
|
||||||
static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device,
|
static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device,
|
||||||
u8 port_num)
|
u8 port_num)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user