aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ocrdma/ocrdma_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ocrdma/ocrdma_main.c')
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_main.c63
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
100static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, 100static 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
137static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, 131static 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
170static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) 164#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
165static 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
192static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev)
193{
194
195}
196#endif /* VLAN */
197
198static 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) || \
206defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
201 207
202static int ocrdma_inet6addr_event(struct notifier_block *notifier, 208static 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
263static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device, 268static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device,
264 u8 port_num) 269 u8 port_num)