diff options
| author | Parav Pandit <parav.pandit@emulex.com> | 2012-06-08 11:55:25 -0400 |
|---|---|---|
| committer | Roland Dreier <roland@purestorage.com> | 2012-06-11 12:38:32 -0400 |
| commit | 6ab6827ee99937834cc268298ee4eab1a651569e (patch) | |
| tree | aa17c93c0007aa19b908634162aa870a275dd5d5 | |
| parent | ae501be0f631bd4fb751c5f580e396f59b2011f1 (diff) | |
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>
| -rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_main.c | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index 04fef3de6d75..b050e629e9c3 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c | |||
| @@ -97,13 +97,11 @@ static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr, | |||
| 97 | sgid->raw[15] = mac_addr[5]; | 97 | sgid->raw[15] = mac_addr[5]; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, | 100 | static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, |
| 101 | bool is_vlan, u16 vlan_id) | 101 | bool is_vlan, u16 vlan_id) |
| 102 | { | 102 | { |
| 103 | int i; | 103 | int i; |
| 104 | bool found = false; | ||
| 105 | union ib_gid new_sgid; | 104 | union ib_gid new_sgid; |
| 106 | int free_idx = OCRDMA_MAX_SGID; | ||
| 107 | unsigned long flags; | 105 | unsigned long flags; |
| 108 | 106 | ||
| 109 | memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid)); | 107 | 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, | |||
| 115 | if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid, | 113 | if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid, |
| 116 | sizeof(union ib_gid))) { | 114 | sizeof(union ib_gid))) { |
| 117 | /* found free entry */ | 115 | /* found free entry */ |
| 118 | if (!found) { | 116 | memcpy(&dev->sgid_tbl[i], &new_sgid, |
| 119 | free_idx = i; | 117 | sizeof(union ib_gid)); |
| 120 | found = true; | 118 | spin_unlock_irqrestore(&dev->sgid_lock, flags); |
| 121 | break; | 119 | return true; |
| 122 | } | ||
| 123 | } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid, | 120 | } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid, |
| 124 | sizeof(union ib_gid))) { | 121 | sizeof(union ib_gid))) { |
| 125 | /* entry already present, no addition is required. */ | 122 | /* entry already present, no addition is required. */ |
| 126 | spin_unlock_irqrestore(&dev->sgid_lock, flags); | 123 | spin_unlock_irqrestore(&dev->sgid_lock, flags); |
| 127 | return; | 124 | return false; |
| 128 | } | 125 | } |
| 129 | } | 126 | } |
| 130 | /* if entry doesn't exist and if table has some space, add entry */ | ||
| 131 | if (found) | ||
| 132 | memcpy(&dev->sgid_tbl[free_idx], &new_sgid, | ||
| 133 | sizeof(union ib_gid)); | ||
| 134 | spin_unlock_irqrestore(&dev->sgid_lock, flags); | 127 | spin_unlock_irqrestore(&dev->sgid_lock, flags); |
| 128 | return false; | ||
| 135 | } | 129 | } |
| 136 | 130 | ||
| 137 | static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, | 131 | 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) | |||
| 167 | ocrdma_get_guid(dev, &sgid->raw[8]); | 161 | ocrdma_get_guid(dev, &sgid->raw[8]); |
| 168 | } | 162 | } |
| 169 | 163 | ||
| 170 | static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) | 164 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) |
| 165 | static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) | ||
| 171 | { | 166 | { |
| 172 | struct net_device *netdev, *tmp; | 167 | struct net_device *netdev, *tmp; |
| 173 | u16 vlan_id; | 168 | u16 vlan_id; |
| @@ -175,8 +170,6 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) | |||
| 175 | 170 | ||
| 176 | netdev = dev->nic_info.netdev; | 171 | netdev = dev->nic_info.netdev; |
| 177 | 172 | ||
| 178 | ocrdma_add_default_sgid(dev); | ||
| 179 | |||
| 180 | rcu_read_lock(); | 173 | rcu_read_lock(); |
| 181 | for_each_netdev_rcu(&init_net, tmp) { | 174 | for_each_netdev_rcu(&init_net, tmp) { |
| 182 | if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) { | 175 | if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) { |
| @@ -194,10 +187,23 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) | |||
| 194 | } | 187 | } |
| 195 | } | 188 | } |
| 196 | rcu_read_unlock(); | 189 | rcu_read_unlock(); |
| 190 | } | ||
| 191 | #else | ||
| 192 | static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) | ||
| 193 | { | ||
| 194 | |||
| 195 | } | ||
| 196 | #endif /* VLAN */ | ||
| 197 | |||
| 198 | static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) | ||
| 199 | { | ||
| 200 | ocrdma_add_default_sgid(dev); | ||
| 201 | ocrdma_add_vlan_sgids(dev); | ||
| 197 | return 0; | 202 | return 0; |
| 198 | } | 203 | } |
| 199 | 204 | ||
| 200 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 205 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) || \ |
| 206 | defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | ||
| 201 | 207 | ||
| 202 | static int ocrdma_inet6addr_event(struct notifier_block *notifier, | 208 | static int ocrdma_inet6addr_event(struct notifier_block *notifier, |
| 203 | unsigned long event, void *ptr) | 209 | unsigned long event, void *ptr) |
| @@ -208,6 +214,7 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, | |||
| 208 | struct ib_event gid_event; | 214 | struct ib_event gid_event; |
| 209 | struct ocrdma_dev *dev; | 215 | struct ocrdma_dev *dev; |
| 210 | bool found = false; | 216 | bool found = false; |
| 217 | bool updated = false; | ||
| 211 | bool is_vlan = false; | 218 | bool is_vlan = false; |
| 212 | u16 vid = 0; | 219 | u16 vid = 0; |
| 213 | 220 | ||
| @@ -233,23 +240,21 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, | |||
| 233 | mutex_lock(&dev->dev_lock); | 240 | mutex_lock(&dev->dev_lock); |
| 234 | switch (event) { | 241 | switch (event) { |
| 235 | case NETDEV_UP: | 242 | case NETDEV_UP: |
| 236 | ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); | 243 | updated = ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); |
| 237 | break; | 244 | break; |
| 238 | case NETDEV_DOWN: | 245 | case NETDEV_DOWN: |
| 239 | found = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); | 246 | updated = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); |
| 240 | if (found) { | ||
| 241 | /* found the matching entry, notify | ||
| 242 | * the consumers about it | ||
| 243 | */ | ||
| 244 | gid_event.device = &dev->ibdev; | ||
| 245 | gid_event.element.port_num = 1; | ||
| 246 | gid_event.event = IB_EVENT_GID_CHANGE; | ||
| 247 | ib_dispatch_event(&gid_event); | ||
| 248 | } | ||
| 249 | break; | 247 | break; |
| 250 | default: | 248 | default: |
| 251 | break; | 249 | break; |
| 252 | } | 250 | } |
| 251 | if (updated) { | ||
| 252 | /* GID table updated, notify the consumers about it */ | ||
| 253 | gid_event.device = &dev->ibdev; | ||
| 254 | gid_event.element.port_num = 1; | ||
| 255 | gid_event.event = IB_EVENT_GID_CHANGE; | ||
| 256 | ib_dispatch_event(&gid_event); | ||
| 257 | } | ||
| 253 | mutex_unlock(&dev->dev_lock); | 258 | mutex_unlock(&dev->dev_lock); |
| 254 | return NOTIFY_OK; | 259 | return NOTIFY_OK; |
| 255 | } | 260 | } |
| @@ -258,7 +263,7 @@ static struct notifier_block ocrdma_inet6addr_notifier = { | |||
| 258 | .notifier_call = ocrdma_inet6addr_event | 263 | .notifier_call = ocrdma_inet6addr_event |
| 259 | }; | 264 | }; |
| 260 | 265 | ||
| 261 | #endif /* IPV6 */ | 266 | #endif /* IPV6 and VLAN */ |
| 262 | 267 | ||
| 263 | static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device, | 268 | static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device, |
| 264 | u8 port_num) | 269 | u8 port_num) |
