mthca_av.c revision b046a04e162dc7f468700a0817acda0321b2b3ae
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2004 Topspin Communications. All rights reserved. 3cd4e8fb49d2326364971a56f5a4b664a976f3712Tom Duffy * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software is available to you under a choice of one of two 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * licenses. You may choose to be licensed under the terms of the GNU 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * General Public License (GPL) Version 2, available from the file 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * COPYING in the main directory of this source tree, or the 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OpenIB.org BSD license below: 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Redistribution and use in source and binary forms, with or 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * without modification, are permitted provided that the following 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * conditions are met: 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Redistributions of source code must retain the above 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * copyright notice, this list of conditions and the following 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * disclaimer. 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Redistributions in binary form must reproduce the above 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * copyright notice, this list of conditions and the following 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * disclaimer in the documentation and/or other materials 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * provided with the distribution. 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SOFTWARE. 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * $Id: mthca_av.c 1349 2004-12-16 21:09:43Z roland $ 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 374e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/string.h> 384e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/slab.h> 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40a4d61e84804f3b14cc35c5e2af768a07c0f64ef6Roland Dreier#include <rdma/ib_verbs.h> 41a4d61e84804f3b14cc35c5e2af768a07c0f64ef6Roland Dreier#include <rdma/ib_cache.h> 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "mthca_dev.h" 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgensteinenum { 46bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein MTHCA_RATE_TAVOR_FULL = 0, 47bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein MTHCA_RATE_TAVOR_1X = 1, 48bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein MTHCA_RATE_TAVOR_4X = 2, 49bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein MTHCA_RATE_TAVOR_1X_DDR = 3 50bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein}; 51bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 52bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgensteinenum { 53bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein MTHCA_RATE_MEMFREE_FULL = 0, 54bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein MTHCA_RATE_MEMFREE_QUARTER = 1, 55bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein MTHCA_RATE_MEMFREE_EIGHTH = 2, 56bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein MTHCA_RATE_MEMFREE_HALF = 3 57bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein}; 58bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct mthca_av { 6097f52eb438be7caebe026421545619d8a0c1398aSean Hefty __be32 port_pd; 6197f52eb438be7caebe026421545619d8a0c1398aSean Hefty u8 reserved1; 6297f52eb438be7caebe026421545619d8a0c1398aSean Hefty u8 g_slid; 6397f52eb438be7caebe026421545619d8a0c1398aSean Hefty __be16 dlid; 6497f52eb438be7caebe026421545619d8a0c1398aSean Hefty u8 reserved2; 6597f52eb438be7caebe026421545619d8a0c1398aSean Hefty u8 gid_index; 6697f52eb438be7caebe026421545619d8a0c1398aSean Hefty u8 msg_sr; 6797f52eb438be7caebe026421545619d8a0c1398aSean Hefty u8 hop_limit; 6897f52eb438be7caebe026421545619d8a0c1398aSean Hefty __be32 sl_tclass_flowlabel; 6997f52eb438be7caebe026421545619d8a0c1398aSean Hefty __be32 dgid[4]; 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 72bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgensteinstatic enum ib_rate memfree_rate_to_ib(u8 mthca_rate, u8 port_rate) 73bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein{ 74bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein switch (mthca_rate) { 75bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case MTHCA_RATE_MEMFREE_EIGHTH: 76bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein return mult_to_ib_rate(port_rate >> 3); 77bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case MTHCA_RATE_MEMFREE_QUARTER: 78bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein return mult_to_ib_rate(port_rate >> 2); 79bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case MTHCA_RATE_MEMFREE_HALF: 80bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein return mult_to_ib_rate(port_rate >> 1); 81bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case MTHCA_RATE_MEMFREE_FULL: 82bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein default: 83bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein return mult_to_ib_rate(port_rate); 84bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein } 85bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein} 86bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 87bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgensteinstatic enum ib_rate tavor_rate_to_ib(u8 mthca_rate, u8 port_rate) 88bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein{ 89bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein switch (mthca_rate) { 90bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case MTHCA_RATE_TAVOR_1X: return IB_RATE_2_5_GBPS; 91bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case MTHCA_RATE_TAVOR_1X_DDR: return IB_RATE_5_GBPS; 92bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case MTHCA_RATE_TAVOR_4X: return IB_RATE_10_GBPS; 93b046a04e162dc7f468700a0817acda0321b2b3aeJack Morgenstein default: return mult_to_ib_rate(port_rate); 94bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein } 95bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein} 96bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 97bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgensteinenum ib_rate mthca_rate_to_ib(struct mthca_dev *dev, u8 mthca_rate, u8 port) 98bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein{ 99bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein if (mthca_is_memfree(dev)) { 100bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein /* Handle old Arbel FW */ 101bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein if (dev->limits.stat_rate_support == 0x3 && mthca_rate) 102bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein return IB_RATE_2_5_GBPS; 103bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 104bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein return memfree_rate_to_ib(mthca_rate, dev->rate[port - 1]); 105bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein } else 106bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein return tavor_rate_to_ib(mthca_rate, dev->rate[port - 1]); 107bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein} 108bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 109bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgensteinstatic u8 ib_rate_to_memfree(u8 req_rate, u8 cur_rate) 110bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein{ 111bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein if (cur_rate <= req_rate) 112bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein return 0; 113bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 114bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein /* 115bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein * Inter-packet delay (IPD) to get from rate X down to a rate 116bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein * no more than Y is (X - 1) / Y. 117bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein */ 118bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein switch ((cur_rate - 1) / req_rate) { 119bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case 0: return MTHCA_RATE_MEMFREE_FULL; 120bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case 1: return MTHCA_RATE_MEMFREE_HALF; 121bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case 2: /* fall through */ 122bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case 3: return MTHCA_RATE_MEMFREE_QUARTER; 123bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein default: return MTHCA_RATE_MEMFREE_EIGHTH; 124bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein } 125bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein} 126bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 127bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgensteinstatic u8 ib_rate_to_tavor(u8 static_rate) 128bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein{ 129bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein switch (static_rate) { 130bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case IB_RATE_2_5_GBPS: return MTHCA_RATE_TAVOR_1X; 131bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case IB_RATE_5_GBPS: return MTHCA_RATE_TAVOR_1X_DDR; 132bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein case IB_RATE_10_GBPS: return MTHCA_RATE_TAVOR_4X; 133bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein default: return MTHCA_RATE_TAVOR_FULL; 134bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein } 135bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein} 136bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 137bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgensteinu8 mthca_get_rate(struct mthca_dev *dev, int static_rate, u8 port) 138bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein{ 139bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein u8 rate; 140bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 141bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein if (!static_rate || ib_rate_to_mult(static_rate) >= dev->rate[port - 1]) 142bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein return 0; 143bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 144bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein if (mthca_is_memfree(dev)) 145bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein rate = ib_rate_to_memfree(ib_rate_to_mult(static_rate), 146bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein dev->rate[port - 1]); 147bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein else 148bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein rate = ib_rate_to_tavor(static_rate); 149bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 150bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein if (!(dev->limits.stat_rate_support & (1 << rate))) 151bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein rate = 1; 152bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 153bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein return rate; 154bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein} 155bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint mthca_create_ah(struct mthca_dev *dev, 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mthca_pd *pd, 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ib_ah_attr *ah_attr, 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mthca_ah *ah) 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 index = -1; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mthca_av *av = NULL; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ah->type = MTHCA_AH_PCI_POOL; 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 166d10ddbf6d7f6699c386d1f41bf542189de32b6beRoland Dreier if (mthca_is_memfree(dev)) { 1678df8a34de60f8e51c87e5c145679f1a896133199Roland Dreier ah->av = kmalloc(sizeof *ah->av, GFP_ATOMIC); 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ah->av) 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ah->type = MTHCA_AH_KMALLOC; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av = ah->av; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (!atomic_read(&pd->sqp_count) && 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds !(dev->mthca_flags & MTHCA_FLAG_DDR_HIDDEN)) { 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds index = mthca_alloc(&dev->av_table.alloc); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* fall back to allocate in host memory */ 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (index == -1) 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto on_hca_fail; 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1818df8a34de60f8e51c87e5c145679f1a896133199Roland Dreier av = kmalloc(sizeof *av, GFP_ATOMIC); 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!av) 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto on_hca_fail; 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ah->type = MTHCA_AH_ON_HCA; 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ah->avdma = dev->av_table.ddr_av_base + 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds index * MTHCA_AV_SIZE; 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldson_hca_fail: 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ah->type == MTHCA_AH_PCI_POOL) { 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ah->av = pci_pool_alloc(dev->av_table.pool, 1938df8a34de60f8e51c87e5c145679f1a896133199Roland Dreier SLAB_ATOMIC, &ah->avdma); 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ah->av) 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av = ah->av; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ah->key = pd->ntmr.ibmr.lkey; 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(av, 0, MTHCA_AV_SIZE); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av->port_pd = cpu_to_be32(pd->pd_num | (ah_attr->port_num << 24)); 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av->g_slid = ah_attr->src_path_bits; 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av->dlid = cpu_to_be16(ah_attr->dlid); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av->msg_sr = (3 << 4) | /* 2K message */ 208bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein mthca_get_rate(dev, ah_attr->static_rate, ah_attr->port_num); 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av->sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28); 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ah_attr->ah_flags & IB_AH_GRH) { 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av->g_slid |= 0x80; 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av->gid_index = (ah_attr->port_num - 1) * dev->limits.gid_table_len + 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ah_attr->grh.sgid_index; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av->hop_limit = ah_attr->grh.hop_limit; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av->sl_tclass_flowlabel |= 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_to_be32((ah_attr->grh.traffic_class << 20) | 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ah_attr->grh.flow_label); 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(av->dgid, ah_attr->grh.dgid.raw, 16); 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Arbel workaround -- low byte of GID must be 2 */ 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av->dgid[3] = cpu_to_be32(2); 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (0) { 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int j; 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mthca_dbg(dev, "Created UDAV at %p/%08lx:\n", 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av, (unsigned long) ah->avdma); 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (j = 0; j < 8; ++j) 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_DEBUG " [%2x] %08x\n", 23197f52eb438be7caebe026421545619d8a0c1398aSean Hefty j * 4, be32_to_cpu(((__be32 *) av)[j])); 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ah->type == MTHCA_AH_ON_HCA) { 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy_toio(dev->av_table.av_map + index * MTHCA_AV_SIZE, 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av, MTHCA_AV_SIZE); 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(av); 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah) 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (ah->type) { 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MTHCA_AH_ON_HCA: 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mthca_free(&dev->av_table.alloc, 2482fa5e2ebbe2d81f741ba7bed9e07dc38cc734625Roland Dreier (ah->avdma - dev->av_table.ddr_av_base) / 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MTHCA_AV_SIZE); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MTHCA_AH_PCI_POOL: 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_pool_free(dev->av_table.pool, ah->av, ah->avdma); 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MTHCA_AH_KMALLOC: 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(ah->av); 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2649eacee2ac624bfa9740d49355dbe6ee88d0cba0aMichael S. Tsirkinint mthca_ah_grh_present(struct mthca_ah *ah) 2659eacee2ac624bfa9740d49355dbe6ee88d0cba0aMichael S. Tsirkin{ 2669eacee2ac624bfa9740d49355dbe6ee88d0cba0aMichael S. Tsirkin return !!(ah->av->g_slid & 0x80); 2679eacee2ac624bfa9740d49355dbe6ee88d0cba0aMichael S. Tsirkin} 2689eacee2ac624bfa9740d49355dbe6ee88d0cba0aMichael S. Tsirkin 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah, 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ib_ud_header *header) 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ah->type == MTHCA_AH_ON_HCA) 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header->lrh.service_level = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28; 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header->lrh.destination_lid = ah->av->dlid; 27797f52eb438be7caebe026421545619d8a0c1398aSean Hefty header->lrh.source_lid = cpu_to_be16(ah->av->g_slid & 0x7f); 2789eacee2ac624bfa9740d49355dbe6ee88d0cba0aMichael S. Tsirkin if (mthca_ah_grh_present(ah)) { 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header->grh.traffic_class = 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 20) & 0xff; 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header->grh.flow_label = 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ah->av->sl_tclass_flowlabel & cpu_to_be32(0xfffff); 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ib_get_cached_gid(&dev->ib_dev, 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds be32_to_cpu(ah->av->port_pd) >> 24, 285f9e61929e5e1dacc2afefbde6abc3e6571ca2887Michael S. Tsirkin ah->av->gid_index % dev->limits.gid_table_len, 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &header->grh.source_gid); 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(header->grh.destination_gid.raw, 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ah->av->dgid, 16); 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2941d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgensteinint mthca_ah_query(struct ib_ah *ibah, struct ib_ah_attr *attr) 2951d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein{ 2961d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein struct mthca_ah *ah = to_mah(ibah); 2971d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein struct mthca_dev *dev = to_mdev(ibah->device); 2981d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein 2991d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein /* Only implement for MAD and memfree ah for now. */ 3001d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein if (ah->type == MTHCA_AH_ON_HCA) 3011d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein return -ENOSYS; 3021d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein 3031d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein memset(attr, 0, sizeof *attr); 3041d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein attr->dlid = be16_to_cpu(ah->av->dlid); 3051d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein attr->sl = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28; 3061d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein attr->port_num = be32_to_cpu(ah->av->port_pd) >> 24; 3072290d2c9f51d7ee2f45adee79b4d9e080ca15d36Jack Morgenstein attr->static_rate = mthca_rate_to_ib(dev, ah->av->msg_sr & 0x7, 3082290d2c9f51d7ee2f45adee79b4d9e080ca15d36Jack Morgenstein attr->port_num); 3092290d2c9f51d7ee2f45adee79b4d9e080ca15d36Jack Morgenstein attr->src_path_bits = ah->av->g_slid & 0x7F; 3101d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein attr->ah_flags = mthca_ah_grh_present(ah) ? IB_AH_GRH : 0; 3111d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein 3121d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein if (attr->ah_flags) { 3131d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein attr->grh.traffic_class = 3141d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 20; 3151d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein attr->grh.flow_label = 3161d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein be32_to_cpu(ah->av->sl_tclass_flowlabel) & 0xfffff; 3171d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein attr->grh.hop_limit = ah->av->hop_limit; 3181d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein attr->grh.sgid_index = ah->av->gid_index & 3191d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein (dev->limits.gid_table_len - 1); 3201d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein memcpy(attr->grh.dgid.raw, ah->av->dgid, 16); 3211d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein } 3221d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein 3231d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein return 0; 3241d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein} 3251d89b1ae6c203bc68a3f424be144abcdf62773c9Jack Morgenstein 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __devinit mthca_init_av_table(struct mthca_dev *dev) 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 330d10ddbf6d7f6699c386d1f41bf542189de32b6beRoland Dreier if (mthca_is_memfree(dev)) 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = mthca_alloc_init(&dev->av_table.alloc, 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->av_table.num_ddr_avs, 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->av_table.num_ddr_avs - 1, 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0); 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err) 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->av_table.pool = pci_pool_create("mthca_av", dev->pdev, 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MTHCA_AV_SIZE, 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MTHCA_AV_SIZE, 0); 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev->av_table.pool) 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_free_alloc; 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(dev->mthca_flags & MTHCA_FLAG_DDR_HIDDEN)) { 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->av_table.av_map = ioremap(pci_resource_start(dev->pdev, 4) + 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->av_table.ddr_av_base - 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->ddr_start, 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->av_table.num_ddr_avs * 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MTHCA_AV_SIZE); 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev->av_table.av_map) 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_free_pool; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->av_table.av_map = NULL; 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out_free_pool: 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_pool_destroy(dev->av_table.pool); 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out_free_alloc: 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mthca_alloc_cleanup(&dev->av_table.alloc); 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 367e1f7868c80947d40ef8e1fd37323d939a9bf311cRoland Dreiervoid mthca_cleanup_av_table(struct mthca_dev *dev) 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 369d10ddbf6d7f6699c386d1f41bf542189de32b6beRoland Dreier if (mthca_is_memfree(dev)) 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->av_table.av_map) 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap(dev->av_table.av_map); 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_pool_destroy(dev->av_table.pool); 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mthca_alloc_cleanup(&dev->av_table.alloc); 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 377