|
@@ -100,8 +100,12 @@ static struct ipoib_mac ipoib_broadcast = {
|
100
|
100
|
/**
|
101
|
101
|
* IPoIB peer address
|
102
|
102
|
*
|
103
|
|
- * This serves a similar role to the ARP cache for Ethernet. (ARP
|
104
|
|
- * *is* used on IPoIB; we have two caches to maintain.)
|
|
103
|
+ * The IPoIB link-layer header is only four bytes long and so does not
|
|
104
|
+ * have sufficient room to store IPoIB MAC address(es). We therefore
|
|
105
|
+ * maintain a cache of MAC addresses identified by a single-byte key,
|
|
106
|
+ * and abuse the spare two bytes within the link-layer header to
|
|
107
|
+ * communicate these MAC addresses between the link-layer code and the
|
|
108
|
+ * netdevice driver.
|
105
|
109
|
*/
|
106
|
110
|
struct ipoib_peer {
|
107
|
111
|
/** Key */
|
|
@@ -145,28 +149,6 @@ static struct ipoib_peer * ipoib_lookup_peer_by_key ( unsigned int key ) {
|
145
|
149
|
return NULL;
|
146
|
150
|
}
|
147
|
151
|
|
148
|
|
-/**
|
149
|
|
- * Look up cached peer by GID
|
150
|
|
- *
|
151
|
|
- * @v gid Peer GID
|
152
|
|
- * @ret peer Peer cache entry, or NULL
|
153
|
|
- */
|
154
|
|
-static struct ipoib_peer *
|
155
|
|
-ipoib_lookup_peer_by_gid ( const struct ib_gid *gid ) {
|
156
|
|
- struct ipoib_peer *peer;
|
157
|
|
- unsigned int i;
|
158
|
|
-
|
159
|
|
- for ( i = 0 ; i < IPOIB_NUM_CACHED_PEERS ; i++ ) {
|
160
|
|
- peer = &ipoib_peer_cache[i];
|
161
|
|
- if ( memcmp ( &peer->mac.gid, gid,
|
162
|
|
- sizeof ( peer->mac.gid) ) == 0 ) {
|
163
|
|
- return peer;
|
164
|
|
- }
|
165
|
|
- }
|
166
|
|
-
|
167
|
|
- return NULL;
|
168
|
|
-}
|
169
|
|
-
|
170
|
152
|
/**
|
171
|
153
|
* Store GID and QPN in peer cache
|
172
|
154
|
*
|
|
@@ -174,16 +156,16 @@ ipoib_lookup_peer_by_gid ( const struct ib_gid *gid ) {
|
174
|
156
|
* @v qpn Peer QPN
|
175
|
157
|
* @ret peer Peer cache entry
|
176
|
158
|
*/
|
177
|
|
-static struct ipoib_peer *
|
178
|
|
-ipoib_cache_peer ( const struct ib_gid *gid, unsigned long qpn ) {
|
|
159
|
+static struct ipoib_peer * ipoib_cache_peer ( const struct ipoib_mac *mac ) {
|
179
|
160
|
struct ipoib_peer *peer;
|
180
|
161
|
unsigned int key;
|
|
162
|
+ unsigned int i;
|
181
|
163
|
|
182
|
164
|
/* Look for existing cache entry */
|
183
|
|
- peer = ipoib_lookup_peer_by_gid ( gid );
|
184
|
|
- if ( peer ) {
|
185
|
|
- assert ( peer->mac.qpn = ntohl ( qpn ) );
|
186
|
|
- return peer;
|
|
165
|
+ for ( i = 0 ; i < IPOIB_NUM_CACHED_PEERS ; i++ ) {
|
|
166
|
+ peer = &ipoib_peer_cache[i];
|
|
167
|
+ if ( memcmp ( &peer->mac, mac, sizeof ( peer->mac ) ) == 0 )
|
|
168
|
+ return peer;
|
187
|
169
|
}
|
188
|
170
|
|
189
|
171
|
/* No entry found: create a new one */
|
|
@@ -194,12 +176,9 @@ ipoib_cache_peer ( const struct ib_gid *gid, unsigned long qpn ) {
|
194
|
176
|
|
195
|
177
|
memset ( peer, 0, sizeof ( *peer ) );
|
196
|
178
|
peer->key = key;
|
197
|
|
- peer->mac.qpn = htonl ( qpn );
|
198
|
|
- memcpy ( &peer->mac.gid, gid, sizeof ( peer->mac.gid ) );
|
199
|
|
- DBG ( "IPoIB peer %x has GID %08x:%08x:%08x:%08x and QPN %lx\n",
|
200
|
|
- peer->key, htonl ( gid->u.dwords[0] ),
|
201
|
|
- htonl ( gid->u.dwords[1] ), htonl ( gid->u.dwords[2] ),
|
202
|
|
- htonl ( gid->u.dwords[3] ), qpn );
|
|
179
|
+ memcpy ( &peer->mac, mac, sizeof ( peer->mac ) );
|
|
180
|
+ DBG ( "IPoIB peer %x has MAC %s\n",
|
|
181
|
+ peer->key, ipoib_ntoa ( &peer->mac ) );
|
203
|
182
|
return peer;
|
204
|
183
|
}
|
205
|
184
|
|
|
@@ -231,8 +210,8 @@ static int ipoib_push ( struct net_device *netdev __unused,
|
231
|
210
|
struct ipoib_peer *src;
|
232
|
211
|
|
233
|
212
|
/* Add link-layer addresses to cache */
|
234
|
|
- dest = ipoib_cache_peer ( &dest_mac->gid, ntohl ( dest_mac->qpn ) );
|
235
|
|
- src = ipoib_cache_peer ( &src_mac->gid, ntohl ( src_mac->qpn ) );
|
|
213
|
+ dest = ipoib_cache_peer ( dest_mac );
|
|
214
|
+ src = ipoib_cache_peer ( src_mac );
|
236
|
215
|
|
237
|
216
|
/* Build IPoIB header */
|
238
|
217
|
ipoib_hdr->proto = net_proto;
|
|
@@ -497,6 +476,7 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
|
497
|
476
|
struct ipoib_device *ipoib = ib_qp_get_ownerdata ( qp );
|
498
|
477
|
struct net_device *netdev = ipoib->netdev;
|
499
|
478
|
struct ipoib_hdr *ipoib_hdr;
|
|
479
|
+ struct ipoib_mac ll_src;
|
500
|
480
|
struct ipoib_peer *src;
|
501
|
481
|
|
502
|
482
|
if ( rc != 0 ) {
|
|
@@ -516,7 +496,9 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
|
516
|
496
|
|
517
|
497
|
/* Parse source address */
|
518
|
498
|
if ( av->gid_present ) {
|
519
|
|
- src = ipoib_cache_peer ( &av->gid, av->qpn );
|
|
499
|
+ ll_src.qpn = htonl ( av->qpn );
|
|
500
|
+ memcpy ( &ll_src.gid, &av->gid, sizeof ( ll_src.gid ) );
|
|
501
|
+ src = ipoib_cache_peer ( &ll_src );
|
520
|
502
|
ipoib_hdr->u.peer.src = src->key;
|
521
|
503
|
}
|
522
|
504
|
|