diff options
author | Parav Pandit <parav.pandit@emulex.com> | 2012-03-26 10:27:13 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2012-05-08 14:17:47 -0400 |
commit | 045508a8a36f9a82b63d1f6362bd323085638588 (patch) | |
tree | 3673bf4fb8bb060beb67b05a3fec9941364d20e4 | |
parent | 6a4ab669ad0b0eadb042383ef7677a84a68a0e0e (diff) |
be2net: Add functionality to support RoCE driver
- Increase MSI-X vectors by 5 for RoCE traffic.
- Add macro to check roce support on a device.
- Add device-specific doorbell and MSI-X vector fields shared with NIC
functionality.
- Provide RoCE driver registration and deregistration functions.
- Add support functions which will be invoked on adapter add/remove
and port up/down events.
- Traverse through the list of adapters to invoke callback functions.
Signed-off-by: Parav Pandit <parav.pandit@emulex.com>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r-- | drivers/net/ethernet/emulex/benet/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be.h | 38 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_hw.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 88 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_roce.c | 182 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_roce.h | 75 |
7 files changed, 375 insertions, 15 deletions
diff --git a/drivers/net/ethernet/emulex/benet/Makefile b/drivers/net/ethernet/emulex/benet/Makefile index a60cd8051135..1a91b276940d 100644 --- a/drivers/net/ethernet/emulex/benet/Makefile +++ b/drivers/net/ethernet/emulex/benet/Makefile | |||
@@ -4,4 +4,4 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_BE2NET) += be2net.o | 5 | obj-$(CONFIG_BE2NET) += be2net.o |
6 | 6 | ||
7 | be2net-y := be_main.o be_cmds.o be_ethtool.o | 7 | be2net-y := be_main.o be_cmds.o be_ethtool.o be_roce.o |
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 9576ac002c23..7bb2e97af898 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/u64_stats_sync.h> | 32 | #include <linux/u64_stats_sync.h> |
33 | 33 | ||
34 | #include "be_hw.h" | 34 | #include "be_hw.h" |
35 | #include "be_roce.h" | ||
35 | 36 | ||
36 | #define DRV_VER "4.2.116u" | 37 | #define DRV_VER "4.2.116u" |
37 | #define DRV_NAME "be2net" | 38 | #define DRV_NAME "be2net" |
@@ -102,7 +103,8 @@ static inline char *nic_name(struct pci_dev *pdev) | |||
102 | #define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */ | 103 | #define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */ |
103 | 104 | ||
104 | #define MAX_TX_QS 8 | 105 | #define MAX_TX_QS 8 |
105 | #define MAX_MSIX_VECTORS MAX_RSS_QS | 106 | #define MAX_ROCE_EQS 5 |
107 | #define MAX_MSIX_VECTORS (MAX_RSS_QS + MAX_ROCE_EQS) /* RSS qs + RoCE */ | ||
106 | #define BE_TX_BUDGET 256 | 108 | #define BE_TX_BUDGET 256 |
107 | #define BE_NAPI_WEIGHT 64 | 109 | #define BE_NAPI_WEIGHT 64 |
108 | #define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ | 110 | #define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ |
@@ -382,6 +384,17 @@ struct be_adapter { | |||
382 | u8 transceiver; | 384 | u8 transceiver; |
383 | u8 autoneg; | 385 | u8 autoneg; |
384 | u8 generation; /* BladeEngine ASIC generation */ | 386 | u8 generation; /* BladeEngine ASIC generation */ |
387 | u32 if_type; | ||
388 | struct { | ||
389 | u8 __iomem *base; /* Door Bell */ | ||
390 | u32 size; | ||
391 | u32 total_size; | ||
392 | u64 io_addr; | ||
393 | } roce_db; | ||
394 | u32 num_msix_roce_vec; | ||
395 | struct ocrdma_dev *ocrdma_dev; | ||
396 | struct list_head entry; | ||
397 | |||
385 | u32 flash_status; | 398 | u32 flash_status; |
386 | struct completion flash_compl; | 399 | struct completion flash_compl; |
387 | 400 | ||
@@ -413,6 +426,10 @@ struct be_adapter { | |||
413 | #define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \ | 426 | #define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \ |
414 | (adapter->pdev->device == OC_DEVICE_ID4)) | 427 | (adapter->pdev->device == OC_DEVICE_ID4)) |
415 | 428 | ||
429 | #define be_roce_supported(adapter) ((adapter->if_type == SLI_INTF_TYPE_3 || \ | ||
430 | adapter->sli_family == SKYHAWK_SLI_FAMILY) && \ | ||
431 | (adapter->function_mode & RDMA_ENABLED)) | ||
432 | |||
416 | extern const struct ethtool_ops be_ethtool_ops; | 433 | extern const struct ethtool_ops be_ethtool_ops; |
417 | 434 | ||
418 | #define msix_enabled(adapter) (adapter->num_msix_vec > 0) | 435 | #define msix_enabled(adapter) (adapter->num_msix_vec > 0) |
@@ -577,10 +594,29 @@ static inline bool be_is_wol_excluded(struct be_adapter *adapter) | |||
577 | } | 594 | } |
578 | } | 595 | } |
579 | 596 | ||
597 | static inline bool be_type_2_3(struct be_adapter *adapter) | ||
598 | { | ||
599 | return (adapter->if_type == SLI_INTF_TYPE_2 || | ||
600 | adapter->if_type == SLI_INTF_TYPE_3) ? true : false; | ||
601 | } | ||
602 | |||
580 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, | 603 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, |
581 | u16 num_popped); | 604 | u16 num_popped); |
582 | extern void be_link_status_update(struct be_adapter *adapter, u8 link_status); | 605 | extern void be_link_status_update(struct be_adapter *adapter, u8 link_status); |
583 | extern void be_parse_stats(struct be_adapter *adapter); | 606 | extern void be_parse_stats(struct be_adapter *adapter); |
584 | extern int be_load_fw(struct be_adapter *adapter, u8 *func); | 607 | extern int be_load_fw(struct be_adapter *adapter, u8 *func); |
585 | extern bool be_is_wol_supported(struct be_adapter *adapter); | 608 | extern bool be_is_wol_supported(struct be_adapter *adapter); |
609 | |||
610 | /* | ||
611 | * internal function to initialize-cleanup roce device. | ||
612 | */ | ||
613 | extern void be_roce_dev_add(struct be_adapter *); | ||
614 | extern void be_roce_dev_remove(struct be_adapter *); | ||
615 | |||
616 | /* | ||
617 | * internal function to open-close roce device during ifup-ifdown. | ||
618 | */ | ||
619 | extern void be_roce_dev_open(struct be_adapter *); | ||
620 | extern void be_roce_dev_close(struct be_adapter *); | ||
621 | |||
586 | #endif /* BE_H */ | 622 | #endif /* BE_H */ |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index d5b680c56af0..54eabd8ff397 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h | |||
@@ -1056,6 +1056,7 @@ struct be_cmd_resp_modify_eq_delay { | |||
1056 | /* The HW can come up in either of the following multi-channel modes | 1056 | /* The HW can come up in either of the following multi-channel modes |
1057 | * based on the skew/IPL. | 1057 | * based on the skew/IPL. |
1058 | */ | 1058 | */ |
1059 | #define RDMA_ENABLED 0x4 | ||
1059 | #define FLEX10_MODE 0x400 | 1060 | #define FLEX10_MODE 0x400 |
1060 | #define VNIC_MODE 0x20000 | 1061 | #define VNIC_MODE 0x20000 |
1061 | #define UMC_ENABLED 0x1000000 | 1062 | #define UMC_ENABLED 0x1000000 |
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h index f2c89e3ccabd..23a345486564 100644 --- a/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/drivers/net/ethernet/emulex/benet/be_hw.h | |||
@@ -98,11 +98,13 @@ | |||
98 | #define SLI_INTF_REV_SHIFT 4 | 98 | #define SLI_INTF_REV_SHIFT 4 |
99 | #define SLI_INTF_FT_MASK 0x00000001 | 99 | #define SLI_INTF_FT_MASK 0x00000001 |
100 | 100 | ||
101 | #define SLI_INTF_TYPE_2 2 | ||
102 | #define SLI_INTF_TYPE_3 3 | ||
101 | 103 | ||
102 | /* SLI family */ | 104 | /* SLI family */ |
103 | #define BE_SLI_FAMILY 0x0 | 105 | #define BE_SLI_FAMILY 0x0 |
104 | #define LANCER_A0_SLI_FAMILY 0xA | 106 | #define LANCER_A0_SLI_FAMILY 0xA |
105 | 107 | #define SKYHAWK_SLI_FAMILY 0x2 | |
106 | 108 | ||
107 | /********* ISR0 Register offset **********/ | 109 | /********* ISR0 Register offset **********/ |
108 | #define CEV_ISR0_OFFSET 0xC18 | 110 | #define CEV_ISR0_OFFSET 0xC18 |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 528a886bc2cd..fcc15e755d5c 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -2103,10 +2103,17 @@ static uint be_num_rss_want(struct be_adapter *adapter) | |||
2103 | static void be_msix_enable(struct be_adapter *adapter) | 2103 | static void be_msix_enable(struct be_adapter *adapter) |
2104 | { | 2104 | { |
2105 | #define BE_MIN_MSIX_VECTORS 1 | 2105 | #define BE_MIN_MSIX_VECTORS 1 |
2106 | int i, status, num_vec; | 2106 | int i, status, num_vec, num_roce_vec = 0; |
2107 | 2107 | ||
2108 | /* If RSS queues are not used, need a vec for default RX Q */ | 2108 | /* If RSS queues are not used, need a vec for default RX Q */ |
2109 | num_vec = min(be_num_rss_want(adapter), num_online_cpus()); | 2109 | num_vec = min(be_num_rss_want(adapter), num_online_cpus()); |
2110 | if (be_roce_supported(adapter)) { | ||
2111 | num_roce_vec = min_t(u32, MAX_ROCE_MSIX_VECTORS, | ||
2112 | (num_online_cpus() + 1)); | ||
2113 | num_roce_vec = min(num_roce_vec, MAX_ROCE_EQS); | ||
2114 | num_vec += num_roce_vec; | ||
2115 | num_vec = min(num_vec, MAX_MSIX_VECTORS); | ||
2116 | } | ||
2110 | num_vec = max(num_vec, BE_MIN_MSIX_VECTORS); | 2117 | num_vec = max(num_vec, BE_MIN_MSIX_VECTORS); |
2111 | 2118 | ||
2112 | for (i = 0; i < num_vec; i++) | 2119 | for (i = 0; i < num_vec; i++) |
@@ -2123,7 +2130,17 @@ static void be_msix_enable(struct be_adapter *adapter) | |||
2123 | } | 2130 | } |
2124 | return; | 2131 | return; |
2125 | done: | 2132 | done: |
2126 | adapter->num_msix_vec = num_vec; | 2133 | if (be_roce_supported(adapter)) { |
2134 | if (num_vec > num_roce_vec) { | ||
2135 | adapter->num_msix_vec = num_vec - num_roce_vec; | ||
2136 | adapter->num_msix_roce_vec = | ||
2137 | num_vec - adapter->num_msix_vec; | ||
2138 | } else { | ||
2139 | adapter->num_msix_vec = num_vec; | ||
2140 | adapter->num_msix_roce_vec = 0; | ||
2141 | } | ||
2142 | } else | ||
2143 | adapter->num_msix_vec = num_vec; | ||
2127 | return; | 2144 | return; |
2128 | } | 2145 | } |
2129 | 2146 | ||
@@ -2282,6 +2299,8 @@ static int be_close(struct net_device *netdev) | |||
2282 | struct be_eq_obj *eqo; | 2299 | struct be_eq_obj *eqo; |
2283 | int i; | 2300 | int i; |
2284 | 2301 | ||
2302 | be_roce_dev_close(adapter); | ||
2303 | |||
2285 | be_async_mcc_disable(adapter); | 2304 | be_async_mcc_disable(adapter); |
2286 | 2305 | ||
2287 | if (!lancer_chip(adapter)) | 2306 | if (!lancer_chip(adapter)) |
@@ -2390,6 +2409,7 @@ static int be_open(struct net_device *netdev) | |||
2390 | if (!status) | 2409 | if (!status) |
2391 | be_link_status_update(adapter, link_status); | 2410 | be_link_status_update(adapter, link_status); |
2392 | 2411 | ||
2412 | be_roce_dev_open(adapter); | ||
2393 | return 0; | 2413 | return 0; |
2394 | err: | 2414 | err: |
2395 | be_close(adapter->netdev); | 2415 | be_close(adapter->netdev); |
@@ -3122,6 +3142,24 @@ static void be_unmap_pci_bars(struct be_adapter *adapter) | |||
3122 | iounmap(adapter->csr); | 3142 | iounmap(adapter->csr); |
3123 | if (adapter->db) | 3143 | if (adapter->db) |
3124 | iounmap(adapter->db); | 3144 | iounmap(adapter->db); |
3145 | if (adapter->roce_db.base) | ||
3146 | pci_iounmap(adapter->pdev, adapter->roce_db.base); | ||
3147 | } | ||
3148 | |||
3149 | static int lancer_roce_map_pci_bars(struct be_adapter *adapter) | ||
3150 | { | ||
3151 | struct pci_dev *pdev = adapter->pdev; | ||
3152 | u8 __iomem *addr; | ||
3153 | |||
3154 | addr = pci_iomap(pdev, 2, 0); | ||
3155 | if (addr == NULL) | ||
3156 | return -ENOMEM; | ||
3157 | |||
3158 | adapter->roce_db.base = addr; | ||
3159 | adapter->roce_db.io_addr = pci_resource_start(pdev, 2); | ||
3160 | adapter->roce_db.size = 8192; | ||
3161 | adapter->roce_db.total_size = pci_resource_len(pdev, 2); | ||
3162 | return 0; | ||
3125 | } | 3163 | } |
3126 | 3164 | ||
3127 | static int be_map_pci_bars(struct be_adapter *adapter) | 3165 | static int be_map_pci_bars(struct be_adapter *adapter) |
@@ -3130,11 +3168,18 @@ static int be_map_pci_bars(struct be_adapter *adapter) | |||
3130 | int db_reg; | 3168 | int db_reg; |
3131 | 3169 | ||
3132 | if (lancer_chip(adapter)) { | 3170 | if (lancer_chip(adapter)) { |
3133 | addr = ioremap_nocache(pci_resource_start(adapter->pdev, 0), | 3171 | if (be_type_2_3(adapter)) { |
3134 | pci_resource_len(adapter->pdev, 0)); | 3172 | addr = ioremap_nocache( |
3135 | if (addr == NULL) | 3173 | pci_resource_start(adapter->pdev, 0), |
3136 | return -ENOMEM; | 3174 | pci_resource_len(adapter->pdev, 0)); |
3137 | adapter->db = addr; | 3175 | if (addr == NULL) |
3176 | return -ENOMEM; | ||
3177 | adapter->db = addr; | ||
3178 | } | ||
3179 | if (adapter->if_type == SLI_INTF_TYPE_3) { | ||
3180 | if (lancer_roce_map_pci_bars(adapter)) | ||
3181 | goto pci_map_err; | ||
3182 | } | ||
3138 | return 0; | 3183 | return 0; |
3139 | } | 3184 | } |
3140 | 3185 | ||
@@ -3159,14 +3204,19 @@ static int be_map_pci_bars(struct be_adapter *adapter) | |||
3159 | if (addr == NULL) | 3204 | if (addr == NULL) |
3160 | goto pci_map_err; | 3205 | goto pci_map_err; |
3161 | adapter->db = addr; | 3206 | adapter->db = addr; |
3162 | 3207 | if (adapter->sli_family == SKYHAWK_SLI_FAMILY) { | |
3208 | adapter->roce_db.size = 4096; | ||
3209 | adapter->roce_db.io_addr = | ||
3210 | pci_resource_start(adapter->pdev, db_reg); | ||
3211 | adapter->roce_db.total_size = | ||
3212 | pci_resource_len(adapter->pdev, db_reg); | ||
3213 | } | ||
3163 | return 0; | 3214 | return 0; |
3164 | pci_map_err: | 3215 | pci_map_err: |
3165 | be_unmap_pci_bars(adapter); | 3216 | be_unmap_pci_bars(adapter); |
3166 | return -ENOMEM; | 3217 | return -ENOMEM; |
3167 | } | 3218 | } |
3168 | 3219 | ||
3169 | |||
3170 | static void be_ctrl_cleanup(struct be_adapter *adapter) | 3220 | static void be_ctrl_cleanup(struct be_adapter *adapter) |
3171 | { | 3221 | { |
3172 | struct be_dma_mem *mem = &adapter->mbox_mem_alloced; | 3222 | struct be_dma_mem *mem = &adapter->mbox_mem_alloced; |
@@ -3272,6 +3322,8 @@ static void __devexit be_remove(struct pci_dev *pdev) | |||
3272 | if (!adapter) | 3322 | if (!adapter) |
3273 | return; | 3323 | return; |
3274 | 3324 | ||
3325 | be_roce_dev_remove(adapter); | ||
3326 | |||
3275 | unregister_netdev(adapter->netdev); | 3327 | unregister_netdev(adapter->netdev); |
3276 | 3328 | ||
3277 | be_clear(adapter); | 3329 | be_clear(adapter); |
@@ -3350,17 +3402,27 @@ static int be_dev_family_check(struct be_adapter *adapter) | |||
3350 | break; | 3402 | break; |
3351 | case BE_DEVICE_ID2: | 3403 | case BE_DEVICE_ID2: |
3352 | case OC_DEVICE_ID2: | 3404 | case OC_DEVICE_ID2: |
3353 | case OC_DEVICE_ID5: | ||
3354 | adapter->generation = BE_GEN3; | 3405 | adapter->generation = BE_GEN3; |
3355 | break; | 3406 | break; |
3356 | case OC_DEVICE_ID3: | 3407 | case OC_DEVICE_ID3: |
3357 | case OC_DEVICE_ID4: | 3408 | case OC_DEVICE_ID4: |
3358 | pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf); | 3409 | pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf); |
3410 | adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> | ||
3411 | SLI_INTF_IF_TYPE_SHIFT; | ||
3359 | if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> | 3412 | if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> |
3360 | SLI_INTF_IF_TYPE_SHIFT; | 3413 | SLI_INTF_IF_TYPE_SHIFT; |
3361 | |||
3362 | if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) || | 3414 | if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) || |
3363 | if_type != 0x02) { | 3415 | !be_type_2_3(adapter)) { |
3416 | dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n"); | ||
3417 | return -EINVAL; | ||
3418 | } | ||
3419 | adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >> | ||
3420 | SLI_INTF_FAMILY_SHIFT); | ||
3421 | adapter->generation = BE_GEN3; | ||
3422 | break; | ||
3423 | case OC_DEVICE_ID5: | ||
3424 | pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf); | ||
3425 | if ((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) { | ||
3364 | dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n"); | 3426 | dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n"); |
3365 | return -EINVAL; | 3427 | return -EINVAL; |
3366 | } | 3428 | } |
@@ -3620,6 +3682,8 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
3620 | if (status != 0) | 3682 | if (status != 0) |
3621 | goto unsetup; | 3683 | goto unsetup; |
3622 | 3684 | ||
3685 | be_roce_dev_add(adapter); | ||
3686 | |||
3623 | dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev), | 3687 | dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev), |
3624 | adapter->port_num); | 3688 | adapter->port_num); |
3625 | 3689 | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_roce.c b/drivers/net/ethernet/emulex/benet/be_roce.c new file mode 100644 index 000000000000..deecc44b3617 --- /dev/null +++ b/drivers/net/ethernet/emulex/benet/be_roce.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 - 2011 Emulex | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License version 2 | ||
7 | * as published by the Free Software Foundation. The full GNU General | ||
8 | * Public License is included in this distribution in the file called COPYING. | ||
9 | * | ||
10 | * Contact Information: | ||
11 | * linux-drivers@emulex.com | ||
12 | * | ||
13 | * Emulex | ||
14 | * 3333 Susan Street | ||
15 | * Costa Mesa, CA 92626 | ||
16 | */ | ||
17 | |||
18 | #include <linux/mutex.h> | ||
19 | #include <linux/list.h> | ||
20 | #include <linux/netdevice.h> | ||
21 | #include <linux/module.h> | ||
22 | |||
23 | #include "be.h" | ||
24 | #include "be_cmds.h" | ||
25 | |||
26 | static struct ocrdma_driver *ocrdma_drv; | ||
27 | static LIST_HEAD(be_adapter_list); | ||
28 | static DEFINE_MUTEX(be_adapter_list_lock); | ||
29 | |||
30 | static void _be_roce_dev_add(struct be_adapter *adapter) | ||
31 | { | ||
32 | struct be_dev_info dev_info; | ||
33 | int i, num_vec; | ||
34 | struct pci_dev *pdev = adapter->pdev; | ||
35 | |||
36 | if (!ocrdma_drv) | ||
37 | return; | ||
38 | if (pdev->device == OC_DEVICE_ID5) { | ||
39 | /* only msix is supported on these devices */ | ||
40 | if (!msix_enabled(adapter)) | ||
41 | return; | ||
42 | /* DPP region address and length */ | ||
43 | dev_info.dpp_unmapped_addr = pci_resource_start(pdev, 2); | ||
44 | dev_info.dpp_unmapped_len = pci_resource_len(pdev, 2); | ||
45 | } else { | ||
46 | dev_info.dpp_unmapped_addr = 0; | ||
47 | dev_info.dpp_unmapped_len = 0; | ||
48 | } | ||
49 | dev_info.pdev = adapter->pdev; | ||
50 | if (adapter->sli_family == SKYHAWK_SLI_FAMILY) | ||
51 | dev_info.db = adapter->db; | ||
52 | else | ||
53 | dev_info.db = adapter->roce_db.base; | ||
54 | dev_info.unmapped_db = adapter->roce_db.io_addr; | ||
55 | dev_info.db_page_size = adapter->roce_db.size; | ||
56 | dev_info.db_total_size = adapter->roce_db.total_size; | ||
57 | dev_info.netdev = adapter->netdev; | ||
58 | memcpy(dev_info.mac_addr, adapter->netdev->dev_addr, ETH_ALEN); | ||
59 | dev_info.dev_family = adapter->sli_family; | ||
60 | if (msix_enabled(adapter)) { | ||
61 | /* provide all the vectors, so that EQ creation response | ||
62 | * can decide which one to use. | ||
63 | */ | ||
64 | num_vec = adapter->num_msix_vec + adapter->num_msix_roce_vec; | ||
65 | dev_info.intr_mode = BE_INTERRUPT_MODE_MSIX; | ||
66 | dev_info.msix.num_vectors = min(num_vec, MAX_ROCE_MSIX_VECTORS); | ||
67 | /* provide start index of the vector, | ||
68 | * so in case of linear usage, | ||
69 | * it can use the base as starting point. | ||
70 | */ | ||
71 | dev_info.msix.start_vector = adapter->num_evt_qs; | ||
72 | for (i = 0; i < dev_info.msix.num_vectors; i++) { | ||
73 | dev_info.msix.vector_list[i] = | ||
74 | adapter->msix_entries[i].vector; | ||
75 | } | ||
76 | } else { | ||
77 | dev_info.msix.num_vectors = 0; | ||
78 | dev_info.intr_mode = BE_INTERRUPT_MODE_INTX; | ||
79 | } | ||
80 | adapter->ocrdma_dev = ocrdma_drv->add(&dev_info); | ||
81 | } | ||
82 | |||
83 | void be_roce_dev_add(struct be_adapter *adapter) | ||
84 | { | ||
85 | if (be_roce_supported(adapter)) { | ||
86 | INIT_LIST_HEAD(&adapter->entry); | ||
87 | mutex_lock(&be_adapter_list_lock); | ||
88 | list_add_tail(&adapter->entry, &be_adapter_list); | ||
89 | |||
90 | /* invoke add() routine of roce driver only if | ||
91 | * valid driver registered with add method and add() is not yet | ||
92 | * invoked on a given adapter. | ||
93 | */ | ||
94 | _be_roce_dev_add(adapter); | ||
95 | mutex_unlock(&be_adapter_list_lock); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | void _be_roce_dev_remove(struct be_adapter *adapter) | ||
100 | { | ||
101 | if (ocrdma_drv && ocrdma_drv->remove && adapter->ocrdma_dev) | ||
102 | ocrdma_drv->remove(adapter->ocrdma_dev); | ||
103 | adapter->ocrdma_dev = NULL; | ||
104 | } | ||
105 | |||
106 | void be_roce_dev_remove(struct be_adapter *adapter) | ||
107 | { | ||
108 | if (be_roce_supported(adapter)) { | ||
109 | mutex_lock(&be_adapter_list_lock); | ||
110 | _be_roce_dev_remove(adapter); | ||
111 | list_del(&adapter->entry); | ||
112 | mutex_unlock(&be_adapter_list_lock); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | void _be_roce_dev_open(struct be_adapter *adapter) | ||
117 | { | ||
118 | if (ocrdma_drv && adapter->ocrdma_dev && | ||
119 | ocrdma_drv->state_change_handler) | ||
120 | ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 0); | ||
121 | } | ||
122 | |||
123 | void be_roce_dev_open(struct be_adapter *adapter) | ||
124 | { | ||
125 | if (be_roce_supported(adapter)) { | ||
126 | mutex_lock(&be_adapter_list_lock); | ||
127 | _be_roce_dev_open(adapter); | ||
128 | mutex_unlock(&be_adapter_list_lock); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | void _be_roce_dev_close(struct be_adapter *adapter) | ||
133 | { | ||
134 | if (ocrdma_drv && adapter->ocrdma_dev && | ||
135 | ocrdma_drv->state_change_handler) | ||
136 | ocrdma_drv->state_change_handler(adapter->ocrdma_dev, 1); | ||
137 | } | ||
138 | |||
139 | void be_roce_dev_close(struct be_adapter *adapter) | ||
140 | { | ||
141 | if (be_roce_supported(adapter)) { | ||
142 | mutex_lock(&be_adapter_list_lock); | ||
143 | _be_roce_dev_close(adapter); | ||
144 | mutex_unlock(&be_adapter_list_lock); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | int be_roce_register_driver(struct ocrdma_driver *drv) | ||
149 | { | ||
150 | struct be_adapter *dev; | ||
151 | |||
152 | mutex_lock(&be_adapter_list_lock); | ||
153 | if (ocrdma_drv) { | ||
154 | mutex_unlock(&be_adapter_list_lock); | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | ocrdma_drv = drv; | ||
158 | list_for_each_entry(dev, &be_adapter_list, entry) { | ||
159 | struct net_device *netdev; | ||
160 | _be_roce_dev_add(dev); | ||
161 | netdev = dev->netdev; | ||
162 | if (netif_running(netdev) && netif_oper_up(netdev)) | ||
163 | _be_roce_dev_open(dev); | ||
164 | } | ||
165 | mutex_unlock(&be_adapter_list_lock); | ||
166 | return 0; | ||
167 | } | ||
168 | EXPORT_SYMBOL(be_roce_register_driver); | ||
169 | |||
170 | void be_roce_unregister_driver(struct ocrdma_driver *drv) | ||
171 | { | ||
172 | struct be_adapter *dev; | ||
173 | |||
174 | mutex_lock(&be_adapter_list_lock); | ||
175 | list_for_each_entry(dev, &be_adapter_list, entry) { | ||
176 | if (dev->ocrdma_dev) | ||
177 | _be_roce_dev_remove(dev); | ||
178 | } | ||
179 | ocrdma_drv = NULL; | ||
180 | mutex_unlock(&be_adapter_list_lock); | ||
181 | } | ||
182 | EXPORT_SYMBOL(be_roce_unregister_driver); | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_roce.h b/drivers/net/ethernet/emulex/benet/be_roce.h new file mode 100644 index 000000000000..db4ea8081c07 --- /dev/null +++ b/drivers/net/ethernet/emulex/benet/be_roce.h | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 - 2011 Emulex | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License version 2 | ||
7 | * as published by the Free Software Foundation. The full GNU General | ||
8 | * Public License is included in this distribution in the file called COPYING. | ||
9 | * | ||
10 | * Contact Information: | ||
11 | * linux-drivers@emulex.com | ||
12 | * | ||
13 | * Emulex | ||
14 | * 3333 Susan Street | ||
15 | * Costa Mesa, CA 92626 | ||
16 | */ | ||
17 | |||
18 | #ifndef BE_ROCE_H | ||
19 | #define BE_ROCE_H | ||
20 | |||
21 | #include <linux/pci.h> | ||
22 | #include <linux/netdevice.h> | ||
23 | |||
24 | struct ocrdma_dev; | ||
25 | |||
26 | enum be_interrupt_mode { | ||
27 | BE_INTERRUPT_MODE_MSIX = 0, | ||
28 | BE_INTERRUPT_MODE_INTX = 1, | ||
29 | BE_INTERRUPT_MODE_MSI = 2, | ||
30 | }; | ||
31 | |||
32 | #define MAX_ROCE_MSIX_VECTORS 16 | ||
33 | struct be_dev_info { | ||
34 | u8 __iomem *db; | ||
35 | u64 unmapped_db; | ||
36 | u32 db_page_size; | ||
37 | u32 db_total_size; | ||
38 | u64 dpp_unmapped_addr; | ||
39 | u32 dpp_unmapped_len; | ||
40 | struct pci_dev *pdev; | ||
41 | struct net_device *netdev; | ||
42 | u8 mac_addr[ETH_ALEN]; | ||
43 | u32 dev_family; | ||
44 | enum be_interrupt_mode intr_mode; | ||
45 | struct { | ||
46 | int num_vectors; | ||
47 | int start_vector; | ||
48 | u32 vector_list[MAX_ROCE_MSIX_VECTORS]; | ||
49 | } msix; | ||
50 | }; | ||
51 | |||
52 | /* ocrdma driver register's the callback functions with nic driver. */ | ||
53 | struct ocrdma_driver { | ||
54 | unsigned char name[32]; | ||
55 | struct ocrdma_dev *(*add) (struct be_dev_info *dev_info); | ||
56 | void (*remove) (struct ocrdma_dev *); | ||
57 | void (*state_change_handler) (struct ocrdma_dev *, u32 new_state); | ||
58 | }; | ||
59 | |||
60 | enum { | ||
61 | BE_DEV_UP = 0, | ||
62 | BE_DEV_DOWN = 1 | ||
63 | }; | ||
64 | |||
65 | /* APIs for RoCE driver to register callback handlers, | ||
66 | * which will be invoked when device is added, removed, ifup, ifdown | ||
67 | */ | ||
68 | int be_roce_register_driver(struct ocrdma_driver *drv); | ||
69 | void be_roce_unregister_driver(struct ocrdma_driver *drv); | ||
70 | |||
71 | /* API for RoCE driver to issue mailbox commands */ | ||
72 | int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload, | ||
73 | int wrb_payload_size, u16 *cmd_status, u16 *ext_status); | ||
74 | |||
75 | #endif /* BE_ROCE_H */ | ||