aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/cxgb3/iwch_provider.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-07-18 05:39:39 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-18 05:39:39 -0400
commit49997d75152b3d23c53b0fa730599f2f74c92c65 (patch)
tree46e93126170d02cfec9505172e545732c1b69656 /drivers/infiniband/hw/cxgb3/iwch_provider.c
parenta0c80b80e0fb48129e4e9d6a9ede914f9ff1850d (diff)
parent5b664cb235e97afbf34db9c4d77f08ebd725335e (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: Documentation/powerpc/booting-without-of.txt drivers/atm/Makefile drivers/net/fs_enet/fs_enet-main.c drivers/pci/pci-acpi.c net/8021q/vlan.c net/iucv/iucv.c
Diffstat (limited to 'drivers/infiniband/hw/cxgb3/iwch_provider.c')
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c203
1 files changed, 194 insertions, 9 deletions
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 8934178a23ee..b89640aa6e10 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -56,6 +56,7 @@
56#include "iwch_provider.h" 56#include "iwch_provider.h"
57#include "iwch_cm.h" 57#include "iwch_cm.h"
58#include "iwch_user.h" 58#include "iwch_user.h"
59#include "common.h"
59 60
60static int iwch_modify_port(struct ib_device *ibdev, 61static int iwch_modify_port(struct ib_device *ibdev,
61 u8 port, int port_modify_mask, 62 u8 port, int port_modify_mask,
@@ -747,6 +748,7 @@ static struct ib_mw *iwch_alloc_mw(struct ib_pd *pd)
747 mhp->attr.type = TPT_MW; 748 mhp->attr.type = TPT_MW;
748 mhp->attr.stag = stag; 749 mhp->attr.stag = stag;
749 mmid = (stag) >> 8; 750 mmid = (stag) >> 8;
751 mhp->ibmw.rkey = stag;
750 insert_handle(rhp, &rhp->mmidr, mhp, mmid); 752 insert_handle(rhp, &rhp->mmidr, mhp, mmid);
751 PDBG("%s mmid 0x%x mhp %p stag 0x%x\n", __func__, mmid, mhp, stag); 753 PDBG("%s mmid 0x%x mhp %p stag 0x%x\n", __func__, mmid, mhp, stag);
752 return &(mhp->ibmw); 754 return &(mhp->ibmw);
@@ -768,6 +770,68 @@ static int iwch_dealloc_mw(struct ib_mw *mw)
768 return 0; 770 return 0;
769} 771}
770 772
773static struct ib_mr *iwch_alloc_fast_reg_mr(struct ib_pd *pd, int pbl_depth)
774{
775 struct iwch_dev *rhp;
776 struct iwch_pd *php;
777 struct iwch_mr *mhp;
778 u32 mmid;
779 u32 stag = 0;
780 int ret;
781
782 php = to_iwch_pd(pd);
783 rhp = php->rhp;
784 mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
785 if (!mhp)
786 return ERR_PTR(-ENOMEM);
787
788 mhp->rhp = rhp;
789 ret = iwch_alloc_pbl(mhp, pbl_depth);
790 if (ret) {
791 kfree(mhp);
792 return ERR_PTR(ret);
793 }
794 mhp->attr.pbl_size = pbl_depth;
795 ret = cxio_allocate_stag(&rhp->rdev, &stag, php->pdid,
796 mhp->attr.pbl_size, mhp->attr.pbl_addr);
797 if (ret) {
798 iwch_free_pbl(mhp);
799 kfree(mhp);
800 return ERR_PTR(ret);
801 }
802 mhp->attr.pdid = php->pdid;
803 mhp->attr.type = TPT_NON_SHARED_MR;
804 mhp->attr.stag = stag;
805 mhp->attr.state = 1;
806 mmid = (stag) >> 8;
807 mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
808 insert_handle(rhp, &rhp->mmidr, mhp, mmid);
809 PDBG("%s mmid 0x%x mhp %p stag 0x%x\n", __func__, mmid, mhp, stag);
810 return &(mhp->ibmr);
811}
812
813static struct ib_fast_reg_page_list *iwch_alloc_fastreg_pbl(
814 struct ib_device *device,
815 int page_list_len)
816{
817 struct ib_fast_reg_page_list *page_list;
818
819 page_list = kmalloc(sizeof *page_list + page_list_len * sizeof(u64),
820 GFP_KERNEL);
821 if (!page_list)
822 return ERR_PTR(-ENOMEM);
823
824 page_list->page_list = (u64 *)(page_list + 1);
825 page_list->max_page_list_len = page_list_len;
826
827 return page_list;
828}
829
830static void iwch_free_fastreg_pbl(struct ib_fast_reg_page_list *page_list)
831{
832 kfree(page_list);
833}
834
771static int iwch_destroy_qp(struct ib_qp *ib_qp) 835static int iwch_destroy_qp(struct ib_qp *ib_qp)
772{ 836{
773 struct iwch_dev *rhp; 837 struct iwch_dev *rhp;
@@ -843,6 +907,15 @@ static struct ib_qp *iwch_create_qp(struct ib_pd *pd,
843 */ 907 */
844 sqsize = roundup_pow_of_two(attrs->cap.max_send_wr); 908 sqsize = roundup_pow_of_two(attrs->cap.max_send_wr);
845 wqsize = roundup_pow_of_two(rqsize + sqsize); 909 wqsize = roundup_pow_of_two(rqsize + sqsize);
910
911 /*
912 * Kernel users need more wq space for fastreg WRs which can take
913 * 2 WR fragments.
914 */
915 ucontext = pd->uobject ? to_iwch_ucontext(pd->uobject->context) : NULL;
916 if (!ucontext && wqsize < (rqsize + (2 * sqsize)))
917 wqsize = roundup_pow_of_two(rqsize +
918 roundup_pow_of_two(attrs->cap.max_send_wr * 2));
846 PDBG("%s wqsize %d sqsize %d rqsize %d\n", __func__, 919 PDBG("%s wqsize %d sqsize %d rqsize %d\n", __func__,
847 wqsize, sqsize, rqsize); 920 wqsize, sqsize, rqsize);
848 qhp = kzalloc(sizeof(*qhp), GFP_KERNEL); 921 qhp = kzalloc(sizeof(*qhp), GFP_KERNEL);
@@ -851,7 +924,6 @@ static struct ib_qp *iwch_create_qp(struct ib_pd *pd,
851 qhp->wq.size_log2 = ilog2(wqsize); 924 qhp->wq.size_log2 = ilog2(wqsize);
852 qhp->wq.rq_size_log2 = ilog2(rqsize); 925 qhp->wq.rq_size_log2 = ilog2(rqsize);
853 qhp->wq.sq_size_log2 = ilog2(sqsize); 926 qhp->wq.sq_size_log2 = ilog2(sqsize);
854 ucontext = pd->uobject ? to_iwch_ucontext(pd->uobject->context) : NULL;
855 if (cxio_create_qp(&rhp->rdev, !udata, &qhp->wq, 927 if (cxio_create_qp(&rhp->rdev, !udata, &qhp->wq,
856 ucontext ? &ucontext->uctx : &rhp->rdev.uctx)) { 928 ucontext ? &ucontext->uctx : &rhp->rdev.uctx)) {
857 kfree(qhp); 929 kfree(qhp);
@@ -935,10 +1007,10 @@ static struct ib_qp *iwch_create_qp(struct ib_pd *pd,
935 qhp->ibqp.qp_num = qhp->wq.qpid; 1007 qhp->ibqp.qp_num = qhp->wq.qpid;
936 init_timer(&(qhp->timer)); 1008 init_timer(&(qhp->timer));
937 PDBG("%s sq_num_entries %d, rq_num_entries %d " 1009 PDBG("%s sq_num_entries %d, rq_num_entries %d "
938 "qpid 0x%0x qhp %p dma_addr 0x%llx size %d\n", 1010 "qpid 0x%0x qhp %p dma_addr 0x%llx size %d rq_addr 0x%x\n",
939 __func__, qhp->attr.sq_num_entries, qhp->attr.rq_num_entries, 1011 __func__, qhp->attr.sq_num_entries, qhp->attr.rq_num_entries,
940 qhp->wq.qpid, qhp, (unsigned long long) qhp->wq.dma_addr, 1012 qhp->wq.qpid, qhp, (unsigned long long) qhp->wq.dma_addr,
941 1 << qhp->wq.size_log2); 1013 1 << qhp->wq.size_log2, qhp->wq.rq_addr);
942 return &qhp->ibqp; 1014 return &qhp->ibqp;
943} 1015}
944 1016
@@ -1023,6 +1095,29 @@ static int iwch_query_gid(struct ib_device *ibdev, u8 port,
1023 return 0; 1095 return 0;
1024} 1096}
1025 1097
1098static u64 fw_vers_string_to_u64(struct iwch_dev *iwch_dev)
1099{
1100 struct ethtool_drvinfo info;
1101 struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev;
1102 char *cp, *next;
1103 unsigned fw_maj, fw_min, fw_mic;
1104
1105 rtnl_lock();
1106 lldev->ethtool_ops->get_drvinfo(lldev, &info);
1107 rtnl_unlock();
1108
1109 next = info.fw_version + 1;
1110 cp = strsep(&next, ".");
1111 sscanf(cp, "%i", &fw_maj);
1112 cp = strsep(&next, ".");
1113 sscanf(cp, "%i", &fw_min);
1114 cp = strsep(&next, ".");
1115 sscanf(cp, "%i", &fw_mic);
1116
1117 return (((u64)fw_maj & 0xffff) << 32) | ((fw_min & 0xffff) << 16) |
1118 (fw_mic & 0xffff);
1119}
1120
1026static int iwch_query_device(struct ib_device *ibdev, 1121static int iwch_query_device(struct ib_device *ibdev,
1027 struct ib_device_attr *props) 1122 struct ib_device_attr *props)
1028{ 1123{
@@ -1033,7 +1128,10 @@ static int iwch_query_device(struct ib_device *ibdev,
1033 dev = to_iwch_dev(ibdev); 1128 dev = to_iwch_dev(ibdev);
1034 memset(props, 0, sizeof *props); 1129 memset(props, 0, sizeof *props);
1035 memcpy(&props->sys_image_guid, dev->rdev.t3cdev_p->lldev->dev_addr, 6); 1130 memcpy(&props->sys_image_guid, dev->rdev.t3cdev_p->lldev->dev_addr, 6);
1131 props->hw_ver = dev->rdev.t3cdev_p->type;
1132 props->fw_ver = fw_vers_string_to_u64(dev);
1036 props->device_cap_flags = dev->device_cap_flags; 1133 props->device_cap_flags = dev->device_cap_flags;
1134 props->page_size_cap = dev->attr.mem_pgsizes_bitmask;
1037 props->vendor_id = (u32)dev->rdev.rnic_info.pdev->vendor; 1135 props->vendor_id = (u32)dev->rdev.rnic_info.pdev->vendor;
1038 props->vendor_part_id = (u32)dev->rdev.rnic_info.pdev->device; 1136 props->vendor_part_id = (u32)dev->rdev.rnic_info.pdev->device;
1039 props->max_mr_size = dev->attr.max_mr_size; 1137 props->max_mr_size = dev->attr.max_mr_size;
@@ -1048,6 +1146,7 @@ static int iwch_query_device(struct ib_device *ibdev,
1048 props->max_mr = dev->attr.max_mem_regs; 1146 props->max_mr = dev->attr.max_mem_regs;
1049 props->max_pd = dev->attr.max_pds; 1147 props->max_pd = dev->attr.max_pds;
1050 props->local_ca_ack_delay = 0; 1148 props->local_ca_ack_delay = 0;
1149 props->max_fast_reg_page_list_len = T3_MAX_FASTREG_DEPTH;
1051 1150
1052 return 0; 1151 return 0;
1053} 1152}
@@ -1088,6 +1187,28 @@ static ssize_t show_rev(struct device *dev, struct device_attribute *attr,
1088 return sprintf(buf, "%d\n", iwch_dev->rdev.t3cdev_p->type); 1187 return sprintf(buf, "%d\n", iwch_dev->rdev.t3cdev_p->type);
1089} 1188}
1090 1189
1190static int fw_supports_fastreg(struct iwch_dev *iwch_dev)
1191{
1192 struct ethtool_drvinfo info;
1193 struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev;
1194 char *cp, *next;
1195 unsigned fw_maj, fw_min;
1196
1197 rtnl_lock();
1198 lldev->ethtool_ops->get_drvinfo(lldev, &info);
1199 rtnl_unlock();
1200
1201 next = info.fw_version+1;
1202 cp = strsep(&next, ".");
1203 sscanf(cp, "%i", &fw_maj);
1204 cp = strsep(&next, ".");
1205 sscanf(cp, "%i", &fw_min);
1206
1207 PDBG("%s maj %u min %u\n", __func__, fw_maj, fw_min);
1208
1209 return fw_maj > 6 || (fw_maj == 6 && fw_min > 0);
1210}
1211
1091static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, char *buf) 1212static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, char *buf)
1092{ 1213{
1093 struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev, 1214 struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev,
@@ -1096,7 +1217,9 @@ static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, ch
1096 struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; 1217 struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev;
1097 1218
1098 PDBG("%s dev 0x%p\n", __func__, dev); 1219 PDBG("%s dev 0x%p\n", __func__, dev);
1220 rtnl_lock();
1099 lldev->ethtool_ops->get_drvinfo(lldev, &info); 1221 lldev->ethtool_ops->get_drvinfo(lldev, &info);
1222 rtnl_unlock();
1100 return sprintf(buf, "%s\n", info.fw_version); 1223 return sprintf(buf, "%s\n", info.fw_version);
1101} 1224}
1102 1225
@@ -1109,7 +1232,9 @@ static ssize_t show_hca(struct device *dev, struct device_attribute *attr,
1109 struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; 1232 struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev;
1110 1233
1111 PDBG("%s dev 0x%p\n", __func__, dev); 1234 PDBG("%s dev 0x%p\n", __func__, dev);
1235 rtnl_lock();
1112 lldev->ethtool_ops->get_drvinfo(lldev, &info); 1236 lldev->ethtool_ops->get_drvinfo(lldev, &info);
1237 rtnl_unlock();
1113 return sprintf(buf, "%s\n", info.driver); 1238 return sprintf(buf, "%s\n", info.driver);
1114} 1239}
1115 1240
@@ -1123,6 +1248,61 @@ static ssize_t show_board(struct device *dev, struct device_attribute *attr,
1123 iwch_dev->rdev.rnic_info.pdev->device); 1248 iwch_dev->rdev.rnic_info.pdev->device);
1124} 1249}
1125 1250
1251static int iwch_get_mib(struct ib_device *ibdev,
1252 union rdma_protocol_stats *stats)
1253{
1254 struct iwch_dev *dev;
1255 struct tp_mib_stats m;
1256 int ret;
1257
1258 PDBG("%s ibdev %p\n", __func__, ibdev);
1259 dev = to_iwch_dev(ibdev);
1260 ret = dev->rdev.t3cdev_p->ctl(dev->rdev.t3cdev_p, RDMA_GET_MIB, &m);
1261 if (ret)
1262 return -ENOSYS;
1263
1264 memset(stats, 0, sizeof *stats);
1265 stats->iw.ipInReceives = ((u64) m.ipInReceive_hi << 32) +
1266 m.ipInReceive_lo;
1267 stats->iw.ipInHdrErrors = ((u64) m.ipInHdrErrors_hi << 32) +
1268 m.ipInHdrErrors_lo;
1269 stats->iw.ipInAddrErrors = ((u64) m.ipInAddrErrors_hi << 32) +
1270 m.ipInAddrErrors_lo;
1271 stats->iw.ipInUnknownProtos = ((u64) m.ipInUnknownProtos_hi << 32) +
1272 m.ipInUnknownProtos_lo;
1273 stats->iw.ipInDiscards = ((u64) m.ipInDiscards_hi << 32) +
1274 m.ipInDiscards_lo;
1275 stats->iw.ipInDelivers = ((u64) m.ipInDelivers_hi << 32) +
1276 m.ipInDelivers_lo;
1277 stats->iw.ipOutRequests = ((u64) m.ipOutRequests_hi << 32) +
1278 m.ipOutRequests_lo;
1279 stats->iw.ipOutDiscards = ((u64) m.ipOutDiscards_hi << 32) +
1280 m.ipOutDiscards_lo;
1281 stats->iw.ipOutNoRoutes = ((u64) m.ipOutNoRoutes_hi << 32) +
1282 m.ipOutNoRoutes_lo;
1283 stats->iw.ipReasmTimeout = (u64) m.ipReasmTimeout;
1284 stats->iw.ipReasmReqds = (u64) m.ipReasmReqds;
1285 stats->iw.ipReasmOKs = (u64) m.ipReasmOKs;
1286 stats->iw.ipReasmFails = (u64) m.ipReasmFails;
1287 stats->iw.tcpActiveOpens = (u64) m.tcpActiveOpens;
1288 stats->iw.tcpPassiveOpens = (u64) m.tcpPassiveOpens;
1289 stats->iw.tcpAttemptFails = (u64) m.tcpAttemptFails;
1290 stats->iw.tcpEstabResets = (u64) m.tcpEstabResets;
1291 stats->iw.tcpOutRsts = (u64) m.tcpOutRsts;
1292 stats->iw.tcpCurrEstab = (u64) m.tcpCurrEstab;
1293 stats->iw.tcpInSegs = ((u64) m.tcpInSegs_hi << 32) +
1294 m.tcpInSegs_lo;
1295 stats->iw.tcpOutSegs = ((u64) m.tcpOutSegs_hi << 32) +
1296 m.tcpOutSegs_lo;
1297 stats->iw.tcpRetransSegs = ((u64) m.tcpRetransSeg_hi << 32) +
1298 m.tcpRetransSeg_lo;
1299 stats->iw.tcpInErrs = ((u64) m.tcpInErrs_hi << 32) +
1300 m.tcpInErrs_lo;
1301 stats->iw.tcpRtoMin = (u64) m.tcpRtoMin;
1302 stats->iw.tcpRtoMax = (u64) m.tcpRtoMax;
1303 return 0;
1304}
1305
1126static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); 1306static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
1127static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); 1307static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
1128static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); 1308static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
@@ -1132,7 +1312,7 @@ static struct device_attribute *iwch_class_attributes[] = {
1132 &dev_attr_hw_rev, 1312 &dev_attr_hw_rev,
1133 &dev_attr_fw_ver, 1313 &dev_attr_fw_ver,
1134 &dev_attr_hca_type, 1314 &dev_attr_hca_type,
1135 &dev_attr_board_id 1315 &dev_attr_board_id,
1136}; 1316};
1137 1317
1138int iwch_register_device(struct iwch_dev *dev) 1318int iwch_register_device(struct iwch_dev *dev)
@@ -1145,8 +1325,12 @@ int iwch_register_device(struct iwch_dev *dev)
1145 memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid)); 1325 memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid));
1146 memcpy(&dev->ibdev.node_guid, dev->rdev.t3cdev_p->lldev->dev_addr, 6); 1326 memcpy(&dev->ibdev.node_guid, dev->rdev.t3cdev_p->lldev->dev_addr, 6);
1147 dev->ibdev.owner = THIS_MODULE; 1327 dev->ibdev.owner = THIS_MODULE;
1148 dev->device_cap_flags = 1328 dev->device_cap_flags = IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_WINDOW;
1149 (IB_DEVICE_ZERO_STAG | IB_DEVICE_MEM_WINDOW); 1329
1330 /* cxgb3 supports STag 0. */
1331 dev->ibdev.local_dma_lkey = 0;
1332 if (fw_supports_fastreg(dev))
1333 dev->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
1150 1334
1151 dev->ibdev.uverbs_cmd_mask = 1335 dev->ibdev.uverbs_cmd_mask =
1152 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | 1336 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
@@ -1198,15 +1382,16 @@ int iwch_register_device(struct iwch_dev *dev)
1198 dev->ibdev.alloc_mw = iwch_alloc_mw; 1382 dev->ibdev.alloc_mw = iwch_alloc_mw;
1199 dev->ibdev.bind_mw = iwch_bind_mw; 1383 dev->ibdev.bind_mw = iwch_bind_mw;
1200 dev->ibdev.dealloc_mw = iwch_dealloc_mw; 1384 dev->ibdev.dealloc_mw = iwch_dealloc_mw;
1201 1385 dev->ibdev.alloc_fast_reg_mr = iwch_alloc_fast_reg_mr;
1386 dev->ibdev.alloc_fast_reg_page_list = iwch_alloc_fastreg_pbl;
1387 dev->ibdev.free_fast_reg_page_list = iwch_free_fastreg_pbl;
1202 dev->ibdev.attach_mcast = iwch_multicast_attach; 1388 dev->ibdev.attach_mcast = iwch_multicast_attach;
1203 dev->ibdev.detach_mcast = iwch_multicast_detach; 1389 dev->ibdev.detach_mcast = iwch_multicast_detach;
1204 dev->ibdev.process_mad = iwch_process_mad; 1390 dev->ibdev.process_mad = iwch_process_mad;
1205
1206 dev->ibdev.req_notify_cq = iwch_arm_cq; 1391 dev->ibdev.req_notify_cq = iwch_arm_cq;
1207 dev->ibdev.post_send = iwch_post_send; 1392 dev->ibdev.post_send = iwch_post_send;
1208 dev->ibdev.post_recv = iwch_post_receive; 1393 dev->ibdev.post_recv = iwch_post_receive;
1209 1394 dev->ibdev.get_protocol_stats = iwch_get_mib;
1210 1395
1211 dev->ibdev.iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL); 1396 dev->ibdev.iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL);
1212 if (!dev->ibdev.iwcm) 1397 if (!dev->ibdev.iwcm)