diff options
author | David S. Miller <davem@davemloft.net> | 2010-04-07 02:53:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-07 02:53:30 -0400 |
commit | 4a35ecf8bf1c4b039503fa554100fe85c761de76 (patch) | |
tree | 9b75f5d5636004d9a9aa496924377379be09aa1f /drivers | |
parent | b4d562e3c3553ac58c7120555c4e4aefbb090a2a (diff) | |
parent | fb9e2d887243499b8d28efcf80821c4f6a092395 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/bonding/bond_main.c
drivers/net/via-velocity.c
drivers/net/wireless/iwlwifi/iwl-agn.c
Diffstat (limited to 'drivers')
339 files changed, 23171 insertions, 4451 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 2ff2b6ab5b6c..cbe6f3924a10 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -998,6 +998,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
998 | } | 998 | } |
999 | 999 | ||
1000 | if (acpi_video_backlight_support()) { | 1000 | if (acpi_video_backlight_support()) { |
1001 | struct backlight_properties props; | ||
1001 | int result; | 1002 | int result; |
1002 | static int count = 0; | 1003 | static int count = 0; |
1003 | char *name; | 1004 | char *name; |
@@ -1010,12 +1011,14 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
1010 | return; | 1011 | return; |
1011 | 1012 | ||
1012 | sprintf(name, "acpi_video%d", count++); | 1013 | sprintf(name, "acpi_video%d", count++); |
1013 | device->backlight = backlight_device_register(name, | 1014 | memset(&props, 0, sizeof(struct backlight_properties)); |
1014 | NULL, device, &acpi_backlight_ops); | 1015 | props.max_brightness = device->brightness->count - 3; |
1016 | device->backlight = backlight_device_register(name, NULL, device, | ||
1017 | &acpi_backlight_ops, | ||
1018 | &props); | ||
1015 | kfree(name); | 1019 | kfree(name); |
1016 | if (IS_ERR(device->backlight)) | 1020 | if (IS_ERR(device->backlight)) |
1017 | return; | 1021 | return; |
1018 | device->backlight->props.max_brightness = device->brightness->count-3; | ||
1019 | 1022 | ||
1020 | result = sysfs_create_link(&device->backlight->dev.kobj, | 1023 | result = sysfs_create_link(&device->backlight->dev.kobj, |
1021 | &device->dev->dev.kobj, "device"); | 1024 | &device->dev->dev.kobj, "device"); |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 6bd930b93bcc..fdc9bcbe55a2 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -641,6 +641,21 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
641 | { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq }, /* MCP67 */ | 641 | { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq }, /* MCP67 */ |
642 | { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq }, /* MCP67 */ | 642 | { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq }, /* MCP67 */ |
643 | { PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq }, /* Linux ID */ | 643 | { PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq }, /* Linux ID */ |
644 | { PCI_VDEVICE(NVIDIA, 0x0581), board_ahci_yesncq }, /* Linux ID */ | ||
645 | { PCI_VDEVICE(NVIDIA, 0x0582), board_ahci_yesncq }, /* Linux ID */ | ||
646 | { PCI_VDEVICE(NVIDIA, 0x0583), board_ahci_yesncq }, /* Linux ID */ | ||
647 | { PCI_VDEVICE(NVIDIA, 0x0584), board_ahci_yesncq }, /* Linux ID */ | ||
648 | { PCI_VDEVICE(NVIDIA, 0x0585), board_ahci_yesncq }, /* Linux ID */ | ||
649 | { PCI_VDEVICE(NVIDIA, 0x0586), board_ahci_yesncq }, /* Linux ID */ | ||
650 | { PCI_VDEVICE(NVIDIA, 0x0587), board_ahci_yesncq }, /* Linux ID */ | ||
651 | { PCI_VDEVICE(NVIDIA, 0x0588), board_ahci_yesncq }, /* Linux ID */ | ||
652 | { PCI_VDEVICE(NVIDIA, 0x0589), board_ahci_yesncq }, /* Linux ID */ | ||
653 | { PCI_VDEVICE(NVIDIA, 0x058a), board_ahci_yesncq }, /* Linux ID */ | ||
654 | { PCI_VDEVICE(NVIDIA, 0x058b), board_ahci_yesncq }, /* Linux ID */ | ||
655 | { PCI_VDEVICE(NVIDIA, 0x058c), board_ahci_yesncq }, /* Linux ID */ | ||
656 | { PCI_VDEVICE(NVIDIA, 0x058d), board_ahci_yesncq }, /* Linux ID */ | ||
657 | { PCI_VDEVICE(NVIDIA, 0x058e), board_ahci_yesncq }, /* Linux ID */ | ||
658 | { PCI_VDEVICE(NVIDIA, 0x058f), board_ahci_yesncq }, /* Linux ID */ | ||
644 | { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq }, /* MCP73 */ | 659 | { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq }, /* MCP73 */ |
645 | { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq }, /* MCP73 */ | 660 | { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq }, /* MCP73 */ |
646 | { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq }, /* MCP73 */ | 661 | { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq }, /* MCP73 */ |
@@ -2263,7 +2278,7 @@ static void ahci_port_intr(struct ata_port *ap) | |||
2263 | struct ahci_port_priv *pp = ap->private_data; | 2278 | struct ahci_port_priv *pp = ap->private_data; |
2264 | struct ahci_host_priv *hpriv = ap->host->private_data; | 2279 | struct ahci_host_priv *hpriv = ap->host->private_data; |
2265 | int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING); | 2280 | int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING); |
2266 | u32 status, qc_active; | 2281 | u32 status, qc_active = 0; |
2267 | int rc; | 2282 | int rc; |
2268 | 2283 | ||
2269 | status = readl(port_mmio + PORT_IRQ_STAT); | 2284 | status = readl(port_mmio + PORT_IRQ_STAT); |
@@ -2321,11 +2336,22 @@ static void ahci_port_intr(struct ata_port *ap) | |||
2321 | } | 2336 | } |
2322 | } | 2337 | } |
2323 | 2338 | ||
2324 | /* pp->active_link is valid iff any command is in flight */ | 2339 | /* pp->active_link is not reliable once FBS is enabled, both |
2325 | if (ap->qc_active && pp->active_link->sactive) | 2340 | * PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because |
2326 | qc_active = readl(port_mmio + PORT_SCR_ACT); | 2341 | * NCQ and non-NCQ commands may be in flight at the same time. |
2327 | else | 2342 | */ |
2328 | qc_active = readl(port_mmio + PORT_CMD_ISSUE); | 2343 | if (pp->fbs_enabled) { |
2344 | if (ap->qc_active) { | ||
2345 | qc_active = readl(port_mmio + PORT_SCR_ACT); | ||
2346 | qc_active |= readl(port_mmio + PORT_CMD_ISSUE); | ||
2347 | } | ||
2348 | } else { | ||
2349 | /* pp->active_link is valid iff any command is in flight */ | ||
2350 | if (ap->qc_active && pp->active_link->sactive) | ||
2351 | qc_active = readl(port_mmio + PORT_SCR_ACT); | ||
2352 | else | ||
2353 | qc_active = readl(port_mmio + PORT_CMD_ISSUE); | ||
2354 | } | ||
2329 | 2355 | ||
2330 | rc = ata_qc_complete_multiple(ap, qc_active); | 2356 | rc = ata_qc_complete_multiple(ap, qc_active); |
2331 | 2357 | ||
@@ -3022,6 +3048,14 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
3022 | * On HP dv[4-6] and HDX18 with earlier BIOSen, link | 3048 | * On HP dv[4-6] and HDX18 with earlier BIOSen, link |
3023 | * to the harddisk doesn't become online after | 3049 | * to the harddisk doesn't become online after |
3024 | * resuming from STR. Warn and fail suspend. | 3050 | * resuming from STR. Warn and fail suspend. |
3051 | * | ||
3052 | * http://bugzilla.kernel.org/show_bug.cgi?id=12276 | ||
3053 | * | ||
3054 | * Use dates instead of versions to match as HP is | ||
3055 | * apparently recycling both product and version | ||
3056 | * strings. | ||
3057 | * | ||
3058 | * http://bugzilla.kernel.org/show_bug.cgi?id=15462 | ||
3025 | */ | 3059 | */ |
3026 | { | 3060 | { |
3027 | .ident = "dv4", | 3061 | .ident = "dv4", |
@@ -3030,7 +3064,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
3030 | DMI_MATCH(DMI_PRODUCT_NAME, | 3064 | DMI_MATCH(DMI_PRODUCT_NAME, |
3031 | "HP Pavilion dv4 Notebook PC"), | 3065 | "HP Pavilion dv4 Notebook PC"), |
3032 | }, | 3066 | }, |
3033 | .driver_data = "F.30", /* cutoff BIOS version */ | 3067 | .driver_data = "20090105", /* F.30 */ |
3034 | }, | 3068 | }, |
3035 | { | 3069 | { |
3036 | .ident = "dv5", | 3070 | .ident = "dv5", |
@@ -3039,7 +3073,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
3039 | DMI_MATCH(DMI_PRODUCT_NAME, | 3073 | DMI_MATCH(DMI_PRODUCT_NAME, |
3040 | "HP Pavilion dv5 Notebook PC"), | 3074 | "HP Pavilion dv5 Notebook PC"), |
3041 | }, | 3075 | }, |
3042 | .driver_data = "F.16", /* cutoff BIOS version */ | 3076 | .driver_data = "20090506", /* F.16 */ |
3043 | }, | 3077 | }, |
3044 | { | 3078 | { |
3045 | .ident = "dv6", | 3079 | .ident = "dv6", |
@@ -3048,7 +3082,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
3048 | DMI_MATCH(DMI_PRODUCT_NAME, | 3082 | DMI_MATCH(DMI_PRODUCT_NAME, |
3049 | "HP Pavilion dv6 Notebook PC"), | 3083 | "HP Pavilion dv6 Notebook PC"), |
3050 | }, | 3084 | }, |
3051 | .driver_data = "F.21", /* cutoff BIOS version */ | 3085 | .driver_data = "20090423", /* F.21 */ |
3052 | }, | 3086 | }, |
3053 | { | 3087 | { |
3054 | .ident = "HDX18", | 3088 | .ident = "HDX18", |
@@ -3057,7 +3091,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
3057 | DMI_MATCH(DMI_PRODUCT_NAME, | 3091 | DMI_MATCH(DMI_PRODUCT_NAME, |
3058 | "HP HDX18 Notebook PC"), | 3092 | "HP HDX18 Notebook PC"), |
3059 | }, | 3093 | }, |
3060 | .driver_data = "F.23", /* cutoff BIOS version */ | 3094 | .driver_data = "20090430", /* F.23 */ |
3061 | }, | 3095 | }, |
3062 | /* | 3096 | /* |
3063 | * Acer eMachines G725 has the same problem. BIOS | 3097 | * Acer eMachines G725 has the same problem. BIOS |
@@ -3065,6 +3099,8 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
3065 | * work. Inbetween, there are V1.06, V2.06 and V3.03 | 3099 | * work. Inbetween, there are V1.06, V2.06 and V3.03 |
3066 | * that we don't have much idea about. For now, | 3100 | * that we don't have much idea about. For now, |
3067 | * blacklist anything older than V3.04. | 3101 | * blacklist anything older than V3.04. |
3102 | * | ||
3103 | * http://bugzilla.kernel.org/show_bug.cgi?id=15104 | ||
3068 | */ | 3104 | */ |
3069 | { | 3105 | { |
3070 | .ident = "G725", | 3106 | .ident = "G725", |
@@ -3072,19 +3108,21 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
3072 | DMI_MATCH(DMI_SYS_VENDOR, "eMachines"), | 3108 | DMI_MATCH(DMI_SYS_VENDOR, "eMachines"), |
3073 | DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"), | 3109 | DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"), |
3074 | }, | 3110 | }, |
3075 | .driver_data = "V3.04", /* cutoff BIOS version */ | 3111 | .driver_data = "20091216", /* V3.04 */ |
3076 | }, | 3112 | }, |
3077 | { } /* terminate list */ | 3113 | { } /* terminate list */ |
3078 | }; | 3114 | }; |
3079 | const struct dmi_system_id *dmi = dmi_first_match(sysids); | 3115 | const struct dmi_system_id *dmi = dmi_first_match(sysids); |
3080 | const char *ver; | 3116 | int year, month, date; |
3117 | char buf[9]; | ||
3081 | 3118 | ||
3082 | if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2)) | 3119 | if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2)) |
3083 | return false; | 3120 | return false; |
3084 | 3121 | ||
3085 | ver = dmi_get_system_info(DMI_BIOS_VERSION); | 3122 | dmi_get_date(DMI_BIOS_DATE, &year, &month, &date); |
3123 | snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date); | ||
3086 | 3124 | ||
3087 | return !ver || strcmp(ver, dmi->driver_data) < 0; | 3125 | return strcmp(buf, dmi->driver_data) < 0; |
3088 | } | 3126 | } |
3089 | 3127 | ||
3090 | static bool ahci_broken_online(struct pci_dev *pdev) | 3128 | static bool ahci_broken_online(struct pci_dev *pdev) |
diff --git a/drivers/base/class.c b/drivers/base/class.c index 0147f476b8a9..9c6a0d6408e7 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -219,6 +219,8 @@ static void class_create_release(struct class *cls) | |||
219 | * This is used to create a struct class pointer that can then be used | 219 | * This is used to create a struct class pointer that can then be used |
220 | * in calls to device_create(). | 220 | * in calls to device_create(). |
221 | * | 221 | * |
222 | * Returns &struct class pointer on success, or ERR_PTR() on error. | ||
223 | * | ||
222 | * Note, the pointer created here is to be destroyed when finished by | 224 | * Note, the pointer created here is to be destroyed when finished by |
223 | * making a call to class_destroy(). | 225 | * making a call to class_destroy(). |
224 | */ | 226 | */ |
diff --git a/drivers/base/core.c b/drivers/base/core.c index ef55df34ddd0..b56a0ba31d4a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -1345,6 +1345,8 @@ static void root_device_release(struct device *dev) | |||
1345 | * 'module' symlink which points to the @owner directory | 1345 | * 'module' symlink which points to the @owner directory |
1346 | * in sysfs. | 1346 | * in sysfs. |
1347 | * | 1347 | * |
1348 | * Returns &struct device pointer on success, or ERR_PTR() on error. | ||
1349 | * | ||
1348 | * Note: You probably want to use root_device_register(). | 1350 | * Note: You probably want to use root_device_register(). |
1349 | */ | 1351 | */ |
1350 | struct device *__root_device_register(const char *name, struct module *owner) | 1352 | struct device *__root_device_register(const char *name, struct module *owner) |
@@ -1432,6 +1434,8 @@ static void device_create_release(struct device *dev) | |||
1432 | * Any further sysfs files that might be required can be created using this | 1434 | * Any further sysfs files that might be required can be created using this |
1433 | * pointer. | 1435 | * pointer. |
1434 | * | 1436 | * |
1437 | * Returns &struct device pointer on success, or ERR_PTR() on error. | ||
1438 | * | ||
1435 | * Note: the struct class passed to this function must have previously | 1439 | * Note: the struct class passed to this function must have previously |
1436 | * been created with a call to class_create(). | 1440 | * been created with a call to class_create(). |
1437 | */ | 1441 | */ |
@@ -1492,6 +1496,8 @@ EXPORT_SYMBOL_GPL(device_create_vargs); | |||
1492 | * Any further sysfs files that might be required can be created using this | 1496 | * Any further sysfs files that might be required can be created using this |
1493 | * pointer. | 1497 | * pointer. |
1494 | * | 1498 | * |
1499 | * Returns &struct device pointer on success, or ERR_PTR() on error. | ||
1500 | * | ||
1495 | * Note: the struct class passed to this function must have previously | 1501 | * Note: the struct class passed to this function must have previously |
1496 | * been created with a call to class_create(). | 1502 | * been created with a call to class_create(). |
1497 | */ | 1503 | */ |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 7036e8e96ab8..b5242e1e8bc4 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -79,24 +79,24 @@ void unregister_cpu(struct cpu *cpu) | |||
79 | } | 79 | } |
80 | 80 | ||
81 | #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE | 81 | #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE |
82 | static ssize_t cpu_probe_store(struct sys_device *dev, | 82 | static ssize_t cpu_probe_store(struct sysdev_class *class, |
83 | struct sysdev_attribute *attr, | 83 | struct sysdev_class_attribute *attr, |
84 | const char *buf, | 84 | const char *buf, |
85 | size_t count) | 85 | size_t count) |
86 | { | 86 | { |
87 | return arch_cpu_probe(buf, count); | 87 | return arch_cpu_probe(buf, count); |
88 | } | 88 | } |
89 | 89 | ||
90 | static ssize_t cpu_release_store(struct sys_device *dev, | 90 | static ssize_t cpu_release_store(struct sysdev_class *class, |
91 | struct sysdev_attribute *attr, | 91 | struct sysdev_class_attribute *attr, |
92 | const char *buf, | 92 | const char *buf, |
93 | size_t count) | 93 | size_t count) |
94 | { | 94 | { |
95 | return arch_cpu_release(buf, count); | 95 | return arch_cpu_release(buf, count); |
96 | } | 96 | } |
97 | 97 | ||
98 | static SYSDEV_ATTR(probe, S_IWUSR, NULL, cpu_probe_store); | 98 | static SYSDEV_CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store); |
99 | static SYSDEV_ATTR(release, S_IWUSR, NULL, cpu_release_store); | 99 | static SYSDEV_CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store); |
100 | #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ | 100 | #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ |
101 | 101 | ||
102 | #else /* ... !CONFIG_HOTPLUG_CPU */ | 102 | #else /* ... !CONFIG_HOTPLUG_CPU */ |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index d0dc26ad5387..18518ba13c81 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -78,6 +78,7 @@ firmware_timeout_show(struct class *class, | |||
78 | /** | 78 | /** |
79 | * firmware_timeout_store - set number of seconds to wait for firmware | 79 | * firmware_timeout_store - set number of seconds to wait for firmware |
80 | * @class: device class pointer | 80 | * @class: device class pointer |
81 | * @attr: device attribute pointer | ||
81 | * @buf: buffer to scan for timeout value | 82 | * @buf: buffer to scan for timeout value |
82 | * @count: number of bytes in @buf | 83 | * @count: number of bytes in @buf |
83 | * | 84 | * |
@@ -442,6 +443,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p, | |||
442 | fw_priv = dev_get_drvdata(f_dev); | 443 | fw_priv = dev_get_drvdata(f_dev); |
443 | 444 | ||
444 | fw_priv->fw = fw; | 445 | fw_priv->fw = fw; |
446 | sysfs_bin_attr_init(&fw_priv->attr_data); | ||
445 | retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data); | 447 | retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data); |
446 | if (retval) { | 448 | if (retval) { |
447 | dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__); | 449 | dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__); |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 2f8691511190..db0848e54cc6 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -429,12 +429,16 @@ static inline int memory_fail_init(void) | |||
429 | * differentiation between which *physical* devices each | 429 | * differentiation between which *physical* devices each |
430 | * section belongs to... | 430 | * section belongs to... |
431 | */ | 431 | */ |
432 | int __weak arch_get_memory_phys_device(unsigned long start_pfn) | ||
433 | { | ||
434 | return 0; | ||
435 | } | ||
432 | 436 | ||
433 | static int add_memory_block(int nid, struct mem_section *section, | 437 | static int add_memory_block(int nid, struct mem_section *section, |
434 | unsigned long state, int phys_device, | 438 | unsigned long state, enum mem_add_context context) |
435 | enum mem_add_context context) | ||
436 | { | 439 | { |
437 | struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); | 440 | struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); |
441 | unsigned long start_pfn; | ||
438 | int ret = 0; | 442 | int ret = 0; |
439 | 443 | ||
440 | if (!mem) | 444 | if (!mem) |
@@ -443,7 +447,8 @@ static int add_memory_block(int nid, struct mem_section *section, | |||
443 | mem->phys_index = __section_nr(section); | 447 | mem->phys_index = __section_nr(section); |
444 | mem->state = state; | 448 | mem->state = state; |
445 | mutex_init(&mem->state_mutex); | 449 | mutex_init(&mem->state_mutex); |
446 | mem->phys_device = phys_device; | 450 | start_pfn = section_nr_to_pfn(mem->phys_index); |
451 | mem->phys_device = arch_get_memory_phys_device(start_pfn); | ||
447 | 452 | ||
448 | ret = register_memory(mem, section); | 453 | ret = register_memory(mem, section); |
449 | if (!ret) | 454 | if (!ret) |
@@ -515,7 +520,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, | |||
515 | */ | 520 | */ |
516 | int register_new_memory(int nid, struct mem_section *section) | 521 | int register_new_memory(int nid, struct mem_section *section) |
517 | { | 522 | { |
518 | return add_memory_block(nid, section, MEM_OFFLINE, 0, HOTPLUG); | 523 | return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG); |
519 | } | 524 | } |
520 | 525 | ||
521 | int unregister_memory_section(struct mem_section *section) | 526 | int unregister_memory_section(struct mem_section *section) |
@@ -548,7 +553,7 @@ int __init memory_dev_init(void) | |||
548 | if (!present_section_nr(i)) | 553 | if (!present_section_nr(i)) |
549 | continue; | 554 | continue; |
550 | err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, | 555 | err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, |
551 | 0, BOOT); | 556 | BOOT); |
552 | if (!ret) | 557 | if (!ret) |
553 | ret = err; | 558 | ret = err; |
554 | } | 559 | } |
diff --git a/drivers/base/node.c b/drivers/base/node.c index ad43185ec15a..93b3ac65c2d4 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -165,8 +165,11 @@ static ssize_t node_read_distance(struct sys_device * dev, | |||
165 | int len = 0; | 165 | int len = 0; |
166 | int i; | 166 | int i; |
167 | 167 | ||
168 | /* buf currently PAGE_SIZE, need ~4 chars per node */ | 168 | /* |
169 | BUILD_BUG_ON(MAX_NUMNODES*4 > PAGE_SIZE/2); | 169 | * buf is currently PAGE_SIZE in length and each node needs 4 chars |
170 | * at the most (distance + space or newline). | ||
171 | */ | ||
172 | BUILD_BUG_ON(MAX_NUMNODES * 4 > PAGE_SIZE); | ||
170 | 173 | ||
171 | for_each_online_node(i) | 174 | for_each_online_node(i) |
172 | len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i)); | 175 | len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i)); |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 1ba9d617d241..4b4b565c835f 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -362,6 +362,8 @@ EXPORT_SYMBOL_GPL(platform_device_unregister); | |||
362 | * enumeration tasks, they don't fully conform to the Linux driver model. | 362 | * enumeration tasks, they don't fully conform to the Linux driver model. |
363 | * In particular, when such drivers are built as modules, they can't be | 363 | * In particular, when such drivers are built as modules, they can't be |
364 | * "hotplugged". | 364 | * "hotplugged". |
365 | * | ||
366 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. | ||
365 | */ | 367 | */ |
366 | struct platform_device *platform_device_register_simple(const char *name, | 368 | struct platform_device *platform_device_register_simple(const char *name, |
367 | int id, | 369 | int id, |
@@ -408,6 +410,8 @@ EXPORT_SYMBOL_GPL(platform_device_register_simple); | |||
408 | * allocated for the device allows drivers using such devices to be | 410 | * allocated for the device allows drivers using such devices to be |
409 | * unloaded without waiting for the last reference to the device to be | 411 | * unloaded without waiting for the last reference to the device to be |
410 | * dropped. | 412 | * dropped. |
413 | * | ||
414 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. | ||
411 | */ | 415 | */ |
412 | struct platform_device *platform_device_register_data( | 416 | struct platform_device *platform_device_register_data( |
413 | struct device *parent, | 417 | struct device *parent, |
@@ -559,6 +563,8 @@ EXPORT_SYMBOL_GPL(platform_driver_probe); | |||
559 | * | 563 | * |
560 | * Use this in legacy-style modules that probe hardware directly and | 564 | * Use this in legacy-style modules that probe hardware directly and |
561 | * register a single platform device and corresponding platform driver. | 565 | * register a single platform device and corresponding platform driver. |
566 | * | ||
567 | * Returns &struct platform_device pointer on success, or ERR_PTR() on error. | ||
562 | */ | 568 | */ |
563 | struct platform_device * __init_or_module platform_create_bundle( | 569 | struct platform_device * __init_or_module platform_create_bundle( |
564 | struct platform_driver *driver, | 570 | struct platform_driver *driver, |
@@ -1052,9 +1058,11 @@ static __initdata LIST_HEAD(early_platform_driver_list); | |||
1052 | static __initdata LIST_HEAD(early_platform_device_list); | 1058 | static __initdata LIST_HEAD(early_platform_device_list); |
1053 | 1059 | ||
1054 | /** | 1060 | /** |
1055 | * early_platform_driver_register | 1061 | * early_platform_driver_register - register early platform driver |
1056 | * @epdrv: early_platform driver structure | 1062 | * @epdrv: early_platform driver structure |
1057 | * @buf: string passed from early_param() | 1063 | * @buf: string passed from early_param() |
1064 | * | ||
1065 | * Helper function for early_platform_init() / early_platform_init_buffer() | ||
1058 | */ | 1066 | */ |
1059 | int __init early_platform_driver_register(struct early_platform_driver *epdrv, | 1067 | int __init early_platform_driver_register(struct early_platform_driver *epdrv, |
1060 | char *buf) | 1068 | char *buf) |
@@ -1106,9 +1114,12 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv, | |||
1106 | } | 1114 | } |
1107 | 1115 | ||
1108 | /** | 1116 | /** |
1109 | * early_platform_add_devices - add a numbers of early platform devices | 1117 | * early_platform_add_devices - adds a number of early platform devices |
1110 | * @devs: array of early platform devices to add | 1118 | * @devs: array of early platform devices to add |
1111 | * @num: number of early platform devices in array | 1119 | * @num: number of early platform devices in array |
1120 | * | ||
1121 | * Used by early architecture code to register early platform devices and | ||
1122 | * their platform data. | ||
1112 | */ | 1123 | */ |
1113 | void __init early_platform_add_devices(struct platform_device **devs, int num) | 1124 | void __init early_platform_add_devices(struct platform_device **devs, int num) |
1114 | { | 1125 | { |
@@ -1128,8 +1139,12 @@ void __init early_platform_add_devices(struct platform_device **devs, int num) | |||
1128 | } | 1139 | } |
1129 | 1140 | ||
1130 | /** | 1141 | /** |
1131 | * early_platform_driver_register_all | 1142 | * early_platform_driver_register_all - register early platform drivers |
1132 | * @class_str: string to identify early platform driver class | 1143 | * @class_str: string to identify early platform driver class |
1144 | * | ||
1145 | * Used by architecture code to register all early platform drivers | ||
1146 | * for a certain class. If omitted then only early platform drivers | ||
1147 | * with matching kernel command line class parameters will be registered. | ||
1133 | */ | 1148 | */ |
1134 | void __init early_platform_driver_register_all(char *class_str) | 1149 | void __init early_platform_driver_register_all(char *class_str) |
1135 | { | 1150 | { |
@@ -1151,7 +1166,7 @@ void __init early_platform_driver_register_all(char *class_str) | |||
1151 | } | 1166 | } |
1152 | 1167 | ||
1153 | /** | 1168 | /** |
1154 | * early_platform_match | 1169 | * early_platform_match - find early platform device matching driver |
1155 | * @epdrv: early platform driver structure | 1170 | * @epdrv: early platform driver structure |
1156 | * @id: id to match against | 1171 | * @id: id to match against |
1157 | */ | 1172 | */ |
@@ -1169,7 +1184,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id) | |||
1169 | } | 1184 | } |
1170 | 1185 | ||
1171 | /** | 1186 | /** |
1172 | * early_platform_left | 1187 | * early_platform_left - check if early platform driver has matching devices |
1173 | * @epdrv: early platform driver structure | 1188 | * @epdrv: early platform driver structure |
1174 | * @id: return true if id or above exists | 1189 | * @id: return true if id or above exists |
1175 | */ | 1190 | */ |
@@ -1187,7 +1202,7 @@ static __init int early_platform_left(struct early_platform_driver *epdrv, | |||
1187 | } | 1202 | } |
1188 | 1203 | ||
1189 | /** | 1204 | /** |
1190 | * early_platform_driver_probe_id | 1205 | * early_platform_driver_probe_id - probe drivers matching class_str and id |
1191 | * @class_str: string to identify early platform driver class | 1206 | * @class_str: string to identify early platform driver class |
1192 | * @id: id to match against | 1207 | * @id: id to match against |
1193 | * @nr_probe: number of platform devices to successfully probe before exiting | 1208 | * @nr_probe: number of platform devices to successfully probe before exiting |
@@ -1257,10 +1272,14 @@ static int __init early_platform_driver_probe_id(char *class_str, | |||
1257 | } | 1272 | } |
1258 | 1273 | ||
1259 | /** | 1274 | /** |
1260 | * early_platform_driver_probe | 1275 | * early_platform_driver_probe - probe a class of registered drivers |
1261 | * @class_str: string to identify early platform driver class | 1276 | * @class_str: string to identify early platform driver class |
1262 | * @nr_probe: number of platform devices to successfully probe before exiting | 1277 | * @nr_probe: number of platform devices to successfully probe before exiting |
1263 | * @user_only: only probe user specified early platform devices | 1278 | * @user_only: only probe user specified early platform devices |
1279 | * | ||
1280 | * Used by architecture code to probe registered early platform drivers | ||
1281 | * within a certain class. For probe to happen a registered early platform | ||
1282 | * device matching a registered early platform driver is needed. | ||
1264 | */ | 1283 | */ |
1265 | int __init early_platform_driver_probe(char *class_str, | 1284 | int __init early_platform_driver_probe(char *class_str, |
1266 | int nr_probe, | 1285 | int nr_probe, |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index e481c5938bad..9c5eea3ea4de 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -215,9 +215,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp) | |||
215 | else | 215 | else |
216 | v &= ~0xffff; | 216 | v &= ~0xffff; |
217 | 217 | ||
218 | for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ; | 218 | for_each_set_bit(irq, &v, HPET_MAX_IRQ) { |
219 | irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) { | ||
220 | |||
221 | if (irq >= nr_irqs) { | 219 | if (irq >= nr_irqs) { |
222 | irq = HPET_MAX_IRQ; | 220 | irq = HPET_MAX_IRQ; |
223 | break; | 221 | break; |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 465185fc0f52..ba55bba151b9 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -312,6 +312,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
312 | spin_lock_irqsave(&hp->lock, flags); | 312 | spin_lock_irqsave(&hp->lock, flags); |
313 | /* Check and then increment for fast path open. */ | 313 | /* Check and then increment for fast path open. */ |
314 | if (hp->count++ > 0) { | 314 | if (hp->count++ > 0) { |
315 | tty_kref_get(tty); | ||
315 | spin_unlock_irqrestore(&hp->lock, flags); | 316 | spin_unlock_irqrestore(&hp->lock, flags); |
316 | hvc_kick(); | 317 | hvc_kick(); |
317 | return 0; | 318 | return 0; |
@@ -319,7 +320,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
319 | 320 | ||
320 | tty->driver_data = hp; | 321 | tty->driver_data = hp; |
321 | 322 | ||
322 | hp->tty = tty; | 323 | hp->tty = tty_kref_get(tty); |
323 | 324 | ||
324 | spin_unlock_irqrestore(&hp->lock, flags); | 325 | spin_unlock_irqrestore(&hp->lock, flags); |
325 | 326 | ||
@@ -336,6 +337,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
336 | spin_lock_irqsave(&hp->lock, flags); | 337 | spin_lock_irqsave(&hp->lock, flags); |
337 | hp->tty = NULL; | 338 | hp->tty = NULL; |
338 | spin_unlock_irqrestore(&hp->lock, flags); | 339 | spin_unlock_irqrestore(&hp->lock, flags); |
340 | tty_kref_put(tty); | ||
339 | tty->driver_data = NULL; | 341 | tty->driver_data = NULL; |
340 | kref_put(&hp->kref, destroy_hvc_struct); | 342 | kref_put(&hp->kref, destroy_hvc_struct); |
341 | printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc); | 343 | printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc); |
@@ -363,13 +365,18 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) | |||
363 | return; | 365 | return; |
364 | 366 | ||
365 | hp = tty->driver_data; | 367 | hp = tty->driver_data; |
368 | |||
366 | spin_lock_irqsave(&hp->lock, flags); | 369 | spin_lock_irqsave(&hp->lock, flags); |
370 | tty_kref_get(tty); | ||
367 | 371 | ||
368 | if (--hp->count == 0) { | 372 | if (--hp->count == 0) { |
369 | /* We are done with the tty pointer now. */ | 373 | /* We are done with the tty pointer now. */ |
370 | hp->tty = NULL; | 374 | hp->tty = NULL; |
371 | spin_unlock_irqrestore(&hp->lock, flags); | 375 | spin_unlock_irqrestore(&hp->lock, flags); |
372 | 376 | ||
377 | /* Put the ref obtained in hvc_open() */ | ||
378 | tty_kref_put(tty); | ||
379 | |||
373 | if (hp->ops->notifier_del) | 380 | if (hp->ops->notifier_del) |
374 | hp->ops->notifier_del(hp, hp->data); | 381 | hp->ops->notifier_del(hp, hp->data); |
375 | 382 | ||
@@ -389,6 +396,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) | |||
389 | spin_unlock_irqrestore(&hp->lock, flags); | 396 | spin_unlock_irqrestore(&hp->lock, flags); |
390 | } | 397 | } |
391 | 398 | ||
399 | tty_kref_put(tty); | ||
392 | kref_put(&hp->kref, destroy_hvc_struct); | 400 | kref_put(&hp->kref, destroy_hvc_struct); |
393 | } | 401 | } |
394 | 402 | ||
@@ -424,10 +432,11 @@ static void hvc_hangup(struct tty_struct *tty) | |||
424 | spin_unlock_irqrestore(&hp->lock, flags); | 432 | spin_unlock_irqrestore(&hp->lock, flags); |
425 | 433 | ||
426 | if (hp->ops->notifier_hangup) | 434 | if (hp->ops->notifier_hangup) |
427 | hp->ops->notifier_hangup(hp, hp->data); | 435 | hp->ops->notifier_hangup(hp, hp->data); |
428 | 436 | ||
429 | while(temp_open_count) { | 437 | while(temp_open_count) { |
430 | --temp_open_count; | 438 | --temp_open_count; |
439 | tty_kref_put(tty); | ||
431 | kref_put(&hp->kref, destroy_hvc_struct); | 440 | kref_put(&hp->kref, destroy_hvc_struct); |
432 | } | 441 | } |
433 | } | 442 | } |
@@ -592,7 +601,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
592 | } | 601 | } |
593 | 602 | ||
594 | /* No tty attached, just skip */ | 603 | /* No tty attached, just skip */ |
595 | tty = hp->tty; | 604 | tty = tty_kref_get(hp->tty); |
596 | if (tty == NULL) | 605 | if (tty == NULL) |
597 | goto bail; | 606 | goto bail; |
598 | 607 | ||
@@ -672,6 +681,8 @@ int hvc_poll(struct hvc_struct *hp) | |||
672 | 681 | ||
673 | tty_flip_buffer_push(tty); | 682 | tty_flip_buffer_push(tty); |
674 | } | 683 | } |
684 | if (tty) | ||
685 | tty_kref_put(tty); | ||
675 | 686 | ||
676 | return poll_mask; | 687 | return poll_mask; |
677 | } | 688 | } |
@@ -807,7 +818,7 @@ int hvc_remove(struct hvc_struct *hp) | |||
807 | struct tty_struct *tty; | 818 | struct tty_struct *tty; |
808 | 819 | ||
809 | spin_lock_irqsave(&hp->lock, flags); | 820 | spin_lock_irqsave(&hp->lock, flags); |
810 | tty = hp->tty; | 821 | tty = tty_kref_get(hp->tty); |
811 | 822 | ||
812 | if (hp->index < MAX_NR_HVC_CONSOLES) | 823 | if (hp->index < MAX_NR_HVC_CONSOLES) |
813 | vtermnos[hp->index] = -1; | 824 | vtermnos[hp->index] = -1; |
@@ -819,18 +830,18 @@ int hvc_remove(struct hvc_struct *hp) | |||
819 | /* | 830 | /* |
820 | * We 'put' the instance that was grabbed when the kref instance | 831 | * We 'put' the instance that was grabbed when the kref instance |
821 | * was initialized using kref_init(). Let the last holder of this | 832 | * was initialized using kref_init(). Let the last holder of this |
822 | * kref cause it to be removed, which will probably be the tty_hangup | 833 | * kref cause it to be removed, which will probably be the tty_vhangup |
823 | * below. | 834 | * below. |
824 | */ | 835 | */ |
825 | kref_put(&hp->kref, destroy_hvc_struct); | 836 | kref_put(&hp->kref, destroy_hvc_struct); |
826 | 837 | ||
827 | /* | 838 | /* |
828 | * This function call will auto chain call hvc_hangup. The tty should | 839 | * This function call will auto chain call hvc_hangup. |
829 | * always be valid at this time unless a simultaneous tty close already | ||
830 | * cleaned up the hvc_struct. | ||
831 | */ | 840 | */ |
832 | if (tty) | 841 | if (tty) { |
833 | tty_hangup(tty); | 842 | tty_vhangup(tty); |
843 | tty_kref_put(tty); | ||
844 | } | ||
834 | return 0; | 845 | return 0; |
835 | } | 846 | } |
836 | EXPORT_SYMBOL_GPL(hvc_remove); | 847 | EXPORT_SYMBOL_GPL(hvc_remove); |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index ec5e3f8df648..c6ad4234378d 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -2272,42 +2272,52 @@ static int create_files(struct bmc_device *bmc) | |||
2272 | bmc->device_id_attr.attr.name = "device_id"; | 2272 | bmc->device_id_attr.attr.name = "device_id"; |
2273 | bmc->device_id_attr.attr.mode = S_IRUGO; | 2273 | bmc->device_id_attr.attr.mode = S_IRUGO; |
2274 | bmc->device_id_attr.show = device_id_show; | 2274 | bmc->device_id_attr.show = device_id_show; |
2275 | sysfs_attr_init(&bmc->device_id_attr.attr); | ||
2275 | 2276 | ||
2276 | bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs"; | 2277 | bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs"; |
2277 | bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; | 2278 | bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; |
2278 | bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; | 2279 | bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; |
2280 | sysfs_attr_init(&bmc->provides_dev_sdrs_attr.attr); | ||
2279 | 2281 | ||
2280 | bmc->revision_attr.attr.name = "revision"; | 2282 | bmc->revision_attr.attr.name = "revision"; |
2281 | bmc->revision_attr.attr.mode = S_IRUGO; | 2283 | bmc->revision_attr.attr.mode = S_IRUGO; |
2282 | bmc->revision_attr.show = revision_show; | 2284 | bmc->revision_attr.show = revision_show; |
2285 | sysfs_attr_init(&bmc->revision_attr.attr); | ||
2283 | 2286 | ||
2284 | bmc->firmware_rev_attr.attr.name = "firmware_revision"; | 2287 | bmc->firmware_rev_attr.attr.name = "firmware_revision"; |
2285 | bmc->firmware_rev_attr.attr.mode = S_IRUGO; | 2288 | bmc->firmware_rev_attr.attr.mode = S_IRUGO; |
2286 | bmc->firmware_rev_attr.show = firmware_rev_show; | 2289 | bmc->firmware_rev_attr.show = firmware_rev_show; |
2290 | sysfs_attr_init(&bmc->firmware_rev_attr.attr); | ||
2287 | 2291 | ||
2288 | bmc->version_attr.attr.name = "ipmi_version"; | 2292 | bmc->version_attr.attr.name = "ipmi_version"; |
2289 | bmc->version_attr.attr.mode = S_IRUGO; | 2293 | bmc->version_attr.attr.mode = S_IRUGO; |
2290 | bmc->version_attr.show = ipmi_version_show; | 2294 | bmc->version_attr.show = ipmi_version_show; |
2295 | sysfs_attr_init(&bmc->version_attr.attr); | ||
2291 | 2296 | ||
2292 | bmc->add_dev_support_attr.attr.name = "additional_device_support"; | 2297 | bmc->add_dev_support_attr.attr.name = "additional_device_support"; |
2293 | bmc->add_dev_support_attr.attr.mode = S_IRUGO; | 2298 | bmc->add_dev_support_attr.attr.mode = S_IRUGO; |
2294 | bmc->add_dev_support_attr.show = add_dev_support_show; | 2299 | bmc->add_dev_support_attr.show = add_dev_support_show; |
2300 | sysfs_attr_init(&bmc->add_dev_support_attr.attr); | ||
2295 | 2301 | ||
2296 | bmc->manufacturer_id_attr.attr.name = "manufacturer_id"; | 2302 | bmc->manufacturer_id_attr.attr.name = "manufacturer_id"; |
2297 | bmc->manufacturer_id_attr.attr.mode = S_IRUGO; | 2303 | bmc->manufacturer_id_attr.attr.mode = S_IRUGO; |
2298 | bmc->manufacturer_id_attr.show = manufacturer_id_show; | 2304 | bmc->manufacturer_id_attr.show = manufacturer_id_show; |
2305 | sysfs_attr_init(&bmc->manufacturer_id_attr.attr); | ||
2299 | 2306 | ||
2300 | bmc->product_id_attr.attr.name = "product_id"; | 2307 | bmc->product_id_attr.attr.name = "product_id"; |
2301 | bmc->product_id_attr.attr.mode = S_IRUGO; | 2308 | bmc->product_id_attr.attr.mode = S_IRUGO; |
2302 | bmc->product_id_attr.show = product_id_show; | 2309 | bmc->product_id_attr.show = product_id_show; |
2310 | sysfs_attr_init(&bmc->product_id_attr.attr); | ||
2303 | 2311 | ||
2304 | bmc->guid_attr.attr.name = "guid"; | 2312 | bmc->guid_attr.attr.name = "guid"; |
2305 | bmc->guid_attr.attr.mode = S_IRUGO; | 2313 | bmc->guid_attr.attr.mode = S_IRUGO; |
2306 | bmc->guid_attr.show = guid_show; | 2314 | bmc->guid_attr.show = guid_show; |
2315 | sysfs_attr_init(&bmc->guid_attr.attr); | ||
2307 | 2316 | ||
2308 | bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision"; | 2317 | bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision"; |
2309 | bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; | 2318 | bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; |
2310 | bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; | 2319 | bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; |
2320 | sysfs_attr_init(&bmc->aux_firmware_rev_attr.attr); | ||
2311 | 2321 | ||
2312 | err = device_create_file(&bmc->dev->dev, | 2322 | err = device_create_file(&bmc->dev->dev, |
2313 | &bmc->device_id_attr); | 2323 | &bmc->device_id_attr); |
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c index af8d97715728..7ee52164d474 100644 --- a/drivers/char/tty_buffer.c +++ b/drivers/char/tty_buffer.c | |||
@@ -248,7 +248,7 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, | |||
248 | { | 248 | { |
249 | int copied = 0; | 249 | int copied = 0; |
250 | do { | 250 | do { |
251 | int goal = min(size - copied, TTY_BUFFER_PAGE); | 251 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); |
252 | int space = tty_buffer_request_room(tty, goal); | 252 | int space = tty_buffer_request_room(tty, goal); |
253 | struct tty_buffer *tb = tty->buf.tail; | 253 | struct tty_buffer *tb = tty->buf.tail; |
254 | /* If there is no space then tb may be NULL */ | 254 | /* If there is no space then tb may be NULL */ |
@@ -285,7 +285,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, | |||
285 | { | 285 | { |
286 | int copied = 0; | 286 | int copied = 0; |
287 | do { | 287 | do { |
288 | int goal = min(size - copied, TTY_BUFFER_PAGE); | 288 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); |
289 | int space = tty_buffer_request_room(tty, goal); | 289 | int space = tty_buffer_request_room(tty, goal); |
290 | struct tty_buffer *tb = tty->buf.tail; | 290 | struct tty_buffer *tb = tty->buf.tail; |
291 | /* If there is no space then tb may be NULL */ | 291 | /* If there is no space then tb may be NULL */ |
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c index be492dd66437..a3bd1d0b66cf 100644 --- a/drivers/char/tty_port.c +++ b/drivers/char/tty_port.c | |||
@@ -119,7 +119,7 @@ EXPORT_SYMBOL(tty_port_tty_set); | |||
119 | static void tty_port_shutdown(struct tty_port *port) | 119 | static void tty_port_shutdown(struct tty_port *port) |
120 | { | 120 | { |
121 | mutex_lock(&port->mutex); | 121 | mutex_lock(&port->mutex); |
122 | if (port->ops->shutdown && | 122 | if (port->ops->shutdown && !port->console && |
123 | test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) | 123 | test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) |
124 | port->ops->shutdown(port); | 124 | port->ops->shutdown(port); |
125 | mutex_unlock(&port->mutex); | 125 | mutex_unlock(&port->mutex); |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index f404ccfc9c20..44288ce0cb45 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -681,6 +681,10 @@ static void resize_console(struct port *port) | |||
681 | struct virtio_device *vdev; | 681 | struct virtio_device *vdev; |
682 | struct winsize ws; | 682 | struct winsize ws; |
683 | 683 | ||
684 | /* The port could have been hot-unplugged */ | ||
685 | if (!port) | ||
686 | return; | ||
687 | |||
684 | vdev = port->portdev->vdev; | 688 | vdev = port->portdev->vdev; |
685 | if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) { | 689 | if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) { |
686 | vdev->config->get(vdev, | 690 | vdev->config->get(vdev, |
@@ -947,11 +951,18 @@ static void handle_control_message(struct ports_device *portdev, | |||
947 | */ | 951 | */ |
948 | err = sysfs_create_group(&port->dev->kobj, | 952 | err = sysfs_create_group(&port->dev->kobj, |
949 | &port_attribute_group); | 953 | &port_attribute_group); |
950 | if (err) | 954 | if (err) { |
951 | dev_err(port->dev, | 955 | dev_err(port->dev, |
952 | "Error %d creating sysfs device attributes\n", | 956 | "Error %d creating sysfs device attributes\n", |
953 | err); | 957 | err); |
954 | 958 | } else { | |
959 | /* | ||
960 | * Generate a udev event so that appropriate | ||
961 | * symlinks can be created based on udev | ||
962 | * rules. | ||
963 | */ | ||
964 | kobject_uevent(&port->dev->kobj, KOBJ_CHANGE); | ||
965 | } | ||
955 | break; | 966 | break; |
956 | case VIRTIO_CONSOLE_PORT_REMOVE: | 967 | case VIRTIO_CONSOLE_PORT_REMOVE: |
957 | /* | 968 | /* |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 87778dcf8727..6aa10284104a 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -888,7 +888,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
888 | ret = -EFAULT; | 888 | ret = -EFAULT; |
889 | goto out; | 889 | goto out; |
890 | } | 890 | } |
891 | if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS && tmp.mode != VT_PROCESS_AUTO) { | 891 | if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) { |
892 | ret = -EINVAL; | 892 | ret = -EINVAL; |
893 | goto out; | 893 | goto out; |
894 | } | 894 | } |
@@ -1622,7 +1622,7 @@ static void complete_change_console(struct vc_data *vc) | |||
1622 | * telling it that it has acquired. Also check if it has died and | 1622 | * telling it that it has acquired. Also check if it has died and |
1623 | * clean up (similar to logic employed in change_console()) | 1623 | * clean up (similar to logic employed in change_console()) |
1624 | */ | 1624 | */ |
1625 | if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) { | 1625 | if (vc->vt_mode.mode == VT_PROCESS) { |
1626 | /* | 1626 | /* |
1627 | * Send the signal as privileged - kill_pid() will | 1627 | * Send the signal as privileged - kill_pid() will |
1628 | * tell us if the process has gone or something else | 1628 | * tell us if the process has gone or something else |
@@ -1682,7 +1682,7 @@ void change_console(struct vc_data *new_vc) | |||
1682 | * vt to auto control. | 1682 | * vt to auto control. |
1683 | */ | 1683 | */ |
1684 | vc = vc_cons[fg_console].d; | 1684 | vc = vc_cons[fg_console].d; |
1685 | if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) { | 1685 | if (vc->vt_mode.mode == VT_PROCESS) { |
1686 | /* | 1686 | /* |
1687 | * Send the signal as privileged - kill_pid() will | 1687 | * Send the signal as privileged - kill_pid() will |
1688 | * tell us if the process has gone or something else | 1688 | * tell us if the process has gone or something else |
@@ -1693,28 +1693,27 @@ void change_console(struct vc_data *new_vc) | |||
1693 | */ | 1693 | */ |
1694 | vc->vt_newvt = new_vc->vc_num; | 1694 | vc->vt_newvt = new_vc->vc_num; |
1695 | if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { | 1695 | if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { |
1696 | if(vc->vt_mode.mode == VT_PROCESS) | ||
1697 | /* | ||
1698 | * It worked. Mark the vt to switch to and | ||
1699 | * return. The process needs to send us a | ||
1700 | * VT_RELDISP ioctl to complete the switch. | ||
1701 | */ | ||
1702 | return; | ||
1703 | } else { | ||
1704 | /* | 1696 | /* |
1705 | * The controlling process has died, so we revert back to | 1697 | * It worked. Mark the vt to switch to and |
1706 | * normal operation. In this case, we'll also change back | 1698 | * return. The process needs to send us a |
1707 | * to KD_TEXT mode. I'm not sure if this is strictly correct | 1699 | * VT_RELDISP ioctl to complete the switch. |
1708 | * but it saves the agony when the X server dies and the screen | ||
1709 | * remains blanked due to KD_GRAPHICS! It would be nice to do | ||
1710 | * this outside of VT_PROCESS but there is no single process | ||
1711 | * to account for and tracking tty count may be undesirable. | ||
1712 | */ | 1700 | */ |
1713 | reset_vc(vc); | 1701 | return; |
1714 | } | 1702 | } |
1715 | 1703 | ||
1716 | /* | 1704 | /* |
1717 | * Fall through to normal (VT_AUTO and VT_PROCESS_AUTO) handling of the switch... | 1705 | * The controlling process has died, so we revert back to |
1706 | * normal operation. In this case, we'll also change back | ||
1707 | * to KD_TEXT mode. I'm not sure if this is strictly correct | ||
1708 | * but it saves the agony when the X server dies and the screen | ||
1709 | * remains blanked due to KD_GRAPHICS! It would be nice to do | ||
1710 | * this outside of VT_PROCESS but there is no single process | ||
1711 | * to account for and tracking tty count may be undesirable. | ||
1712 | */ | ||
1713 | reset_vc(vc); | ||
1714 | |||
1715 | /* | ||
1716 | * Fall through to normal (VT_AUTO) handling of the switch... | ||
1718 | */ | 1717 | */ |
1719 | } | 1718 | } |
1720 | 1719 | ||
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c index 8fc91a019620..f5b6d9fe4def 100644 --- a/drivers/edac/edac_mce_amd.c +++ b/drivers/edac/edac_mce_amd.c | |||
@@ -316,7 +316,12 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors) | |||
316 | if (regs->nbsh & K8_NBSH_ERR_CPU_VAL) | 316 | if (regs->nbsh & K8_NBSH_ERR_CPU_VAL) |
317 | pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf)); | 317 | pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf)); |
318 | } else { | 318 | } else { |
319 | pr_cont(", core: %d\n", fls((regs->nbsh & 0xf) - 1)); | 319 | u8 assoc_cpus = regs->nbsh & 0xf; |
320 | |||
321 | if (assoc_cpus > 0) | ||
322 | pr_cont(", core: %d", fls(assoc_cpus) - 1); | ||
323 | |||
324 | pr_cont("\n"); | ||
320 | } | 325 | } |
321 | 326 | ||
322 | pr_emerg("%s.\n", EXT_ERR_MSG(xec)); | 327 | pr_emerg("%s.\n", EXT_ERR_MSG(xec)); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 20564f8cb0ec..406228f4a2a0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c | |||
@@ -89,19 +89,21 @@ static struct backlight_ops nv50_bl_ops = { | |||
89 | 89 | ||
90 | static int nouveau_nv40_backlight_init(struct drm_device *dev) | 90 | static int nouveau_nv40_backlight_init(struct drm_device *dev) |
91 | { | 91 | { |
92 | struct backlight_properties props; | ||
92 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 93 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
93 | struct backlight_device *bd; | 94 | struct backlight_device *bd; |
94 | 95 | ||
95 | if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)) | 96 | if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)) |
96 | return 0; | 97 | return 0; |
97 | 98 | ||
99 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
100 | props.max_brightness = 31; | ||
98 | bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev, | 101 | bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev, |
99 | &nv40_bl_ops); | 102 | &nv40_bl_ops, &props); |
100 | if (IS_ERR(bd)) | 103 | if (IS_ERR(bd)) |
101 | return PTR_ERR(bd); | 104 | return PTR_ERR(bd); |
102 | 105 | ||
103 | dev_priv->backlight = bd; | 106 | dev_priv->backlight = bd; |
104 | bd->props.max_brightness = 31; | ||
105 | bd->props.brightness = nv40_get_intensity(bd); | 107 | bd->props.brightness = nv40_get_intensity(bd); |
106 | backlight_update_status(bd); | 108 | backlight_update_status(bd); |
107 | 109 | ||
@@ -110,19 +112,21 @@ static int nouveau_nv40_backlight_init(struct drm_device *dev) | |||
110 | 112 | ||
111 | static int nouveau_nv50_backlight_init(struct drm_device *dev) | 113 | static int nouveau_nv50_backlight_init(struct drm_device *dev) |
112 | { | 114 | { |
115 | struct backlight_properties props; | ||
113 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 116 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
114 | struct backlight_device *bd; | 117 | struct backlight_device *bd; |
115 | 118 | ||
116 | if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT)) | 119 | if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT)) |
117 | return 0; | 120 | return 0; |
118 | 121 | ||
122 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
123 | props.max_brightness = 1025; | ||
119 | bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev, | 124 | bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev, |
120 | &nv50_bl_ops); | 125 | &nv50_bl_ops, &props); |
121 | if (IS_ERR(bd)) | 126 | if (IS_ERR(bd)) |
122 | return PTR_ERR(bd); | 127 | return PTR_ERR(bd); |
123 | 128 | ||
124 | dev_priv->backlight = bd; | 129 | dev_priv->backlight = bd; |
125 | bd->props.max_brightness = 1025; | ||
126 | bd->props.brightness = nv50_get_intensity(bd); | 130 | bd->props.brightness = nv50_get_intensity(bd); |
127 | backlight_update_status(bd); | 131 | backlight_update_status(bd); |
128 | return 0; | 132 | return 0; |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 368fbb0c4ca6..2e2aa759d230 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1357,6 +1357,7 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1357 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, | 1357 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, |
1358 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) }, | 1358 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) }, |
1359 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, | 1359 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, |
1360 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) }, | ||
1360 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, | 1361 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, |
1361 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, | 1362 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, |
1362 | { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, | 1363 | { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, |
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index cd4ece6fdfb9..0c4e75573186 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c | |||
@@ -564,10 +564,10 @@ void hid_debug_event(struct hid_device *hdev, char *buf) | |||
564 | struct hid_debug_list *list; | 564 | struct hid_debug_list *list; |
565 | 565 | ||
566 | list_for_each_entry(list, &hdev->debug_list, node) { | 566 | list_for_each_entry(list, &hdev->debug_list, node) { |
567 | for (i = 0; i <= strlen(buf); i++) | 567 | for (i = 0; i < strlen(buf); i++) |
568 | list->hid_debug_buf[(list->tail + i) % (HID_DEBUG_BUFSIZE - 1)] = | 568 | list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] = |
569 | buf[i]; | 569 | buf[i]; |
570 | list->tail = (list->tail + i) % (HID_DEBUG_BUFSIZE - 1); | 570 | list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE; |
571 | } | 571 | } |
572 | } | 572 | } |
573 | EXPORT_SYMBOL_GPL(hid_debug_event); | 573 | EXPORT_SYMBOL_GPL(hid_debug_event); |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 72c05f90553c..797e06470356 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -445,6 +445,7 @@ | |||
445 | 445 | ||
446 | #define USB_VENDOR_ID_UCLOGIC 0x5543 | 446 | #define USB_VENDOR_ID_UCLOGIC 0x5543 |
447 | #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 | 447 | #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 |
448 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 | ||
448 | 449 | ||
449 | #define USB_VENDOR_ID_VERNIER 0x08f7 | 450 | #define USB_VENDOR_ID_VERNIER 0x08f7 |
450 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 | 451 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 |
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 4a3a94f2b10c..c174b64c3810 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c | |||
@@ -353,7 +353,7 @@ static int magicmouse_probe(struct hid_device *hdev, | |||
353 | goto err_free; | 353 | goto err_free; |
354 | } | 354 | } |
355 | 355 | ||
356 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 356 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT); |
357 | if (ret) { | 357 | if (ret) { |
358 | dev_err(&hdev->dev, "magicmouse hw start failed\n"); | 358 | dev_err(&hdev->dev, "magicmouse hw start failed\n"); |
359 | goto err_free; | 359 | goto err_free; |
@@ -409,8 +409,11 @@ err_free: | |||
409 | 409 | ||
410 | static void magicmouse_remove(struct hid_device *hdev) | 410 | static void magicmouse_remove(struct hid_device *hdev) |
411 | { | 411 | { |
412 | struct magicmouse_sc *msc = hid_get_drvdata(hdev); | ||
413 | |||
412 | hid_hw_stop(hdev); | 414 | hid_hw_stop(hdev); |
413 | kfree(hid_get_drvdata(hdev)); | 415 | input_unregister_device(msc->input); |
416 | kfree(msc); | ||
414 | } | 417 | } |
415 | 418 | ||
416 | static const struct hid_device_id magic_mice[] = { | 419 | static const struct hid_device_id magic_mice[] = { |
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 3234c729a895..edcc0c4247bb 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c | |||
@@ -140,6 +140,9 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, | |||
140 | nd->reading_mt = 1; | 140 | nd->reading_mt = 1; |
141 | nd->first_contact_confidence = 0; | 141 | nd->first_contact_confidence = 0; |
142 | break; | 142 | break; |
143 | case HID_DG_TIPSWITCH: | ||
144 | /* Prevent emission of touch until validated */ | ||
145 | return 1; | ||
143 | case HID_DG_CONFIDENCE: | 146 | case HID_DG_CONFIDENCE: |
144 | nd->confidence = value; | 147 | nd->confidence = value; |
145 | break; | 148 | break; |
@@ -259,6 +262,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, | |||
259 | BTN_TOOL_TRIPLETAP, 0); | 262 | BTN_TOOL_TRIPLETAP, 0); |
260 | input_report_key(input, | 263 | input_report_key(input, |
261 | BTN_TOOL_QUADTAP, 0); | 264 | BTN_TOOL_QUADTAP, 0); |
265 | input_report_key(input, BTN_TOUCH, 0); | ||
262 | } | 266 | } |
263 | break; | 267 | break; |
264 | 268 | ||
@@ -308,13 +312,20 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
308 | 312 | ||
309 | 313 | ||
310 | list_for_each_entry(hidinput, &hdev->inputs, list) { | 314 | list_for_each_entry(hidinput, &hdev->inputs, list) { |
315 | if (hidinput->report->maxfield < 1) | ||
316 | continue; | ||
317 | |||
311 | input = hidinput->input; | 318 | input = hidinput->input; |
312 | switch (hidinput->report->field[0]->application) { | 319 | switch (hidinput->report->field[0]->application) { |
313 | case HID_DG_PEN: | 320 | case HID_DG_PEN: |
314 | input->name = "N-Trig Pen"; | 321 | input->name = "N-Trig Pen"; |
315 | break; | 322 | break; |
316 | case HID_DG_TOUCHSCREEN: | 323 | case HID_DG_TOUCHSCREEN: |
324 | /* These keys are redundant for fingers, clear them | ||
325 | * to prevent incorrect identification */ | ||
317 | __clear_bit(BTN_TOOL_PEN, input->keybit); | 326 | __clear_bit(BTN_TOOL_PEN, input->keybit); |
327 | __clear_bit(BTN_TOOL_FINGER, input->keybit); | ||
328 | __clear_bit(BTN_0, input->keybit); | ||
318 | /* | 329 | /* |
319 | * A little something special to enable | 330 | * A little something special to enable |
320 | * two and three finger taps. | 331 | * two and three finger taps. |
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c index 167ea746fb9c..c32f32c84ac8 100644 --- a/drivers/hid/hid-tmff.c +++ b/drivers/hid/hid-tmff.c | |||
@@ -251,6 +251,8 @@ static const struct hid_device_id tm_devices[] = { | |||
251 | .driver_data = (unsigned long)ff_rumble }, | 251 | .driver_data = (unsigned long)ff_rumble }, |
252 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651), /* FGT Rumble Force Wheel */ | 252 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651), /* FGT Rumble Force Wheel */ |
253 | .driver_data = (unsigned long)ff_rumble }, | 253 | .driver_data = (unsigned long)ff_rumble }, |
254 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653), /* RGT Force Feedback CLUTCH Raging Wheel */ | ||
255 | .driver_data = (unsigned long)ff_joystick }, | ||
254 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */ | 256 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */ |
255 | .driver_data = (unsigned long)ff_joystick }, | 257 | .driver_data = (unsigned long)ff_joystick }, |
256 | { } | 258 | { } |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 7844280897d1..928943c7ce9a 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -63,6 +63,7 @@ static const struct hid_blacklist { | |||
63 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, | 63 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, |
64 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, | 64 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, |
65 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, | 65 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, |
66 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, | ||
66 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, | 67 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, |
67 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 68 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
68 | 69 | ||
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 1558bb7fc74d..f901957abc8b 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c | |||
@@ -461,6 +461,7 @@ alloc_group_attrs(ssize_t (*show)(struct ib_port *, | |||
461 | element->attr.attr.mode = S_IRUGO; | 461 | element->attr.attr.mode = S_IRUGO; |
462 | element->attr.show = show; | 462 | element->attr.show = show; |
463 | element->index = i; | 463 | element->index = i; |
464 | sysfs_attr_init(&element->attr.attr); | ||
464 | 465 | ||
465 | tab_attr[i] = &element->attr.attr; | 466 | tab_attr[i] = &element->attr.attr; |
466 | } | 467 | } |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 71237f8f78f7..e78af36d3a0e 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
@@ -613,7 +613,7 @@ static struct scsi_host_template iscsi_iser_sht = { | |||
613 | .cmd_per_lun = ISER_DEF_CMD_PER_LUN, | 613 | .cmd_per_lun = ISER_DEF_CMD_PER_LUN, |
614 | .eh_abort_handler = iscsi_eh_abort, | 614 | .eh_abort_handler = iscsi_eh_abort, |
615 | .eh_device_reset_handler= iscsi_eh_device_reset, | 615 | .eh_device_reset_handler= iscsi_eh_device_reset, |
616 | .eh_target_reset_handler= iscsi_eh_target_reset, | 616 | .eh_target_reset_handler = iscsi_eh_recover_target, |
617 | .target_alloc = iscsi_target_alloc, | 617 | .target_alloc = iscsi_target_alloc, |
618 | .use_clustering = DISABLE_CLUSTERING, | 618 | .use_clustering = DISABLE_CLUSTERING, |
619 | .proc_name = "iscsi_iser", | 619 | .proc_name = "iscsi_iser", |
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index e5deb15cf40c..8d1d63a02b34 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c | |||
@@ -50,7 +50,7 @@ module_param(isdnprot, int, 0); | |||
50 | handler. | 50 | handler. |
51 | */ | 51 | */ |
52 | 52 | ||
53 | static int avma1cs_config(struct pcmcia_device *link); | 53 | static int avma1cs_config(struct pcmcia_device *link) __devinit ; |
54 | static void avma1cs_release(struct pcmcia_device *link); | 54 | static void avma1cs_release(struct pcmcia_device *link); |
55 | 55 | ||
56 | /* | 56 | /* |
@@ -59,7 +59,7 @@ static void avma1cs_release(struct pcmcia_device *link); | |||
59 | needed to manage one actual PCMCIA card. | 59 | needed to manage one actual PCMCIA card. |
60 | */ | 60 | */ |
61 | 61 | ||
62 | static void avma1cs_detach(struct pcmcia_device *p_dev); | 62 | static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ; |
63 | 63 | ||
64 | 64 | ||
65 | /* | 65 | /* |
@@ -99,7 +99,7 @@ typedef struct local_info_t { | |||
99 | 99 | ||
100 | ======================================================================*/ | 100 | ======================================================================*/ |
101 | 101 | ||
102 | static int avma1cs_probe(struct pcmcia_device *p_dev) | 102 | static int __devinit avma1cs_probe(struct pcmcia_device *p_dev) |
103 | { | 103 | { |
104 | local_info_t *local; | 104 | local_info_t *local; |
105 | 105 | ||
@@ -140,7 +140,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev) | |||
140 | 140 | ||
141 | ======================================================================*/ | 141 | ======================================================================*/ |
142 | 142 | ||
143 | static void avma1cs_detach(struct pcmcia_device *link) | 143 | static void __devexit avma1cs_detach(struct pcmcia_device *link) |
144 | { | 144 | { |
145 | dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link); | 145 | dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link); |
146 | avma1cs_release(link); | 146 | avma1cs_release(link); |
@@ -174,7 +174,7 @@ static int avma1cs_configcheck(struct pcmcia_device *p_dev, | |||
174 | } | 174 | } |
175 | 175 | ||
176 | 176 | ||
177 | static int avma1cs_config(struct pcmcia_device *link) | 177 | static int __devinit avma1cs_config(struct pcmcia_device *link) |
178 | { | 178 | { |
179 | local_info_t *dev; | 179 | local_info_t *dev; |
180 | int i; | 180 | int i; |
@@ -282,7 +282,7 @@ static struct pcmcia_driver avma1cs_driver = { | |||
282 | .name = "avma1_cs", | 282 | .name = "avma1_cs", |
283 | }, | 283 | }, |
284 | .probe = avma1cs_probe, | 284 | .probe = avma1cs_probe, |
285 | .remove = avma1cs_detach, | 285 | .remove = __devexit_p(avma1cs_detach), |
286 | .id_table = avma1cs_ids, | 286 | .id_table = avma1cs_ids, |
287 | }; | 287 | }; |
288 | 288 | ||
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index c9a30b1c9237..c9f2279e21f5 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c | |||
@@ -76,7 +76,7 @@ module_param(protocol, int, 0); | |||
76 | handler. | 76 | handler. |
77 | */ | 77 | */ |
78 | 78 | ||
79 | static int elsa_cs_config(struct pcmcia_device *link); | 79 | static int elsa_cs_config(struct pcmcia_device *link) __devinit ; |
80 | static void elsa_cs_release(struct pcmcia_device *link); | 80 | static void elsa_cs_release(struct pcmcia_device *link); |
81 | 81 | ||
82 | /* | 82 | /* |
@@ -85,7 +85,7 @@ static void elsa_cs_release(struct pcmcia_device *link); | |||
85 | needed to manage one actual PCMCIA card. | 85 | needed to manage one actual PCMCIA card. |
86 | */ | 86 | */ |
87 | 87 | ||
88 | static void elsa_cs_detach(struct pcmcia_device *p_dev); | 88 | static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit; |
89 | 89 | ||
90 | /* | 90 | /* |
91 | A driver needs to provide a dev_node_t structure for each device | 91 | A driver needs to provide a dev_node_t structure for each device |
@@ -121,7 +121,7 @@ typedef struct local_info_t { | |||
121 | 121 | ||
122 | ======================================================================*/ | 122 | ======================================================================*/ |
123 | 123 | ||
124 | static int elsa_cs_probe(struct pcmcia_device *link) | 124 | static int __devinit elsa_cs_probe(struct pcmcia_device *link) |
125 | { | 125 | { |
126 | local_info_t *local; | 126 | local_info_t *local; |
127 | 127 | ||
@@ -166,7 +166,7 @@ static int elsa_cs_probe(struct pcmcia_device *link) | |||
166 | 166 | ||
167 | ======================================================================*/ | 167 | ======================================================================*/ |
168 | 168 | ||
169 | static void elsa_cs_detach(struct pcmcia_device *link) | 169 | static void __devexit elsa_cs_detach(struct pcmcia_device *link) |
170 | { | 170 | { |
171 | local_info_t *info = link->priv; | 171 | local_info_t *info = link->priv; |
172 | 172 | ||
@@ -210,7 +210,7 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev, | |||
210 | return -ENODEV; | 210 | return -ENODEV; |
211 | } | 211 | } |
212 | 212 | ||
213 | static int elsa_cs_config(struct pcmcia_device *link) | 213 | static int __devinit elsa_cs_config(struct pcmcia_device *link) |
214 | { | 214 | { |
215 | local_info_t *dev; | 215 | local_info_t *dev; |
216 | int i; | 216 | int i; |
@@ -327,7 +327,7 @@ static struct pcmcia_driver elsa_cs_driver = { | |||
327 | .name = "elsa_cs", | 327 | .name = "elsa_cs", |
328 | }, | 328 | }, |
329 | .probe = elsa_cs_probe, | 329 | .probe = elsa_cs_probe, |
330 | .remove = elsa_cs_detach, | 330 | .remove = __devexit_p(elsa_cs_detach), |
331 | .id_table = elsa_ids, | 331 | .id_table = elsa_ids, |
332 | .suspend = elsa_suspend, | 332 | .suspend = elsa_suspend, |
333 | .resume = elsa_resume, | 333 | .resume = elsa_resume, |
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 7836ec3c7f86..71b3ddef03bb 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c | |||
@@ -76,7 +76,7 @@ module_param(protocol, int, 0); | |||
76 | event handler. | 76 | event handler. |
77 | */ | 77 | */ |
78 | 78 | ||
79 | static int sedlbauer_config(struct pcmcia_device *link); | 79 | static int sedlbauer_config(struct pcmcia_device *link) __devinit ; |
80 | static void sedlbauer_release(struct pcmcia_device *link); | 80 | static void sedlbauer_release(struct pcmcia_device *link); |
81 | 81 | ||
82 | /* | 82 | /* |
@@ -85,7 +85,7 @@ static void sedlbauer_release(struct pcmcia_device *link); | |||
85 | needed to manage one actual PCMCIA card. | 85 | needed to manage one actual PCMCIA card. |
86 | */ | 86 | */ |
87 | 87 | ||
88 | static void sedlbauer_detach(struct pcmcia_device *p_dev); | 88 | static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit; |
89 | 89 | ||
90 | /* | 90 | /* |
91 | You'll also need to prototype all the functions that will actually | 91 | You'll also need to prototype all the functions that will actually |
@@ -129,7 +129,7 @@ typedef struct local_info_t { | |||
129 | 129 | ||
130 | ======================================================================*/ | 130 | ======================================================================*/ |
131 | 131 | ||
132 | static int sedlbauer_probe(struct pcmcia_device *link) | 132 | static int __devinit sedlbauer_probe(struct pcmcia_device *link) |
133 | { | 133 | { |
134 | local_info_t *local; | 134 | local_info_t *local; |
135 | 135 | ||
@@ -177,7 +177,7 @@ static int sedlbauer_probe(struct pcmcia_device *link) | |||
177 | 177 | ||
178 | ======================================================================*/ | 178 | ======================================================================*/ |
179 | 179 | ||
180 | static void sedlbauer_detach(struct pcmcia_device *link) | 180 | static void __devexit sedlbauer_detach(struct pcmcia_device *link) |
181 | { | 181 | { |
182 | dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link); | 182 | dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link); |
183 | 183 | ||
@@ -283,7 +283,7 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev, | |||
283 | 283 | ||
284 | 284 | ||
285 | 285 | ||
286 | static int sedlbauer_config(struct pcmcia_device *link) | 286 | static int __devinit sedlbauer_config(struct pcmcia_device *link) |
287 | { | 287 | { |
288 | local_info_t *dev = link->priv; | 288 | local_info_t *dev = link->priv; |
289 | win_req_t *req; | 289 | win_req_t *req; |
@@ -441,7 +441,7 @@ static struct pcmcia_driver sedlbauer_driver = { | |||
441 | .name = "sedlbauer_cs", | 441 | .name = "sedlbauer_cs", |
442 | }, | 442 | }, |
443 | .probe = sedlbauer_probe, | 443 | .probe = sedlbauer_probe, |
444 | .remove = sedlbauer_detach, | 444 | .remove = __devexit_p(sedlbauer_detach), |
445 | .id_table = sedlbauer_ids, | 445 | .id_table = sedlbauer_ids, |
446 | .suspend = sedlbauer_suspend, | 446 | .suspend = sedlbauer_suspend, |
447 | .resume = sedlbauer_resume, | 447 | .resume = sedlbauer_resume, |
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index b0c5976cbdb3..d010a0da8e19 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c | |||
@@ -57,7 +57,7 @@ module_param(protocol, int, 0); | |||
57 | handler. | 57 | handler. |
58 | */ | 58 | */ |
59 | 59 | ||
60 | static int teles_cs_config(struct pcmcia_device *link); | 60 | static int teles_cs_config(struct pcmcia_device *link) __devinit ; |
61 | static void teles_cs_release(struct pcmcia_device *link); | 61 | static void teles_cs_release(struct pcmcia_device *link); |
62 | 62 | ||
63 | /* | 63 | /* |
@@ -66,7 +66,7 @@ static void teles_cs_release(struct pcmcia_device *link); | |||
66 | needed to manage one actual PCMCIA card. | 66 | needed to manage one actual PCMCIA card. |
67 | */ | 67 | */ |
68 | 68 | ||
69 | static void teles_detach(struct pcmcia_device *p_dev); | 69 | static void teles_detach(struct pcmcia_device *p_dev) __devexit ; |
70 | 70 | ||
71 | /* | 71 | /* |
72 | A linked list of "instances" of the teles_cs device. Each actual | 72 | A linked list of "instances" of the teles_cs device. Each actual |
@@ -112,7 +112,7 @@ typedef struct local_info_t { | |||
112 | 112 | ||
113 | ======================================================================*/ | 113 | ======================================================================*/ |
114 | 114 | ||
115 | static int teles_probe(struct pcmcia_device *link) | 115 | static int __devinit teles_probe(struct pcmcia_device *link) |
116 | { | 116 | { |
117 | local_info_t *local; | 117 | local_info_t *local; |
118 | 118 | ||
@@ -156,7 +156,7 @@ static int teles_probe(struct pcmcia_device *link) | |||
156 | 156 | ||
157 | ======================================================================*/ | 157 | ======================================================================*/ |
158 | 158 | ||
159 | static void teles_detach(struct pcmcia_device *link) | 159 | static void __devexit teles_detach(struct pcmcia_device *link) |
160 | { | 160 | { |
161 | local_info_t *info = link->priv; | 161 | local_info_t *info = link->priv; |
162 | 162 | ||
@@ -200,7 +200,7 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev, | |||
200 | return -ENODEV; | 200 | return -ENODEV; |
201 | } | 201 | } |
202 | 202 | ||
203 | static int teles_cs_config(struct pcmcia_device *link) | 203 | static int __devinit teles_cs_config(struct pcmcia_device *link) |
204 | { | 204 | { |
205 | local_info_t *dev; | 205 | local_info_t *dev; |
206 | int i; | 206 | int i; |
@@ -319,7 +319,7 @@ static struct pcmcia_driver teles_cs_driver = { | |||
319 | .name = "teles_cs", | 319 | .name = "teles_cs", |
320 | }, | 320 | }, |
321 | .probe = teles_probe, | 321 | .probe = teles_probe, |
322 | .remove = teles_detach, | 322 | .remove = __devexit_p(teles_detach), |
323 | .id_table = teles_ids, | 323 | .id_table = teles_ids, |
324 | .suspend = teles_suspend, | 324 | .suspend = teles_suspend, |
325 | .resume = teles_resume, | 325 | .resume = teles_resume, |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index e0b64312e66a..505eb64c329c 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -15,6 +15,8 @@ config LEDS_CLASS | |||
15 | This option enables the led sysfs class in /sys/class/leds. You'll | 15 | This option enables the led sysfs class in /sys/class/leds. You'll |
16 | need this to do anything useful with LEDs. If unsure, say N. | 16 | need this to do anything useful with LEDs. If unsure, say N. |
17 | 17 | ||
18 | if LEDS_CLASS | ||
19 | |||
18 | comment "LED drivers" | 20 | comment "LED drivers" |
19 | 21 | ||
20 | config LEDS_88PM860X | 22 | config LEDS_88PM860X |
@@ -26,73 +28,73 @@ config LEDS_88PM860X | |||
26 | 28 | ||
27 | config LEDS_ATMEL_PWM | 29 | config LEDS_ATMEL_PWM |
28 | tristate "LED Support using Atmel PWM outputs" | 30 | tristate "LED Support using Atmel PWM outputs" |
29 | depends on LEDS_CLASS && ATMEL_PWM | 31 | depends on ATMEL_PWM |
30 | help | 32 | help |
31 | This option enables support for LEDs driven using outputs | 33 | This option enables support for LEDs driven using outputs |
32 | of the dedicated PWM controller found on newer Atmel SOCs. | 34 | of the dedicated PWM controller found on newer Atmel SOCs. |
33 | 35 | ||
34 | config LEDS_LOCOMO | 36 | config LEDS_LOCOMO |
35 | tristate "LED Support for Locomo device" | 37 | tristate "LED Support for Locomo device" |
36 | depends on LEDS_CLASS && SHARP_LOCOMO | 38 | depends on SHARP_LOCOMO |
37 | help | 39 | help |
38 | This option enables support for the LEDs on Sharp Locomo. | 40 | This option enables support for the LEDs on Sharp Locomo. |
39 | Zaurus models SL-5500 and SL-5600. | 41 | Zaurus models SL-5500 and SL-5600. |
40 | 42 | ||
41 | config LEDS_MIKROTIK_RB532 | 43 | config LEDS_MIKROTIK_RB532 |
42 | tristate "LED Support for Mikrotik Routerboard 532" | 44 | tristate "LED Support for Mikrotik Routerboard 532" |
43 | depends on LEDS_CLASS && MIKROTIK_RB532 | 45 | depends on MIKROTIK_RB532 |
44 | help | 46 | help |
45 | This option enables support for the so called "User LED" of | 47 | This option enables support for the so called "User LED" of |
46 | Mikrotik's Routerboard 532. | 48 | Mikrotik's Routerboard 532. |
47 | 49 | ||
48 | config LEDS_S3C24XX | 50 | config LEDS_S3C24XX |
49 | tristate "LED Support for Samsung S3C24XX GPIO LEDs" | 51 | tristate "LED Support for Samsung S3C24XX GPIO LEDs" |
50 | depends on LEDS_CLASS && ARCH_S3C2410 | 52 | depends on ARCH_S3C2410 |
51 | help | 53 | help |
52 | This option enables support for LEDs connected to GPIO lines | 54 | This option enables support for LEDs connected to GPIO lines |
53 | on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440. | 55 | on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440. |
54 | 56 | ||
55 | config LEDS_AMS_DELTA | 57 | config LEDS_AMS_DELTA |
56 | tristate "LED Support for the Amstrad Delta (E3)" | 58 | tristate "LED Support for the Amstrad Delta (E3)" |
57 | depends on LEDS_CLASS && MACH_AMS_DELTA | 59 | depends on MACH_AMS_DELTA |
58 | help | 60 | help |
59 | This option enables support for the LEDs on Amstrad Delta (E3). | 61 | This option enables support for the LEDs on Amstrad Delta (E3). |
60 | 62 | ||
61 | config LEDS_NET48XX | 63 | config LEDS_NET48XX |
62 | tristate "LED Support for Soekris net48xx series Error LED" | 64 | tristate "LED Support for Soekris net48xx series Error LED" |
63 | depends on LEDS_CLASS && SCx200_GPIO | 65 | depends on SCx200_GPIO |
64 | help | 66 | help |
65 | This option enables support for the Soekris net4801 and net4826 error | 67 | This option enables support for the Soekris net4801 and net4826 error |
66 | LED. | 68 | LED. |
67 | 69 | ||
68 | config LEDS_FSG | 70 | config LEDS_FSG |
69 | tristate "LED Support for the Freecom FSG-3" | 71 | tristate "LED Support for the Freecom FSG-3" |
70 | depends on LEDS_CLASS && MACH_FSG | 72 | depends on MACH_FSG |
71 | help | 73 | help |
72 | This option enables support for the LEDs on the Freecom FSG-3. | 74 | This option enables support for the LEDs on the Freecom FSG-3. |
73 | 75 | ||
74 | config LEDS_WRAP | 76 | config LEDS_WRAP |
75 | tristate "LED Support for the WRAP series LEDs" | 77 | tristate "LED Support for the WRAP series LEDs" |
76 | depends on LEDS_CLASS && SCx200_GPIO | 78 | depends on SCx200_GPIO |
77 | help | 79 | help |
78 | This option enables support for the PCEngines WRAP programmable LEDs. | 80 | This option enables support for the PCEngines WRAP programmable LEDs. |
79 | 81 | ||
80 | config LEDS_ALIX2 | 82 | config LEDS_ALIX2 |
81 | tristate "LED Support for ALIX.2 and ALIX.3 series" | 83 | tristate "LED Support for ALIX.2 and ALIX.3 series" |
82 | depends on LEDS_CLASS && X86 && EXPERIMENTAL | 84 | depends on X86 && !GPIO_CS5535 && !CS5535_GPIO |
83 | help | 85 | help |
84 | This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs. | 86 | This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs. |
85 | You have to set leds-alix2.force=1 for boards with Award BIOS. | 87 | You have to set leds-alix2.force=1 for boards with Award BIOS. |
86 | 88 | ||
87 | config LEDS_H1940 | 89 | config LEDS_H1940 |
88 | tristate "LED Support for iPAQ H1940 device" | 90 | tristate "LED Support for iPAQ H1940 device" |
89 | depends on LEDS_CLASS && ARCH_H1940 | 91 | depends on ARCH_H1940 |
90 | help | 92 | help |
91 | This option enables support for the LEDs on the h1940. | 93 | This option enables support for the LEDs on the h1940. |
92 | 94 | ||
93 | config LEDS_COBALT_QUBE | 95 | config LEDS_COBALT_QUBE |
94 | tristate "LED Support for the Cobalt Qube series front LED" | 96 | tristate "LED Support for the Cobalt Qube series front LED" |
95 | depends on LEDS_CLASS && MIPS_COBALT | 97 | depends on MIPS_COBALT |
96 | help | 98 | help |
97 | This option enables support for the front LED on Cobalt Qube series | 99 | This option enables support for the front LED on Cobalt Qube series |
98 | 100 | ||
@@ -105,7 +107,7 @@ config LEDS_COBALT_RAQ | |||
105 | 107 | ||
106 | config LEDS_SUNFIRE | 108 | config LEDS_SUNFIRE |
107 | tristate "LED support for SunFire servers." | 109 | tristate "LED support for SunFire servers." |
108 | depends on LEDS_CLASS && SPARC64 | 110 | depends on SPARC64 |
109 | select LEDS_TRIGGERS | 111 | select LEDS_TRIGGERS |
110 | help | 112 | help |
111 | This option enables support for the Left, Middle, and Right | 113 | This option enables support for the Left, Middle, and Right |
@@ -113,14 +115,14 @@ config LEDS_SUNFIRE | |||
113 | 115 | ||
114 | config LEDS_HP6XX | 116 | config LEDS_HP6XX |
115 | tristate "LED Support for the HP Jornada 6xx" | 117 | tristate "LED Support for the HP Jornada 6xx" |
116 | depends on LEDS_CLASS && SH_HP6XX | 118 | depends on SH_HP6XX |
117 | help | 119 | help |
118 | This option enables LED support for the handheld | 120 | This option enables LED support for the handheld |
119 | HP Jornada 620/660/680/690. | 121 | HP Jornada 620/660/680/690. |
120 | 122 | ||
121 | config LEDS_PCA9532 | 123 | config LEDS_PCA9532 |
122 | tristate "LED driver for PCA9532 dimmer" | 124 | tristate "LED driver for PCA9532 dimmer" |
123 | depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL | 125 | depends on I2C && INPUT && EXPERIMENTAL |
124 | help | 126 | help |
125 | This option enables support for NXP pca9532 | 127 | This option enables support for NXP pca9532 |
126 | LED controller. It is generally only useful | 128 | LED controller. It is generally only useful |
@@ -128,7 +130,7 @@ config LEDS_PCA9532 | |||
128 | 130 | ||
129 | config LEDS_GPIO | 131 | config LEDS_GPIO |
130 | tristate "LED Support for GPIO connected LEDs" | 132 | tristate "LED Support for GPIO connected LEDs" |
131 | depends on LEDS_CLASS && GENERIC_GPIO | 133 | depends on GENERIC_GPIO |
132 | help | 134 | help |
133 | This option enables support for the LEDs connected to GPIO | 135 | This option enables support for the LEDs connected to GPIO |
134 | outputs. To be useful the particular board must have LEDs | 136 | outputs. To be useful the particular board must have LEDs |
@@ -155,7 +157,7 @@ config LEDS_GPIO_OF | |||
155 | 157 | ||
156 | config LEDS_LP3944 | 158 | config LEDS_LP3944 |
157 | tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip" | 159 | tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip" |
158 | depends on LEDS_CLASS && I2C | 160 | depends on I2C |
159 | help | 161 | help |
160 | This option enables support for LEDs connected to the National | 162 | This option enables support for LEDs connected to the National |
161 | Semiconductor LP3944 Lighting Management Unit (LMU) also known as | 163 | Semiconductor LP3944 Lighting Management Unit (LMU) also known as |
@@ -166,7 +168,7 @@ config LEDS_LP3944 | |||
166 | 168 | ||
167 | config LEDS_CLEVO_MAIL | 169 | config LEDS_CLEVO_MAIL |
168 | tristate "Mail LED on Clevo notebook" | 170 | tristate "Mail LED on Clevo notebook" |
169 | depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI | 171 | depends on X86 && SERIO_I8042 && DMI |
170 | help | 172 | help |
171 | This driver makes the mail LED accessible from userspace | 173 | This driver makes the mail LED accessible from userspace |
172 | programs through the leds subsystem. This LED have three | 174 | programs through the leds subsystem. This LED have three |
@@ -196,7 +198,7 @@ config LEDS_CLEVO_MAIL | |||
196 | 198 | ||
197 | config LEDS_PCA955X | 199 | config LEDS_PCA955X |
198 | tristate "LED Support for PCA955x I2C chips" | 200 | tristate "LED Support for PCA955x I2C chips" |
199 | depends on LEDS_CLASS && I2C | 201 | depends on I2C |
200 | help | 202 | help |
201 | This option enables support for LEDs connected to PCA955x | 203 | This option enables support for LEDs connected to PCA955x |
202 | LED driver chips accessed via the I2C bus. Supported | 204 | LED driver chips accessed via the I2C bus. Supported |
@@ -204,54 +206,54 @@ config LEDS_PCA955X | |||
204 | 206 | ||
205 | config LEDS_WM831X_STATUS | 207 | config LEDS_WM831X_STATUS |
206 | tristate "LED support for status LEDs on WM831x PMICs" | 208 | tristate "LED support for status LEDs on WM831x PMICs" |
207 | depends on LEDS_CLASS && MFD_WM831X | 209 | depends on MFD_WM831X |
208 | help | 210 | help |
209 | This option enables support for the status LEDs of the WM831x | 211 | This option enables support for the status LEDs of the WM831x |
210 | series of PMICs. | 212 | series of PMICs. |
211 | 213 | ||
212 | config LEDS_WM8350 | 214 | config LEDS_WM8350 |
213 | tristate "LED Support for WM8350 AudioPlus PMIC" | 215 | tristate "LED Support for WM8350 AudioPlus PMIC" |
214 | depends on LEDS_CLASS && MFD_WM8350 | 216 | depends on MFD_WM8350 |
215 | help | 217 | help |
216 | This option enables support for LEDs driven by the Wolfson | 218 | This option enables support for LEDs driven by the Wolfson |
217 | Microelectronics WM8350 AudioPlus PMIC. | 219 | Microelectronics WM8350 AudioPlus PMIC. |
218 | 220 | ||
219 | config LEDS_DA903X | 221 | config LEDS_DA903X |
220 | tristate "LED Support for DA9030/DA9034 PMIC" | 222 | tristate "LED Support for DA9030/DA9034 PMIC" |
221 | depends on LEDS_CLASS && PMIC_DA903X | 223 | depends on PMIC_DA903X |
222 | help | 224 | help |
223 | This option enables support for on-chip LED drivers found | 225 | This option enables support for on-chip LED drivers found |
224 | on Dialog Semiconductor DA9030/DA9034 PMICs. | 226 | on Dialog Semiconductor DA9030/DA9034 PMICs. |
225 | 227 | ||
226 | config LEDS_DAC124S085 | 228 | config LEDS_DAC124S085 |
227 | tristate "LED Support for DAC124S085 SPI DAC" | 229 | tristate "LED Support for DAC124S085 SPI DAC" |
228 | depends on LEDS_CLASS && SPI | 230 | depends on SPI |
229 | help | 231 | help |
230 | This option enables support for DAC124S085 SPI DAC from NatSemi, | 232 | This option enables support for DAC124S085 SPI DAC from NatSemi, |
231 | which can be used to control up to four LEDs. | 233 | which can be used to control up to four LEDs. |
232 | 234 | ||
233 | config LEDS_PWM | 235 | config LEDS_PWM |
234 | tristate "PWM driven LED Support" | 236 | tristate "PWM driven LED Support" |
235 | depends on LEDS_CLASS && HAVE_PWM | 237 | depends on HAVE_PWM |
236 | help | 238 | help |
237 | This option enables support for pwm driven LEDs | 239 | This option enables support for pwm driven LEDs |
238 | 240 | ||
239 | config LEDS_REGULATOR | 241 | config LEDS_REGULATOR |
240 | tristate "REGULATOR driven LED support" | 242 | tristate "REGULATOR driven LED support" |
241 | depends on LEDS_CLASS && REGULATOR | 243 | depends on REGULATOR |
242 | help | 244 | help |
243 | This option enables support for regulator driven LEDs. | 245 | This option enables support for regulator driven LEDs. |
244 | 246 | ||
245 | config LEDS_BD2802 | 247 | config LEDS_BD2802 |
246 | tristate "LED driver for BD2802 RGB LED" | 248 | tristate "LED driver for BD2802 RGB LED" |
247 | depends on LEDS_CLASS && I2C | 249 | depends on I2C |
248 | help | 250 | help |
249 | This option enables support for BD2802GU RGB LED driver chips | 251 | This option enables support for BD2802GU RGB LED driver chips |
250 | accessed via the I2C bus. | 252 | accessed via the I2C bus. |
251 | 253 | ||
252 | config LEDS_INTEL_SS4200 | 254 | config LEDS_INTEL_SS4200 |
253 | tristate "LED driver for Intel NAS SS4200 series" | 255 | tristate "LED driver for Intel NAS SS4200 series" |
254 | depends on LEDS_CLASS && PCI && DMI | 256 | depends on PCI && DMI |
255 | help | 257 | help |
256 | This option enables support for the Intel SS4200 series of | 258 | This option enables support for the Intel SS4200 series of |
257 | Network Attached Storage servers. You may control the hard | 259 | Network Attached Storage servers. You may control the hard |
@@ -260,7 +262,7 @@ config LEDS_INTEL_SS4200 | |||
260 | 262 | ||
261 | config LEDS_LT3593 | 263 | config LEDS_LT3593 |
262 | tristate "LED driver for LT3593 controllers" | 264 | tristate "LED driver for LT3593 controllers" |
263 | depends on LEDS_CLASS && GENERIC_GPIO | 265 | depends on GENERIC_GPIO |
264 | help | 266 | help |
265 | This option enables support for LEDs driven by a Linear Technology | 267 | This option enables support for LEDs driven by a Linear Technology |
266 | LT3593 controller. This controller uses a special one-wire pulse | 268 | LT3593 controller. This controller uses a special one-wire pulse |
@@ -268,7 +270,7 @@ config LEDS_LT3593 | |||
268 | 270 | ||
269 | config LEDS_ADP5520 | 271 | config LEDS_ADP5520 |
270 | tristate "LED Support for ADP5520/ADP5501 PMIC" | 272 | tristate "LED Support for ADP5520/ADP5501 PMIC" |
271 | depends on LEDS_CLASS && PMIC_ADP5520 | 273 | depends on PMIC_ADP5520 |
272 | help | 274 | help |
273 | This option enables support for on-chip LED drivers found | 275 | This option enables support for on-chip LED drivers found |
274 | on Analog Devices ADP5520/ADP5501 PMICs. | 276 | on Analog Devices ADP5520/ADP5501 PMICs. |
@@ -276,7 +278,12 @@ config LEDS_ADP5520 | |||
276 | To compile this driver as a module, choose M here: the module will | 278 | To compile this driver as a module, choose M here: the module will |
277 | be called leds-adp5520. | 279 | be called leds-adp5520. |
278 | 280 | ||
279 | comment "LED Triggers" | 281 | config LEDS_DELL_NETBOOKS |
282 | tristate "External LED on Dell Business Netbooks" | ||
283 | depends on X86 && ACPI_WMI | ||
284 | help | ||
285 | This adds support for the Latitude 2100 and similar | ||
286 | notebooks that have an external LED. | ||
280 | 287 | ||
281 | config LEDS_TRIGGERS | 288 | config LEDS_TRIGGERS |
282 | bool "LED Trigger support" | 289 | bool "LED Trigger support" |
@@ -285,9 +292,12 @@ config LEDS_TRIGGERS | |||
285 | These triggers allow kernel events to drive the LEDs and can | 292 | These triggers allow kernel events to drive the LEDs and can |
286 | be configured via sysfs. If unsure, say Y. | 293 | be configured via sysfs. If unsure, say Y. |
287 | 294 | ||
295 | if LEDS_TRIGGERS | ||
296 | |||
297 | comment "LED Triggers" | ||
298 | |||
288 | config LEDS_TRIGGER_TIMER | 299 | config LEDS_TRIGGER_TIMER |
289 | tristate "LED Timer Trigger" | 300 | tristate "LED Timer Trigger" |
290 | depends on LEDS_TRIGGERS | ||
291 | help | 301 | help |
292 | This allows LEDs to be controlled by a programmable timer | 302 | This allows LEDs to be controlled by a programmable timer |
293 | via sysfs. Some LED hardware can be programmed to start | 303 | via sysfs. Some LED hardware can be programmed to start |
@@ -298,14 +308,13 @@ config LEDS_TRIGGER_TIMER | |||
298 | 308 | ||
299 | config LEDS_TRIGGER_IDE_DISK | 309 | config LEDS_TRIGGER_IDE_DISK |
300 | bool "LED IDE Disk Trigger" | 310 | bool "LED IDE Disk Trigger" |
301 | depends on LEDS_TRIGGERS && IDE_GD_ATA | 311 | depends on IDE_GD_ATA |
302 | help | 312 | help |
303 | This allows LEDs to be controlled by IDE disk activity. | 313 | This allows LEDs to be controlled by IDE disk activity. |
304 | If unsure, say Y. | 314 | If unsure, say Y. |
305 | 315 | ||
306 | config LEDS_TRIGGER_HEARTBEAT | 316 | config LEDS_TRIGGER_HEARTBEAT |
307 | tristate "LED Heartbeat Trigger" | 317 | tristate "LED Heartbeat Trigger" |
308 | depends on LEDS_TRIGGERS | ||
309 | help | 318 | help |
310 | This allows LEDs to be controlled by a CPU load average. | 319 | This allows LEDs to be controlled by a CPU load average. |
311 | The flash frequency is a hyperbolic function of the 1-minute | 320 | The flash frequency is a hyperbolic function of the 1-minute |
@@ -314,7 +323,6 @@ config LEDS_TRIGGER_HEARTBEAT | |||
314 | 323 | ||
315 | config LEDS_TRIGGER_BACKLIGHT | 324 | config LEDS_TRIGGER_BACKLIGHT |
316 | tristate "LED backlight Trigger" | 325 | tristate "LED backlight Trigger" |
317 | depends on LEDS_TRIGGERS | ||
318 | help | 326 | help |
319 | This allows LEDs to be controlled as a backlight device: they | 327 | This allows LEDs to be controlled as a backlight device: they |
320 | turn off and on when the display is blanked and unblanked. | 328 | turn off and on when the display is blanked and unblanked. |
@@ -323,7 +331,6 @@ config LEDS_TRIGGER_BACKLIGHT | |||
323 | 331 | ||
324 | config LEDS_TRIGGER_GPIO | 332 | config LEDS_TRIGGER_GPIO |
325 | tristate "LED GPIO Trigger" | 333 | tristate "LED GPIO Trigger" |
326 | depends on LEDS_TRIGGERS | ||
327 | depends on GPIOLIB | 334 | depends on GPIOLIB |
328 | help | 335 | help |
329 | This allows LEDs to be controlled by gpio events. It's good | 336 | This allows LEDs to be controlled by gpio events. It's good |
@@ -336,7 +343,6 @@ config LEDS_TRIGGER_GPIO | |||
336 | 343 | ||
337 | config LEDS_TRIGGER_DEFAULT_ON | 344 | config LEDS_TRIGGER_DEFAULT_ON |
338 | tristate "LED Default ON Trigger" | 345 | tristate "LED Default ON Trigger" |
339 | depends on LEDS_TRIGGERS | ||
340 | help | 346 | help |
341 | This allows LEDs to be initialised in the ON state. | 347 | This allows LEDs to be initialised in the ON state. |
342 | If unsure, say Y. | 348 | If unsure, say Y. |
@@ -344,4 +350,8 @@ config LEDS_TRIGGER_DEFAULT_ON | |||
344 | comment "iptables trigger is under Netfilter config (LED target)" | 350 | comment "iptables trigger is under Netfilter config (LED target)" |
345 | depends on LEDS_TRIGGERS | 351 | depends on LEDS_TRIGGERS |
346 | 352 | ||
353 | endif # LEDS_TRIGGERS | ||
354 | |||
355 | endif # LEDS_CLASS | ||
356 | |||
347 | endif # NEW_LEDS | 357 | endif # NEW_LEDS |
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index d76fb32b77c0..0cd8b9957380 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
@@ -34,6 +34,7 @@ obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o | |||
34 | obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o | 34 | obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o |
35 | obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o | 35 | obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o |
36 | obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o | 36 | obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o |
37 | obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o | ||
37 | 38 | ||
38 | # LED SPI Drivers | 39 | # LED SPI Drivers |
39 | obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o | 40 | obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o |
diff --git a/drivers/leds/dell-led.c b/drivers/leds/dell-led.c new file mode 100644 index 000000000000..ee310891fff8 --- /dev/null +++ b/drivers/leds/dell-led.c | |||
@@ -0,0 +1,200 @@ | |||
1 | /* | ||
2 | * dell_led.c - Dell LED Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Dell Inc. | ||
5 | * Louis Davis <louis_davis@dell.com> | ||
6 | * Jim Dailey <jim_dailey@dell.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/acpi.h> | ||
15 | #include <linux/leds.h> | ||
16 | |||
17 | MODULE_AUTHOR("Louis Davis/Jim Dailey"); | ||
18 | MODULE_DESCRIPTION("Dell LED Control Driver"); | ||
19 | MODULE_LICENSE("GPL"); | ||
20 | |||
21 | #define DELL_LED_BIOS_GUID "F6E4FE6E-909D-47cb-8BAB-C9F6F2F8D396" | ||
22 | MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID); | ||
23 | |||
24 | /* Error Result Codes: */ | ||
25 | #define INVALID_DEVICE_ID 250 | ||
26 | #define INVALID_PARAMETER 251 | ||
27 | #define INVALID_BUFFER 252 | ||
28 | #define INTERFACE_ERROR 253 | ||
29 | #define UNSUPPORTED_COMMAND 254 | ||
30 | #define UNSPECIFIED_ERROR 255 | ||
31 | |||
32 | /* Device ID */ | ||
33 | #define DEVICE_ID_PANEL_BACK 1 | ||
34 | |||
35 | /* LED Commands */ | ||
36 | #define CMD_LED_ON 16 | ||
37 | #define CMD_LED_OFF 17 | ||
38 | #define CMD_LED_BLINK 18 | ||
39 | |||
40 | struct bios_args { | ||
41 | unsigned char length; | ||
42 | unsigned char result_code; | ||
43 | unsigned char device_id; | ||
44 | unsigned char command; | ||
45 | unsigned char on_time; | ||
46 | unsigned char off_time; | ||
47 | }; | ||
48 | |||
49 | static int dell_led_perform_fn(u8 length, | ||
50 | u8 result_code, | ||
51 | u8 device_id, | ||
52 | u8 command, | ||
53 | u8 on_time, | ||
54 | u8 off_time) | ||
55 | { | ||
56 | struct bios_args *bios_return; | ||
57 | u8 return_code; | ||
58 | union acpi_object *obj; | ||
59 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
60 | struct acpi_buffer input; | ||
61 | acpi_status status; | ||
62 | |||
63 | struct bios_args args; | ||
64 | args.length = length; | ||
65 | args.result_code = result_code; | ||
66 | args.device_id = device_id; | ||
67 | args.command = command; | ||
68 | args.on_time = on_time; | ||
69 | args.off_time = off_time; | ||
70 | |||
71 | input.length = sizeof(struct bios_args); | ||
72 | input.pointer = &args; | ||
73 | |||
74 | status = wmi_evaluate_method(DELL_LED_BIOS_GUID, | ||
75 | 1, | ||
76 | 1, | ||
77 | &input, | ||
78 | &output); | ||
79 | |||
80 | if (ACPI_FAILURE(status)) | ||
81 | return status; | ||
82 | |||
83 | obj = output.pointer; | ||
84 | |||
85 | if (!obj) | ||
86 | return -EINVAL; | ||
87 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
88 | kfree(obj); | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | |||
92 | bios_return = ((struct bios_args *)obj->buffer.pointer); | ||
93 | return_code = bios_return->result_code; | ||
94 | |||
95 | kfree(obj); | ||
96 | |||
97 | return return_code; | ||
98 | } | ||
99 | |||
100 | static int led_on(void) | ||
101 | { | ||
102 | return dell_led_perform_fn(3, /* Length of command */ | ||
103 | INTERFACE_ERROR, /* Init to INTERFACE_ERROR */ | ||
104 | DEVICE_ID_PANEL_BACK, /* Device ID */ | ||
105 | CMD_LED_ON, /* Command */ | ||
106 | 0, /* not used */ | ||
107 | 0); /* not used */ | ||
108 | } | ||
109 | |||
110 | static int led_off(void) | ||
111 | { | ||
112 | return dell_led_perform_fn(3, /* Length of command */ | ||
113 | INTERFACE_ERROR, /* Init to INTERFACE_ERROR */ | ||
114 | DEVICE_ID_PANEL_BACK, /* Device ID */ | ||
115 | CMD_LED_OFF, /* Command */ | ||
116 | 0, /* not used */ | ||
117 | 0); /* not used */ | ||
118 | } | ||
119 | |||
120 | static int led_blink(unsigned char on_eighths, | ||
121 | unsigned char off_eighths) | ||
122 | { | ||
123 | return dell_led_perform_fn(5, /* Length of command */ | ||
124 | INTERFACE_ERROR, /* Init to INTERFACE_ERROR */ | ||
125 | DEVICE_ID_PANEL_BACK, /* Device ID */ | ||
126 | CMD_LED_BLINK, /* Command */ | ||
127 | on_eighths, /* blink on in eigths of a second */ | ||
128 | off_eighths); /* blink off in eights of a second */ | ||
129 | } | ||
130 | |||
131 | static void dell_led_set(struct led_classdev *led_cdev, | ||
132 | enum led_brightness value) | ||
133 | { | ||
134 | if (value == LED_OFF) | ||
135 | led_off(); | ||
136 | else | ||
137 | led_on(); | ||
138 | } | ||
139 | |||
140 | static int dell_led_blink(struct led_classdev *led_cdev, | ||
141 | unsigned long *delay_on, | ||
142 | unsigned long *delay_off) | ||
143 | { | ||
144 | unsigned long on_eighths; | ||
145 | unsigned long off_eighths; | ||
146 | |||
147 | /* The Dell LED delay is based on 125ms intervals. | ||
148 | Need to round up to next interval. */ | ||
149 | |||
150 | on_eighths = (*delay_on + 124) / 125; | ||
151 | if (0 == on_eighths) | ||
152 | on_eighths = 1; | ||
153 | if (on_eighths > 255) | ||
154 | on_eighths = 255; | ||
155 | *delay_on = on_eighths * 125; | ||
156 | |||
157 | off_eighths = (*delay_off + 124) / 125; | ||
158 | if (0 == off_eighths) | ||
159 | off_eighths = 1; | ||
160 | if (off_eighths > 255) | ||
161 | off_eighths = 255; | ||
162 | *delay_off = off_eighths * 125; | ||
163 | |||
164 | led_blink(on_eighths, off_eighths); | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static struct led_classdev dell_led = { | ||
170 | .name = "dell::lid", | ||
171 | .brightness = LED_OFF, | ||
172 | .max_brightness = 1, | ||
173 | .brightness_set = dell_led_set, | ||
174 | .blink_set = dell_led_blink, | ||
175 | .flags = LED_CORE_SUSPENDRESUME, | ||
176 | }; | ||
177 | |||
178 | static int __init dell_led_init(void) | ||
179 | { | ||
180 | int error = 0; | ||
181 | |||
182 | if (!wmi_has_guid(DELL_LED_BIOS_GUID)) | ||
183 | return -ENODEV; | ||
184 | |||
185 | error = led_off(); | ||
186 | if (error != 0) | ||
187 | return -ENODEV; | ||
188 | |||
189 | return led_classdev_register(NULL, &dell_led); | ||
190 | } | ||
191 | |||
192 | static void __exit dell_led_exit(void) | ||
193 | { | ||
194 | led_classdev_unregister(&dell_led); | ||
195 | |||
196 | led_off(); | ||
197 | } | ||
198 | |||
199 | module_init(dell_led_init); | ||
200 | module_exit(dell_led_exit); | ||
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 782f95822eab..69e7d86a5143 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
@@ -72,11 +72,14 @@ static ssize_t led_max_brightness_show(struct device *dev, | |||
72 | return sprintf(buf, "%u\n", led_cdev->max_brightness); | 72 | return sprintf(buf, "%u\n", led_cdev->max_brightness); |
73 | } | 73 | } |
74 | 74 | ||
75 | static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store); | 75 | static struct device_attribute led_class_attrs[] = { |
76 | static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL); | 76 | __ATTR(brightness, 0644, led_brightness_show, led_brightness_store), |
77 | __ATTR(max_brightness, 0644, led_max_brightness_show, NULL), | ||
77 | #ifdef CONFIG_LEDS_TRIGGERS | 78 | #ifdef CONFIG_LEDS_TRIGGERS |
78 | static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); | 79 | __ATTR(trigger, 0644, led_trigger_show, led_trigger_store), |
79 | #endif | 80 | #endif |
81 | __ATTR_NULL, | ||
82 | }; | ||
80 | 83 | ||
81 | /** | 84 | /** |
82 | * led_classdev_suspend - suspend an led_classdev. | 85 | * led_classdev_suspend - suspend an led_classdev. |
@@ -127,18 +130,11 @@ static int led_resume(struct device *dev) | |||
127 | */ | 130 | */ |
128 | int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | 131 | int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) |
129 | { | 132 | { |
130 | int rc; | ||
131 | |||
132 | led_cdev->dev = device_create(leds_class, parent, 0, led_cdev, | 133 | led_cdev->dev = device_create(leds_class, parent, 0, led_cdev, |
133 | "%s", led_cdev->name); | 134 | "%s", led_cdev->name); |
134 | if (IS_ERR(led_cdev->dev)) | 135 | if (IS_ERR(led_cdev->dev)) |
135 | return PTR_ERR(led_cdev->dev); | 136 | return PTR_ERR(led_cdev->dev); |
136 | 137 | ||
137 | /* register the attributes */ | ||
138 | rc = device_create_file(led_cdev->dev, &dev_attr_brightness); | ||
139 | if (rc) | ||
140 | goto err_out; | ||
141 | |||
142 | #ifdef CONFIG_LEDS_TRIGGERS | 138 | #ifdef CONFIG_LEDS_TRIGGERS |
143 | init_rwsem(&led_cdev->trigger_lock); | 139 | init_rwsem(&led_cdev->trigger_lock); |
144 | #endif | 140 | #endif |
@@ -150,36 +146,18 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
150 | if (!led_cdev->max_brightness) | 146 | if (!led_cdev->max_brightness) |
151 | led_cdev->max_brightness = LED_FULL; | 147 | led_cdev->max_brightness = LED_FULL; |
152 | 148 | ||
153 | rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness); | ||
154 | if (rc) | ||
155 | goto err_out_attr_max; | ||
156 | |||
157 | led_update_brightness(led_cdev); | 149 | led_update_brightness(led_cdev); |
158 | 150 | ||
159 | #ifdef CONFIG_LEDS_TRIGGERS | 151 | #ifdef CONFIG_LEDS_TRIGGERS |
160 | rc = device_create_file(led_cdev->dev, &dev_attr_trigger); | ||
161 | if (rc) | ||
162 | goto err_out_led_list; | ||
163 | |||
164 | led_trigger_set_default(led_cdev); | 152 | led_trigger_set_default(led_cdev); |
165 | #endif | 153 | #endif |
166 | 154 | ||
167 | printk(KERN_INFO "Registered led device: %s\n", | 155 | printk(KERN_DEBUG "Registered led device: %s\n", |
168 | led_cdev->name); | 156 | led_cdev->name); |
169 | 157 | ||
170 | return 0; | 158 | return 0; |
171 | |||
172 | #ifdef CONFIG_LEDS_TRIGGERS | ||
173 | err_out_led_list: | ||
174 | device_remove_file(led_cdev->dev, &dev_attr_max_brightness); | ||
175 | #endif | ||
176 | err_out_attr_max: | ||
177 | device_remove_file(led_cdev->dev, &dev_attr_brightness); | ||
178 | list_del(&led_cdev->node); | ||
179 | err_out: | ||
180 | device_unregister(led_cdev->dev); | ||
181 | return rc; | ||
182 | } | 159 | } |
160 | |||
183 | EXPORT_SYMBOL_GPL(led_classdev_register); | 161 | EXPORT_SYMBOL_GPL(led_classdev_register); |
184 | 162 | ||
185 | /** | 163 | /** |
@@ -190,10 +168,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register); | |||
190 | */ | 168 | */ |
191 | void led_classdev_unregister(struct led_classdev *led_cdev) | 169 | void led_classdev_unregister(struct led_classdev *led_cdev) |
192 | { | 170 | { |
193 | device_remove_file(led_cdev->dev, &dev_attr_max_brightness); | ||
194 | device_remove_file(led_cdev->dev, &dev_attr_brightness); | ||
195 | #ifdef CONFIG_LEDS_TRIGGERS | 171 | #ifdef CONFIG_LEDS_TRIGGERS |
196 | device_remove_file(led_cdev->dev, &dev_attr_trigger); | ||
197 | down_write(&led_cdev->trigger_lock); | 172 | down_write(&led_cdev->trigger_lock); |
198 | if (led_cdev->trigger) | 173 | if (led_cdev->trigger) |
199 | led_trigger_set(led_cdev, NULL); | 174 | led_trigger_set(led_cdev, NULL); |
@@ -215,6 +190,7 @@ static int __init leds_init(void) | |||
215 | return PTR_ERR(leds_class); | 190 | return PTR_ERR(leds_class); |
216 | leds_class->suspend = led_suspend; | 191 | leds_class->suspend = led_suspend; |
217 | leds_class->resume = led_resume; | 192 | leds_class->resume = led_resume; |
193 | leds_class->dev_attrs = led_class_attrs; | ||
218 | return 0; | 194 | return 0; |
219 | } | 195 | } |
220 | 196 | ||
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index e5225d28f392..0823e2622e8c 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c | |||
@@ -211,7 +211,6 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, | |||
211 | const struct of_device_id *match) | 211 | const struct of_device_id *match) |
212 | { | 212 | { |
213 | struct device_node *np = ofdev->node, *child; | 213 | struct device_node *np = ofdev->node, *child; |
214 | struct gpio_led led; | ||
215 | struct gpio_led_of_platform_data *pdata; | 214 | struct gpio_led_of_platform_data *pdata; |
216 | int count = 0, ret; | 215 | int count = 0, ret; |
217 | 216 | ||
@@ -226,8 +225,8 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, | |||
226 | if (!pdata) | 225 | if (!pdata) |
227 | return -ENOMEM; | 226 | return -ENOMEM; |
228 | 227 | ||
229 | memset(&led, 0, sizeof(led)); | ||
230 | for_each_child_of_node(np, child) { | 228 | for_each_child_of_node(np, child) { |
229 | struct gpio_led led = {}; | ||
231 | enum of_gpio_flags flags; | 230 | enum of_gpio_flags flags; |
232 | const char *state; | 231 | const char *state; |
233 | 232 | ||
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c index 97f04984c1ca..51477ec71391 100644 --- a/drivers/leds/leds-ss4200.c +++ b/drivers/leds/leds-ss4200.c | |||
@@ -63,7 +63,7 @@ MODULE_LICENSE("GPL"); | |||
63 | /* | 63 | /* |
64 | * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives. | 64 | * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives. |
65 | */ | 65 | */ |
66 | static struct pci_device_id ich7_lpc_pci_id[] = | 66 | static const struct pci_device_id ich7_lpc_pci_id[] = |
67 | { | 67 | { |
68 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) }, | 68 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) }, |
69 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) }, | 69 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) }, |
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index 4f3c4479c16a..1cec02f6c431 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c | |||
@@ -144,6 +144,7 @@ void pmu_backlight_set_sleep(int sleep) | |||
144 | 144 | ||
145 | void __init pmu_backlight_init() | 145 | void __init pmu_backlight_init() |
146 | { | 146 | { |
147 | struct backlight_properties props; | ||
147 | struct backlight_device *bd; | 148 | struct backlight_device *bd; |
148 | char name[10]; | 149 | char name[10]; |
149 | int level, autosave; | 150 | int level, autosave; |
@@ -161,13 +162,15 @@ void __init pmu_backlight_init() | |||
161 | 162 | ||
162 | snprintf(name, sizeof(name), "pmubl"); | 163 | snprintf(name, sizeof(name), "pmubl"); |
163 | 164 | ||
164 | bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data); | 165 | memset(&props, 0, sizeof(struct backlight_properties)); |
166 | props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | ||
167 | bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data, | ||
168 | &props); | ||
165 | if (IS_ERR(bd)) { | 169 | if (IS_ERR(bd)) { |
166 | printk(KERN_ERR "PMU Backlight registration failed\n"); | 170 | printk(KERN_ERR "PMU Backlight registration failed\n"); |
167 | return; | 171 | return; |
168 | } | 172 | } |
169 | uses_pmu_bl = 1; | 173 | uses_pmu_bl = 1; |
170 | bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | ||
171 | pmu_backlight_init_curve(0x7F, 0x46, 0x0E); | 174 | pmu_backlight_init_curve(0x7F, 0x46, 0x0E); |
172 | 175 | ||
173 | level = bd->props.max_brightness; | 176 | level = bd->props.max_brightness; |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index af2d39d603c7..bb2a23159b21 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -172,12 +172,14 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
172 | disk_stack_limits(mddev->gendisk, rdev->bdev, | 172 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
173 | rdev->data_offset << 9); | 173 | rdev->data_offset << 9); |
174 | /* as we don't honour merge_bvec_fn, we must never risk | 174 | /* as we don't honour merge_bvec_fn, we must never risk |
175 | * violating it, so limit ->max_sector to one PAGE, as | 175 | * violating it, so limit max_segments to 1 lying within |
176 | * a one page request is never in violation. | 176 | * a single page. |
177 | */ | 177 | */ |
178 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn && | 178 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { |
179 | queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) | 179 | blk_queue_max_segments(mddev->queue, 1); |
180 | blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); | 180 | blk_queue_segment_boundary(mddev->queue, |
181 | PAGE_CACHE_SIZE - 1); | ||
182 | } | ||
181 | 183 | ||
182 | conf->array_sectors += rdev->sectors; | 184 | conf->array_sectors += rdev->sectors; |
183 | cnt++; | 185 | cnt++; |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 4b323f45ad74..5558ebc705c8 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -301,14 +301,16 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
301 | rdev->data_offset << 9); | 301 | rdev->data_offset << 9); |
302 | 302 | ||
303 | /* as we don't honour merge_bvec_fn, we must never risk | 303 | /* as we don't honour merge_bvec_fn, we must never risk |
304 | * violating it, so limit ->max_sector to one PAGE, as | 304 | * violating it, so limit ->max_segments to one, lying |
305 | * a one page request is never in violation. | 305 | * within a single page. |
306 | * (Note: it is very unlikely that a device with | 306 | * (Note: it is very unlikely that a device with |
307 | * merge_bvec_fn will be involved in multipath.) | 307 | * merge_bvec_fn will be involved in multipath.) |
308 | */ | 308 | */ |
309 | if (q->merge_bvec_fn && | 309 | if (q->merge_bvec_fn) { |
310 | queue_max_sectors(q) > (PAGE_SIZE>>9)) | 310 | blk_queue_max_segments(mddev->queue, 1); |
311 | blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); | 311 | blk_queue_segment_boundary(mddev->queue, |
312 | PAGE_CACHE_SIZE - 1); | ||
313 | } | ||
312 | 314 | ||
313 | conf->working_disks++; | 315 | conf->working_disks++; |
314 | mddev->degraded--; | 316 | mddev->degraded--; |
@@ -476,9 +478,11 @@ static int multipath_run (mddev_t *mddev) | |||
476 | /* as we don't honour merge_bvec_fn, we must never risk | 478 | /* as we don't honour merge_bvec_fn, we must never risk |
477 | * violating it, not that we ever expect a device with | 479 | * violating it, not that we ever expect a device with |
478 | * a merge_bvec_fn to be involved in multipath */ | 480 | * a merge_bvec_fn to be involved in multipath */ |
479 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn && | 481 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { |
480 | queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) | 482 | blk_queue_max_segments(mddev->queue, 1); |
481 | blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); | 483 | blk_queue_segment_boundary(mddev->queue, |
484 | PAGE_CACHE_SIZE - 1); | ||
485 | } | ||
482 | 486 | ||
483 | if (!test_bit(Faulty, &rdev->flags)) | 487 | if (!test_bit(Faulty, &rdev->flags)) |
484 | conf->working_disks++; | 488 | conf->working_disks++; |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index a1f7147b757f..377cf2a3c333 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -176,14 +176,15 @@ static int create_strip_zones(mddev_t *mddev) | |||
176 | disk_stack_limits(mddev->gendisk, rdev1->bdev, | 176 | disk_stack_limits(mddev->gendisk, rdev1->bdev, |
177 | rdev1->data_offset << 9); | 177 | rdev1->data_offset << 9); |
178 | /* as we don't honour merge_bvec_fn, we must never risk | 178 | /* as we don't honour merge_bvec_fn, we must never risk |
179 | * violating it, so limit ->max_sector to one PAGE, as | 179 | * violating it, so limit ->max_segments to 1, lying within |
180 | * a one page request is never in violation. | 180 | * a single page. |
181 | */ | 181 | */ |
182 | 182 | ||
183 | if (rdev1->bdev->bd_disk->queue->merge_bvec_fn && | 183 | if (rdev1->bdev->bd_disk->queue->merge_bvec_fn) { |
184 | queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) | 184 | blk_queue_max_segments(mddev->queue, 1); |
185 | blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); | 185 | blk_queue_segment_boundary(mddev->queue, |
186 | 186 | PAGE_CACHE_SIZE - 1); | |
187 | } | ||
187 | if (!smallest || (rdev1->sectors < smallest->sectors)) | 188 | if (!smallest || (rdev1->sectors < smallest->sectors)) |
188 | smallest = rdev1; | 189 | smallest = rdev1; |
189 | cnt++; | 190 | cnt++; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 5a06122abd3b..f741f77eeb2b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1152,13 +1152,17 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1152 | 1152 | ||
1153 | disk_stack_limits(mddev->gendisk, rdev->bdev, | 1153 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
1154 | rdev->data_offset << 9); | 1154 | rdev->data_offset << 9); |
1155 | /* as we don't honour merge_bvec_fn, we must never risk | 1155 | /* as we don't honour merge_bvec_fn, we must |
1156 | * violating it, so limit ->max_sector to one PAGE, as | 1156 | * never risk violating it, so limit |
1157 | * a one page request is never in violation. | 1157 | * ->max_segments to one lying with a single |
1158 | * page, as a one page request is never in | ||
1159 | * violation. | ||
1158 | */ | 1160 | */ |
1159 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn && | 1161 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { |
1160 | queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) | 1162 | blk_queue_max_segments(mddev->queue, 1); |
1161 | blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); | 1163 | blk_queue_segment_boundary(mddev->queue, |
1164 | PAGE_CACHE_SIZE - 1); | ||
1165 | } | ||
1162 | 1166 | ||
1163 | p->head_position = 0; | 1167 | p->head_position = 0; |
1164 | rdev->raid_disk = mirror; | 1168 | rdev->raid_disk = mirror; |
@@ -2098,12 +2102,14 @@ static int run(mddev_t *mddev) | |||
2098 | disk_stack_limits(mddev->gendisk, rdev->bdev, | 2102 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
2099 | rdev->data_offset << 9); | 2103 | rdev->data_offset << 9); |
2100 | /* as we don't honour merge_bvec_fn, we must never risk | 2104 | /* as we don't honour merge_bvec_fn, we must never risk |
2101 | * violating it, so limit ->max_sector to one PAGE, as | 2105 | * violating it, so limit ->max_segments to 1 lying within |
2102 | * a one page request is never in violation. | 2106 | * a single page, as a one page request is never in violation. |
2103 | */ | 2107 | */ |
2104 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn && | 2108 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { |
2105 | queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) | 2109 | blk_queue_max_segments(mddev->queue, 1); |
2106 | blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); | 2110 | blk_queue_segment_boundary(mddev->queue, |
2111 | PAGE_CACHE_SIZE - 1); | ||
2112 | } | ||
2107 | } | 2113 | } |
2108 | 2114 | ||
2109 | mddev->degraded = 0; | 2115 | mddev->degraded = 0; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 7584f9ab9bcf..b4ba41ecbd20 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1155,13 +1155,17 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1155 | 1155 | ||
1156 | disk_stack_limits(mddev->gendisk, rdev->bdev, | 1156 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
1157 | rdev->data_offset << 9); | 1157 | rdev->data_offset << 9); |
1158 | /* as we don't honour merge_bvec_fn, we must never risk | 1158 | /* as we don't honour merge_bvec_fn, we must |
1159 | * violating it, so limit ->max_sector to one PAGE, as | 1159 | * never risk violating it, so limit |
1160 | * a one page request is never in violation. | 1160 | * ->max_segments to one lying with a single |
1161 | * page, as a one page request is never in | ||
1162 | * violation. | ||
1161 | */ | 1163 | */ |
1162 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn && | 1164 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { |
1163 | queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) | 1165 | blk_queue_max_segments(mddev->queue, 1); |
1164 | blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); | 1166 | blk_queue_segment_boundary(mddev->queue, |
1167 | PAGE_CACHE_SIZE - 1); | ||
1168 | } | ||
1165 | 1169 | ||
1166 | p->head_position = 0; | 1170 | p->head_position = 0; |
1167 | rdev->raid_disk = mirror; | 1171 | rdev->raid_disk = mirror; |
@@ -2255,12 +2259,14 @@ static int run(mddev_t *mddev) | |||
2255 | disk_stack_limits(mddev->gendisk, rdev->bdev, | 2259 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
2256 | rdev->data_offset << 9); | 2260 | rdev->data_offset << 9); |
2257 | /* as we don't honour merge_bvec_fn, we must never risk | 2261 | /* as we don't honour merge_bvec_fn, we must never risk |
2258 | * violating it, so limit ->max_sector to one PAGE, as | 2262 | * violating it, so limit max_segments to 1 lying |
2259 | * a one page request is never in violation. | 2263 | * within a single page. |
2260 | */ | 2264 | */ |
2261 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn && | 2265 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { |
2262 | queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) | 2266 | blk_queue_max_segments(mddev->queue, 1); |
2263 | blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); | 2267 | blk_queue_segment_boundary(mddev->queue, |
2268 | PAGE_CACHE_SIZE - 1); | ||
2269 | } | ||
2264 | 2270 | ||
2265 | disk->head_position = 0; | 2271 | disk->head_position = 0; |
2266 | } | 2272 | } |
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/drivers/mtd/maps/omap_nor.c +++ /dev/null | |||
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 1157d5679e66..42e5ea49e975 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -457,7 +457,7 @@ config MTD_NAND_NOMADIK | |||
457 | 457 | ||
458 | config MTD_NAND_SH_FLCTL | 458 | config MTD_NAND_SH_FLCTL |
459 | tristate "Support for NAND on Renesas SuperH FLCTL" | 459 | tristate "Support for NAND on Renesas SuperH FLCTL" |
460 | depends on MTD_NAND && SUPERH | 460 | depends on MTD_NAND && (SUPERH || ARCH_SHMOBILE) |
461 | help | 461 | help |
462 | Several Renesas SuperH CPU has FLCTL. This option enables support | 462 | Several Renesas SuperH CPU has FLCTL. This option enables support |
463 | for NAND Flash using FLCTL. | 463 | for NAND Flash using FLCTL. |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 20e2dec1d534..65db201fd77e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -2583,6 +2583,31 @@ config CHELSIO_T3 | |||
2583 | To compile this driver as a module, choose M here: the module | 2583 | To compile this driver as a module, choose M here: the module |
2584 | will be called cxgb3. | 2584 | will be called cxgb3. |
2585 | 2585 | ||
2586 | config CHELSIO_T4_DEPENDS | ||
2587 | tristate | ||
2588 | depends on PCI && INET | ||
2589 | default y | ||
2590 | |||
2591 | config CHELSIO_T4 | ||
2592 | tristate "Chelsio Communications T4 Ethernet support" | ||
2593 | depends on CHELSIO_T4_DEPENDS | ||
2594 | select FW_LOADER | ||
2595 | select MDIO | ||
2596 | help | ||
2597 | This driver supports Chelsio T4-based gigabit and 10Gb Ethernet | ||
2598 | adapters. | ||
2599 | |||
2600 | For general information about Chelsio and our products, visit | ||
2601 | our website at <http://www.chelsio.com>. | ||
2602 | |||
2603 | For customer support, please visit our customer support page at | ||
2604 | <http://www.chelsio.com/support.htm>. | ||
2605 | |||
2606 | Please send feedback to <linux-bugs@chelsio.com>. | ||
2607 | |||
2608 | To compile this driver as a module choose M here; the module | ||
2609 | will be called cxgb4. | ||
2610 | |||
2586 | config EHEA | 2611 | config EHEA |
2587 | tristate "eHEA Ethernet support" | 2612 | tristate "eHEA Ethernet support" |
2588 | depends on IBMEBUS && INET && SPARSEMEM | 2613 | depends on IBMEBUS && INET && SPARSEMEM |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index f8444f439a65..ebf80b983063 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_IXGB) += ixgb/ | |||
19 | obj-$(CONFIG_IP1000) += ipg.o | 19 | obj-$(CONFIG_IP1000) += ipg.o |
20 | obj-$(CONFIG_CHELSIO_T1) += chelsio/ | 20 | obj-$(CONFIG_CHELSIO_T1) += chelsio/ |
21 | obj-$(CONFIG_CHELSIO_T3) += cxgb3/ | 21 | obj-$(CONFIG_CHELSIO_T3) += cxgb3/ |
22 | obj-$(CONFIG_CHELSIO_T4) += cxgb4/ | ||
22 | obj-$(CONFIG_EHEA) += ehea/ | 23 | obj-$(CONFIG_EHEA) += ehea/ |
23 | obj-$(CONFIG_CAN) += can/ | 24 | obj-$(CONFIG_CAN) += can/ |
24 | obj-$(CONFIG_BONDING) += bonding/ | 25 | obj-$(CONFIG_BONDING) += bonding/ |
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 9ba547069db3..0ebd8208f606 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c | |||
@@ -84,7 +84,7 @@ | |||
84 | 84 | ||
85 | #define ATLX_DRIVER_VERSION "2.1.3" | 85 | #define ATLX_DRIVER_VERSION "2.1.3" |
86 | MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \ | 86 | MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \ |
87 | Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>"); | 87 | Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>"); |
88 | MODULE_LICENSE("GPL"); | 88 | MODULE_LICENSE("GPL"); |
89 | MODULE_VERSION(ATLX_DRIVER_VERSION); | 89 | MODULE_VERSION(ATLX_DRIVER_VERSION); |
90 | 90 | ||
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 61a9afdb83f4..da8793026bb1 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -1466,8 +1466,8 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, | |||
1466 | 1466 | ||
1467 | req->params.op_type = cpu_to_le32(IMG_TYPE_REDBOOT); | 1467 | req->params.op_type = cpu_to_le32(IMG_TYPE_REDBOOT); |
1468 | req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT); | 1468 | req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT); |
1469 | req->params.offset = offset; | 1469 | req->params.offset = cpu_to_le32(offset); |
1470 | req->params.data_buf_size = 0x4; | 1470 | req->params.data_buf_size = cpu_to_le32(0x4); |
1471 | 1471 | ||
1472 | status = be_mcc_notify_wait(adapter); | 1472 | status = be_mcc_notify_wait(adapter); |
1473 | if (!status) | 1473 | if (!status) |
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index d7390da470cd..d488d52d710a 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
@@ -490,7 +490,7 @@ be_test_ddr_dma(struct be_adapter *adapter) | |||
490 | { | 490 | { |
491 | int ret, i; | 491 | int ret, i; |
492 | struct be_dma_mem ddrdma_cmd; | 492 | struct be_dma_mem ddrdma_cmd; |
493 | u64 pattern[2] = {0x5a5a5a5a5a5a5a5a, 0xa5a5a5a5a5a5a5a5}; | 493 | u64 pattern[2] = {0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL}; |
494 | 494 | ||
495 | ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test); | 495 | ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test); |
496 | ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size, | 496 | ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size, |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index cb0a4a6d5dea..49d51965312e 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -879,7 +879,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, | |||
879 | return; | 879 | return; |
880 | } | 880 | } |
881 | vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); | 881 | vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); |
882 | vid = be16_to_cpu(vid); | 882 | vid = swab16(vid); |
883 | vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid); | 883 | vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid); |
884 | } else { | 884 | } else { |
885 | netif_receive_skb(skb); | 885 | netif_receive_skb(skb); |
@@ -956,7 +956,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, | |||
956 | napi_gro_frags(&eq_obj->napi); | 956 | napi_gro_frags(&eq_obj->napi); |
957 | } else { | 957 | } else { |
958 | vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); | 958 | vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); |
959 | vid = be16_to_cpu(vid); | 959 | vid = swab16(vid); |
960 | 960 | ||
961 | if (!adapter->vlan_grp || adapter->vlans_added == 0) | 961 | if (!adapter->vlan_grp || adapter->vlans_added == 0) |
962 | return; | 962 | return; |
@@ -1977,7 +1977,7 @@ static bool be_flash_redboot(struct be_adapter *adapter, | |||
1977 | p += crc_offset; | 1977 | p += crc_offset; |
1978 | 1978 | ||
1979 | status = be_cmd_get_flash_crc(adapter, flashed_crc, | 1979 | status = be_cmd_get_flash_crc(adapter, flashed_crc, |
1980 | (img_start + image_size - 4)); | 1980 | (image_size - 4)); |
1981 | if (status) { | 1981 | if (status) { |
1982 | dev_err(&adapter->pdev->dev, | 1982 | dev_err(&adapter->pdev->dev, |
1983 | "could not get crc from flash, not flashing redboot\n"); | 1983 | "could not get crc from flash, not flashing redboot\n"); |
@@ -2113,7 +2113,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) | |||
2113 | struct flash_file_hdr_g3 *fhdr3; | 2113 | struct flash_file_hdr_g3 *fhdr3; |
2114 | struct image_hdr *img_hdr_ptr = NULL; | 2114 | struct image_hdr *img_hdr_ptr = NULL; |
2115 | struct be_dma_mem flash_cmd; | 2115 | struct be_dma_mem flash_cmd; |
2116 | int status, i = 0; | 2116 | int status, i = 0, num_imgs = 0; |
2117 | const u8 *p; | 2117 | const u8 *p; |
2118 | 2118 | ||
2119 | strcpy(fw_file, func); | 2119 | strcpy(fw_file, func); |
@@ -2139,15 +2139,14 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) | |||
2139 | if ((adapter->generation == BE_GEN3) && | 2139 | if ((adapter->generation == BE_GEN3) && |
2140 | (get_ufigen_type(fhdr) == BE_GEN3)) { | 2140 | (get_ufigen_type(fhdr) == BE_GEN3)) { |
2141 | fhdr3 = (struct flash_file_hdr_g3 *) fw->data; | 2141 | fhdr3 = (struct flash_file_hdr_g3 *) fw->data; |
2142 | for (i = 0; i < fhdr3->num_imgs; i++) { | 2142 | num_imgs = le32_to_cpu(fhdr3->num_imgs); |
2143 | for (i = 0; i < num_imgs; i++) { | ||
2143 | img_hdr_ptr = (struct image_hdr *) (fw->data + | 2144 | img_hdr_ptr = (struct image_hdr *) (fw->data + |
2144 | (sizeof(struct flash_file_hdr_g3) + | 2145 | (sizeof(struct flash_file_hdr_g3) + |
2145 | i * sizeof(struct image_hdr))); | 2146 | i * sizeof(struct image_hdr))); |
2146 | if (img_hdr_ptr->imageid == 1) { | 2147 | if (le32_to_cpu(img_hdr_ptr->imageid) == 1) |
2147 | status = be_flash_data(adapter, fw, | 2148 | status = be_flash_data(adapter, fw, &flash_cmd, |
2148 | &flash_cmd, fhdr3->num_imgs); | 2149 | num_imgs); |
2149 | } | ||
2150 | |||
2151 | } | 2150 | } |
2152 | } else if ((adapter->generation == BE_GEN2) && | 2151 | } else if ((adapter->generation == BE_GEN2) && |
2153 | (get_ufigen_type(fhdr) == BE_GEN2)) { | 2152 | (get_ufigen_type(fhdr) == BE_GEN2)) { |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 0b69ffb7951d..802b538502eb 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -246,6 +246,8 @@ static const struct flash_spec flash_5709 = { | |||
246 | 246 | ||
247 | MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); | 247 | MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); |
248 | 248 | ||
249 | static void bnx2_init_napi(struct bnx2 *bp); | ||
250 | |||
249 | static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr) | 251 | static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr) |
250 | { | 252 | { |
251 | u32 diff; | 253 | u32 diff; |
@@ -6196,6 +6198,7 @@ bnx2_open(struct net_device *dev) | |||
6196 | bnx2_disable_int(bp); | 6198 | bnx2_disable_int(bp); |
6197 | 6199 | ||
6198 | bnx2_setup_int_mode(bp, disable_msi); | 6200 | bnx2_setup_int_mode(bp, disable_msi); |
6201 | bnx2_init_napi(bp); | ||
6199 | bnx2_napi_enable(bp); | 6202 | bnx2_napi_enable(bp); |
6200 | rc = bnx2_alloc_mem(bp); | 6203 | rc = bnx2_alloc_mem(bp); |
6201 | if (rc) | 6204 | if (rc) |
@@ -7642,9 +7645,11 @@ poll_bnx2(struct net_device *dev) | |||
7642 | int i; | 7645 | int i; |
7643 | 7646 | ||
7644 | for (i = 0; i < bp->irq_nvecs; i++) { | 7647 | for (i = 0; i < bp->irq_nvecs; i++) { |
7645 | disable_irq(bp->irq_tbl[i].vector); | 7648 | struct bnx2_irq *irq = &bp->irq_tbl[i]; |
7646 | bnx2_interrupt(bp->irq_tbl[i].vector, &bp->bnx2_napi[i]); | 7649 | |
7647 | enable_irq(bp->irq_tbl[i].vector); | 7650 | disable_irq(irq->vector); |
7651 | irq->handler(irq->vector, &bp->bnx2_napi[i]); | ||
7652 | enable_irq(irq->vector); | ||
7648 | } | 7653 | } |
7649 | } | 7654 | } |
7650 | #endif | 7655 | #endif |
@@ -8206,7 +8211,7 @@ bnx2_init_napi(struct bnx2 *bp) | |||
8206 | { | 8211 | { |
8207 | int i; | 8212 | int i; |
8208 | 8213 | ||
8209 | for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) { | 8214 | for (i = 0; i < bp->irq_nvecs; i++) { |
8210 | struct bnx2_napi *bnapi = &bp->bnx2_napi[i]; | 8215 | struct bnx2_napi *bnapi = &bp->bnx2_napi[i]; |
8211 | int (*poll)(struct napi_struct *, int); | 8216 | int (*poll)(struct napi_struct *, int); |
8212 | 8217 | ||
@@ -8275,7 +8280,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
8275 | dev->ethtool_ops = &bnx2_ethtool_ops; | 8280 | dev->ethtool_ops = &bnx2_ethtool_ops; |
8276 | 8281 | ||
8277 | bp = netdev_priv(dev); | 8282 | bp = netdev_priv(dev); |
8278 | bnx2_init_napi(bp); | ||
8279 | 8283 | ||
8280 | pci_set_drvdata(pdev, dev); | 8284 | pci_set_drvdata(pdev, dev); |
8281 | 8285 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 22682f1c8473..85e813c7762b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1162,6 +1162,11 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
1162 | write_lock_bh(&bond->curr_slave_lock); | 1162 | write_lock_bh(&bond->curr_slave_lock); |
1163 | } | 1163 | } |
1164 | } | 1164 | } |
1165 | |||
1166 | /* resend IGMP joins since all were sent on curr_active_slave */ | ||
1167 | if (bond->params.mode == BOND_MODE_ROUNDROBIN) { | ||
1168 | bond_resend_igmp_join_requests(bond); | ||
1169 | } | ||
1165 | } | 1170 | } |
1166 | 1171 | ||
1167 | /** | 1172 | /** |
@@ -4096,22 +4101,41 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev | |||
4096 | struct bonding *bond = netdev_priv(bond_dev); | 4101 | struct bonding *bond = netdev_priv(bond_dev); |
4097 | struct slave *slave, *start_at; | 4102 | struct slave *slave, *start_at; |
4098 | int i, slave_no, res = 1; | 4103 | int i, slave_no, res = 1; |
4104 | struct iphdr *iph = ip_hdr(skb); | ||
4099 | 4105 | ||
4100 | read_lock(&bond->lock); | 4106 | read_lock(&bond->lock); |
4101 | 4107 | ||
4102 | if (!BOND_IS_OK(bond)) | 4108 | if (!BOND_IS_OK(bond)) |
4103 | goto out; | 4109 | goto out; |
4104 | |||
4105 | /* | 4110 | /* |
4106 | * Concurrent TX may collide on rr_tx_counter; we accept that | 4111 | * Start with the curr_active_slave that joined the bond as the |
4107 | * as being rare enough not to justify using an atomic op here | 4112 | * default for sending IGMP traffic. For failover purposes one |
4113 | * needs to maintain some consistency for the interface that will | ||
4114 | * send the join/membership reports. The curr_active_slave found | ||
4115 | * will send all of this type of traffic. | ||
4108 | */ | 4116 | */ |
4109 | slave_no = bond->rr_tx_counter++ % bond->slave_cnt; | 4117 | if ((iph->protocol == IPPROTO_IGMP) && |
4118 | (skb->protocol == htons(ETH_P_IP))) { | ||
4110 | 4119 | ||
4111 | bond_for_each_slave(bond, slave, i) { | 4120 | read_lock(&bond->curr_slave_lock); |
4112 | slave_no--; | 4121 | slave = bond->curr_active_slave; |
4113 | if (slave_no < 0) | 4122 | read_unlock(&bond->curr_slave_lock); |
4114 | break; | 4123 | |
4124 | if (!slave) | ||
4125 | goto out; | ||
4126 | } else { | ||
4127 | /* | ||
4128 | * Concurrent TX may collide on rr_tx_counter; we accept | ||
4129 | * that as being rare enough not to justify using an | ||
4130 | * atomic op here. | ||
4131 | */ | ||
4132 | slave_no = bond->rr_tx_counter++ % bond->slave_cnt; | ||
4133 | |||
4134 | bond_for_each_slave(bond, slave, i) { | ||
4135 | slave_no--; | ||
4136 | if (slave_no < 0) | ||
4137 | break; | ||
4138 | } | ||
4115 | } | 4139 | } |
4116 | 4140 | ||
4117 | start_at = slave; | 4141 | start_at = slave; |
@@ -4384,6 +4408,14 @@ static const struct net_device_ops bond_netdev_ops = { | |||
4384 | .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid, | 4408 | .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid, |
4385 | }; | 4409 | }; |
4386 | 4410 | ||
4411 | static void bond_destructor(struct net_device *bond_dev) | ||
4412 | { | ||
4413 | struct bonding *bond = netdev_priv(bond_dev); | ||
4414 | if (bond->wq) | ||
4415 | destroy_workqueue(bond->wq); | ||
4416 | free_netdev(bond_dev); | ||
4417 | } | ||
4418 | |||
4387 | static void bond_setup(struct net_device *bond_dev) | 4419 | static void bond_setup(struct net_device *bond_dev) |
4388 | { | 4420 | { |
4389 | struct bonding *bond = netdev_priv(bond_dev); | 4421 | struct bonding *bond = netdev_priv(bond_dev); |
@@ -4404,7 +4436,7 @@ static void bond_setup(struct net_device *bond_dev) | |||
4404 | bond_dev->ethtool_ops = &bond_ethtool_ops; | 4436 | bond_dev->ethtool_ops = &bond_ethtool_ops; |
4405 | bond_set_mode_ops(bond, bond->params.mode); | 4437 | bond_set_mode_ops(bond, bond->params.mode); |
4406 | 4438 | ||
4407 | bond_dev->destructor = free_netdev; | 4439 | bond_dev->destructor = bond_destructor; |
4408 | 4440 | ||
4409 | /* Initialize the device options */ | 4441 | /* Initialize the device options */ |
4410 | bond_dev->tx_queue_len = 0; | 4442 | bond_dev->tx_queue_len = 0; |
@@ -4476,9 +4508,6 @@ static void bond_uninit(struct net_device *bond_dev) | |||
4476 | 4508 | ||
4477 | bond_remove_proc_entry(bond); | 4509 | bond_remove_proc_entry(bond); |
4478 | 4510 | ||
4479 | if (bond->wq) | ||
4480 | destroy_workqueue(bond->wq); | ||
4481 | |||
4482 | __hw_addr_flush(&bond->mc_list); | 4511 | __hw_addr_flush(&bond->mc_list); |
4483 | } | 4512 | } |
4484 | 4513 | ||
@@ -4890,8 +4919,8 @@ int bond_create(struct net *net, const char *name) | |||
4890 | bond_setup); | 4919 | bond_setup); |
4891 | if (!bond_dev) { | 4920 | if (!bond_dev) { |
4892 | pr_err("%s: eek! can't alloc netdev!\n", name); | 4921 | pr_err("%s: eek! can't alloc netdev!\n", name); |
4893 | res = -ENOMEM; | 4922 | rtnl_unlock(); |
4894 | goto out; | 4923 | return -ENOMEM; |
4895 | } | 4924 | } |
4896 | 4925 | ||
4897 | dev_net_set(bond_dev, net); | 4926 | dev_net_set(bond_dev, net); |
@@ -4900,19 +4929,16 @@ int bond_create(struct net *net, const char *name) | |||
4900 | if (!name) { | 4929 | if (!name) { |
4901 | res = dev_alloc_name(bond_dev, "bond%d"); | 4930 | res = dev_alloc_name(bond_dev, "bond%d"); |
4902 | if (res < 0) | 4931 | if (res < 0) |
4903 | goto out_netdev; | 4932 | goto out; |
4904 | } | 4933 | } |
4905 | 4934 | ||
4906 | res = register_netdevice(bond_dev); | 4935 | res = register_netdevice(bond_dev); |
4907 | if (res < 0) | ||
4908 | goto out_netdev; | ||
4909 | 4936 | ||
4910 | out: | 4937 | out: |
4911 | rtnl_unlock(); | 4938 | rtnl_unlock(); |
4939 | if (res < 0) | ||
4940 | bond_destructor(bond_dev); | ||
4912 | return res; | 4941 | return res; |
4913 | out_netdev: | ||
4914 | free_netdev(bond_dev); | ||
4915 | goto out; | ||
4916 | } | 4942 | } |
4917 | 4943 | ||
4918 | static int __net_init bond_net_init(struct net *net) | 4944 | static int __net_init bond_net_init(struct net *net) |
diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index 866905fa4119..03489864376d 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/can/dev.h> | 22 | #include <linux/can/dev.h> |
23 | #include <linux/can/error.h> | 23 | #include <linux/can/error.h> |
24 | 24 | ||
25 | #include <asm/bfin_can.h> | ||
25 | #include <asm/portmux.h> | 26 | #include <asm/portmux.h> |
26 | 27 | ||
27 | #define DRV_NAME "bfin_can" | 28 | #define DRV_NAME "bfin_can" |
@@ -29,90 +30,6 @@ | |||
29 | #define TX_ECHO_SKB_MAX 1 | 30 | #define TX_ECHO_SKB_MAX 1 |
30 | 31 | ||
31 | /* | 32 | /* |
32 | * transmit and receive channels | ||
33 | */ | ||
34 | #define TRANSMIT_CHL 24 | ||
35 | #define RECEIVE_STD_CHL 0 | ||
36 | #define RECEIVE_EXT_CHL 4 | ||
37 | #define RECEIVE_RTR_CHL 8 | ||
38 | #define RECEIVE_EXT_RTR_CHL 12 | ||
39 | #define MAX_CHL_NUMBER 32 | ||
40 | |||
41 | /* | ||
42 | * bfin can registers layout | ||
43 | */ | ||
44 | struct bfin_can_mask_regs { | ||
45 | u16 aml; | ||
46 | u16 dummy1; | ||
47 | u16 amh; | ||
48 | u16 dummy2; | ||
49 | }; | ||
50 | |||
51 | struct bfin_can_channel_regs { | ||
52 | u16 data[8]; | ||
53 | u16 dlc; | ||
54 | u16 dummy1; | ||
55 | u16 tsv; | ||
56 | u16 dummy2; | ||
57 | u16 id0; | ||
58 | u16 dummy3; | ||
59 | u16 id1; | ||
60 | u16 dummy4; | ||
61 | }; | ||
62 | |||
63 | struct bfin_can_regs { | ||
64 | /* | ||
65 | * global control and status registers | ||
66 | */ | ||
67 | u16 mc1; /* offset 0 */ | ||
68 | u16 dummy1; | ||
69 | u16 md1; /* offset 4 */ | ||
70 | u16 rsv1[13]; | ||
71 | u16 mbtif1; /* offset 0x20 */ | ||
72 | u16 dummy2; | ||
73 | u16 mbrif1; /* offset 0x24 */ | ||
74 | u16 dummy3; | ||
75 | u16 mbim1; /* offset 0x28 */ | ||
76 | u16 rsv2[11]; | ||
77 | u16 mc2; /* offset 0x40 */ | ||
78 | u16 dummy4; | ||
79 | u16 md2; /* offset 0x44 */ | ||
80 | u16 dummy5; | ||
81 | u16 trs2; /* offset 0x48 */ | ||
82 | u16 rsv3[11]; | ||
83 | u16 mbtif2; /* offset 0x60 */ | ||
84 | u16 dummy6; | ||
85 | u16 mbrif2; /* offset 0x64 */ | ||
86 | u16 dummy7; | ||
87 | u16 mbim2; /* offset 0x68 */ | ||
88 | u16 rsv4[11]; | ||
89 | u16 clk; /* offset 0x80 */ | ||
90 | u16 dummy8; | ||
91 | u16 timing; /* offset 0x84 */ | ||
92 | u16 rsv5[3]; | ||
93 | u16 status; /* offset 0x8c */ | ||
94 | u16 dummy9; | ||
95 | u16 cec; /* offset 0x90 */ | ||
96 | u16 dummy10; | ||
97 | u16 gis; /* offset 0x94 */ | ||
98 | u16 dummy11; | ||
99 | u16 gim; /* offset 0x98 */ | ||
100 | u16 rsv6[3]; | ||
101 | u16 ctrl; /* offset 0xa0 */ | ||
102 | u16 dummy12; | ||
103 | u16 intr; /* offset 0xa4 */ | ||
104 | u16 rsv7[7]; | ||
105 | u16 esr; /* offset 0xb4 */ | ||
106 | u16 rsv8[37]; | ||
107 | |||
108 | /* | ||
109 | * channel(mailbox) mask and message registers | ||
110 | */ | ||
111 | struct bfin_can_mask_regs msk[MAX_CHL_NUMBER]; /* offset 0x100 */ | ||
112 | struct bfin_can_channel_regs chl[MAX_CHL_NUMBER]; /* offset 0x200 */ | ||
113 | }; | ||
114 | |||
115 | /* | ||
116 | * bfin can private data | 33 | * bfin can private data |
117 | */ | 34 | */ |
118 | struct bfin_can_priv { | 35 | struct bfin_can_priv { |
@@ -163,7 +80,7 @@ static int bfin_can_set_bittiming(struct net_device *dev) | |||
163 | if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) | 80 | if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) |
164 | timing |= SAM; | 81 | timing |= SAM; |
165 | 82 | ||
166 | bfin_write16(®->clk, clk); | 83 | bfin_write16(®->clock, clk); |
167 | bfin_write16(®->timing, timing); | 84 | bfin_write16(®->timing, timing); |
168 | 85 | ||
169 | dev_info(dev->dev.parent, "setting CLOCK=0x%04x TIMING=0x%04x\n", | 86 | dev_info(dev->dev.parent, "setting CLOCK=0x%04x TIMING=0x%04x\n", |
@@ -185,11 +102,11 @@ static void bfin_can_set_reset_mode(struct net_device *dev) | |||
185 | bfin_write16(®->gim, 0); | 102 | bfin_write16(®->gim, 0); |
186 | 103 | ||
187 | /* reset can and enter configuration mode */ | 104 | /* reset can and enter configuration mode */ |
188 | bfin_write16(®->ctrl, SRS | CCR); | 105 | bfin_write16(®->control, SRS | CCR); |
189 | SSYNC(); | 106 | SSYNC(); |
190 | bfin_write16(®->ctrl, CCR); | 107 | bfin_write16(®->control, CCR); |
191 | SSYNC(); | 108 | SSYNC(); |
192 | while (!(bfin_read16(®->ctrl) & CCA)) { | 109 | while (!(bfin_read16(®->control) & CCA)) { |
193 | udelay(10); | 110 | udelay(10); |
194 | if (--timeout == 0) { | 111 | if (--timeout == 0) { |
195 | dev_err(dev->dev.parent, | 112 | dev_err(dev->dev.parent, |
@@ -244,7 +161,7 @@ static void bfin_can_set_normal_mode(struct net_device *dev) | |||
244 | /* | 161 | /* |
245 | * leave configuration mode | 162 | * leave configuration mode |
246 | */ | 163 | */ |
247 | bfin_write16(®->ctrl, bfin_read16(®->ctrl) & ~CCR); | 164 | bfin_write16(®->control, bfin_read16(®->control) & ~CCR); |
248 | 165 | ||
249 | while (bfin_read16(®->status) & CCA) { | 166 | while (bfin_read16(®->status) & CCA) { |
250 | udelay(10); | 167 | udelay(10); |
@@ -726,7 +643,7 @@ static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
726 | 643 | ||
727 | if (netif_running(dev)) { | 644 | if (netif_running(dev)) { |
728 | /* enter sleep mode */ | 645 | /* enter sleep mode */ |
729 | bfin_write16(®->ctrl, bfin_read16(®->ctrl) | SMR); | 646 | bfin_write16(®->control, bfin_read16(®->control) | SMR); |
730 | SSYNC(); | 647 | SSYNC(); |
731 | while (!(bfin_read16(®->intr) & SMACK)) { | 648 | while (!(bfin_read16(®->intr) & SMACK)) { |
732 | udelay(10); | 649 | udelay(10); |
diff --git a/drivers/net/cxgb4/Makefile b/drivers/net/cxgb4/Makefile new file mode 100644 index 000000000000..498667487f52 --- /dev/null +++ b/drivers/net/cxgb4/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Chelsio T4 driver | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_CHELSIO_T4) += cxgb4.o | ||
6 | |||
7 | cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o | ||
diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h new file mode 100644 index 000000000000..3d8ff4889b56 --- /dev/null +++ b/drivers/net/cxgb4/cxgb4.h | |||
@@ -0,0 +1,741 @@ | |||
1 | /* | ||
2 | * This file is part of the Chelsio T4 Ethernet driver for Linux. | ||
3 | * | ||
4 | * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved. | ||
5 | * | ||
6 | * This software is available to you under a choice of one of two | ||
7 | * licenses. You may choose to be licensed under the terms of the GNU | ||
8 | * General Public License (GPL) Version 2, available from the file | ||
9 | * COPYING in the main directory of this source tree, or the | ||
10 | * OpenIB.org BSD license below: | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or | ||
13 | * without modification, are permitted provided that the following | ||
14 | * conditions are met: | ||
15 | * | ||
16 | * - Redistributions of source code must retain the above | ||
17 | * copyright notice, this list of conditions and the following | ||
18 | * disclaimer. | ||
19 | * | ||
20 | * - Redistributions in binary form must reproduce the above | ||
21 | * copyright notice, this list of conditions and the following | ||
22 | * disclaimer in the documentation and/or other materials | ||
23 | * provided with the distribution. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
32 | * SOFTWARE. | ||
33 | */ | ||
34 | |||
35 | #ifndef __CXGB4_H__ | ||
36 | #define __CXGB4_H__ | ||
37 | |||
38 | #include <linux/bitops.h> | ||
39 | #include <linux/cache.h> | ||
40 | #include <linux/interrupt.h> | ||
41 | #include <linux/list.h> | ||
42 | #include <linux/netdevice.h> | ||
43 | #include <linux/pci.h> | ||
44 | #include <linux/spinlock.h> | ||
45 | #include <linux/timer.h> | ||
46 | #include <asm/io.h> | ||
47 | #include "cxgb4_uld.h" | ||
48 | #include "t4_hw.h" | ||
49 | |||
50 | #define FW_VERSION_MAJOR 1 | ||
51 | #define FW_VERSION_MINOR 1 | ||
52 | #define FW_VERSION_MICRO 0 | ||
53 | |||
54 | enum { | ||
55 | MAX_NPORTS = 4, /* max # of ports */ | ||
56 | SERNUM_LEN = 16, /* Serial # length */ | ||
57 | EC_LEN = 16, /* E/C length */ | ||
58 | ID_LEN = 16, /* ID length */ | ||
59 | }; | ||
60 | |||
61 | enum { | ||
62 | MEM_EDC0, | ||
63 | MEM_EDC1, | ||
64 | MEM_MC | ||
65 | }; | ||
66 | |||
67 | enum dev_master { | ||
68 | MASTER_CANT, | ||
69 | MASTER_MAY, | ||
70 | MASTER_MUST | ||
71 | }; | ||
72 | |||
73 | enum dev_state { | ||
74 | DEV_STATE_UNINIT, | ||
75 | DEV_STATE_INIT, | ||
76 | DEV_STATE_ERR | ||
77 | }; | ||
78 | |||
79 | enum { | ||
80 | PAUSE_RX = 1 << 0, | ||
81 | PAUSE_TX = 1 << 1, | ||
82 | PAUSE_AUTONEG = 1 << 2 | ||
83 | }; | ||
84 | |||
85 | struct port_stats { | ||
86 | u64 tx_octets; /* total # of octets in good frames */ | ||
87 | u64 tx_frames; /* all good frames */ | ||
88 | u64 tx_bcast_frames; /* all broadcast frames */ | ||
89 | u64 tx_mcast_frames; /* all multicast frames */ | ||
90 | u64 tx_ucast_frames; /* all unicast frames */ | ||
91 | u64 tx_error_frames; /* all error frames */ | ||
92 | |||
93 | u64 tx_frames_64; /* # of Tx frames in a particular range */ | ||
94 | u64 tx_frames_65_127; | ||
95 | u64 tx_frames_128_255; | ||
96 | u64 tx_frames_256_511; | ||
97 | u64 tx_frames_512_1023; | ||
98 | u64 tx_frames_1024_1518; | ||
99 | u64 tx_frames_1519_max; | ||
100 | |||
101 | u64 tx_drop; /* # of dropped Tx frames */ | ||
102 | u64 tx_pause; /* # of transmitted pause frames */ | ||
103 | u64 tx_ppp0; /* # of transmitted PPP prio 0 frames */ | ||
104 | u64 tx_ppp1; /* # of transmitted PPP prio 1 frames */ | ||
105 | u64 tx_ppp2; /* # of transmitted PPP prio 2 frames */ | ||
106 | u64 tx_ppp3; /* # of transmitted PPP prio 3 frames */ | ||
107 | u64 tx_ppp4; /* # of transmitted PPP prio 4 frames */ | ||
108 | u64 tx_ppp5; /* # of transmitted PPP prio 5 frames */ | ||
109 | u64 tx_ppp6; /* # of transmitted PPP prio 6 frames */ | ||
110 | u64 tx_ppp7; /* # of transmitted PPP prio 7 frames */ | ||
111 | |||
112 | u64 rx_octets; /* total # of octets in good frames */ | ||
113 | u64 rx_frames; /* all good frames */ | ||
114 | u64 rx_bcast_frames; /* all broadcast frames */ | ||
115 | u64 rx_mcast_frames; /* all multicast frames */ | ||
116 | u64 rx_ucast_frames; /* all unicast frames */ | ||
117 | u64 rx_too_long; /* # of frames exceeding MTU */ | ||
118 | u64 rx_jabber; /* # of jabber frames */ | ||
119 | u64 rx_fcs_err; /* # of received frames with bad FCS */ | ||
120 | u64 rx_len_err; /* # of received frames with length error */ | ||
121 | u64 rx_symbol_err; /* symbol errors */ | ||
122 | u64 rx_runt; /* # of short frames */ | ||
123 | |||
124 | u64 rx_frames_64; /* # of Rx frames in a particular range */ | ||
125 | u64 rx_frames_65_127; | ||
126 | u64 rx_frames_128_255; | ||
127 | u64 rx_frames_256_511; | ||
128 | u64 rx_frames_512_1023; | ||
129 | u64 rx_frames_1024_1518; | ||
130 | u64 rx_frames_1519_max; | ||
131 | |||
132 | u64 rx_pause; /* # of received pause frames */ | ||
133 | u64 rx_ppp0; /* # of received PPP prio 0 frames */ | ||
134 | u64 rx_ppp1; /* # of received PPP prio 1 frames */ | ||
135 | u64 rx_ppp2; /* # of received PPP prio 2 frames */ | ||
136 | u64 rx_ppp3; /* # of received PPP prio 3 frames */ | ||
137 | u64 rx_ppp4; /* # of received PPP prio 4 frames */ | ||
138 | u64 rx_ppp5; /* # of received PPP prio 5 frames */ | ||
139 | u64 rx_ppp6; /* # of received PPP prio 6 frames */ | ||
140 | u64 rx_ppp7; /* # of received PPP prio 7 frames */ | ||
141 | |||
142 | u64 rx_ovflow0; /* drops due to buffer-group 0 overflows */ | ||
143 | u64 rx_ovflow1; /* drops due to buffer-group 1 overflows */ | ||
144 | u64 rx_ovflow2; /* drops due to buffer-group 2 overflows */ | ||
145 | u64 rx_ovflow3; /* drops due to buffer-group 3 overflows */ | ||
146 | u64 rx_trunc0; /* buffer-group 0 truncated packets */ | ||
147 | u64 rx_trunc1; /* buffer-group 1 truncated packets */ | ||
148 | u64 rx_trunc2; /* buffer-group 2 truncated packets */ | ||
149 | u64 rx_trunc3; /* buffer-group 3 truncated packets */ | ||
150 | }; | ||
151 | |||
152 | struct lb_port_stats { | ||
153 | u64 octets; | ||
154 | u64 frames; | ||
155 | u64 bcast_frames; | ||
156 | u64 mcast_frames; | ||
157 | u64 ucast_frames; | ||
158 | u64 error_frames; | ||
159 | |||
160 | u64 frames_64; | ||
161 | u64 frames_65_127; | ||
162 | u64 frames_128_255; | ||
163 | u64 frames_256_511; | ||
164 | u64 frames_512_1023; | ||
165 | u64 frames_1024_1518; | ||
166 | u64 frames_1519_max; | ||
167 | |||
168 | u64 drop; | ||
169 | |||
170 | u64 ovflow0; | ||
171 | u64 ovflow1; | ||
172 | u64 ovflow2; | ||
173 | u64 ovflow3; | ||
174 | u64 trunc0; | ||
175 | u64 trunc1; | ||
176 | u64 trunc2; | ||
177 | u64 trunc3; | ||
178 | }; | ||
179 | |||
180 | struct tp_tcp_stats { | ||
181 | u32 tcpOutRsts; | ||
182 | u64 tcpInSegs; | ||
183 | u64 tcpOutSegs; | ||
184 | u64 tcpRetransSegs; | ||
185 | }; | ||
186 | |||
187 | struct tp_err_stats { | ||
188 | u32 macInErrs[4]; | ||
189 | u32 hdrInErrs[4]; | ||
190 | u32 tcpInErrs[4]; | ||
191 | u32 tnlCongDrops[4]; | ||
192 | u32 ofldChanDrops[4]; | ||
193 | u32 tnlTxDrops[4]; | ||
194 | u32 ofldVlanDrops[4]; | ||
195 | u32 tcp6InErrs[4]; | ||
196 | u32 ofldNoNeigh; | ||
197 | u32 ofldCongDefer; | ||
198 | }; | ||
199 | |||
200 | struct tp_params { | ||
201 | unsigned int ntxchan; /* # of Tx channels */ | ||
202 | unsigned int tre; /* log2 of core clocks per TP tick */ | ||
203 | }; | ||
204 | |||
205 | struct vpd_params { | ||
206 | unsigned int cclk; | ||
207 | u8 ec[EC_LEN + 1]; | ||
208 | u8 sn[SERNUM_LEN + 1]; | ||
209 | u8 id[ID_LEN + 1]; | ||
210 | }; | ||
211 | |||
212 | struct pci_params { | ||
213 | unsigned char speed; | ||
214 | unsigned char width; | ||
215 | }; | ||
216 | |||
217 | struct adapter_params { | ||
218 | struct tp_params tp; | ||
219 | struct vpd_params vpd; | ||
220 | struct pci_params pci; | ||
221 | |||
222 | unsigned int fw_vers; | ||
223 | unsigned int tp_vers; | ||
224 | u8 api_vers[7]; | ||
225 | |||
226 | unsigned short mtus[NMTUS]; | ||
227 | unsigned short a_wnd[NCCTRL_WIN]; | ||
228 | unsigned short b_wnd[NCCTRL_WIN]; | ||
229 | |||
230 | unsigned char nports; /* # of ethernet ports */ | ||
231 | unsigned char portvec; | ||
232 | unsigned char rev; /* chip revision */ | ||
233 | unsigned char offload; | ||
234 | |||
235 | unsigned int ofldq_wr_cred; | ||
236 | }; | ||
237 | |||
238 | struct trace_params { | ||
239 | u32 data[TRACE_LEN / 4]; | ||
240 | u32 mask[TRACE_LEN / 4]; | ||
241 | unsigned short snap_len; | ||
242 | unsigned short min_len; | ||
243 | unsigned char skip_ofst; | ||
244 | unsigned char skip_len; | ||
245 | unsigned char invert; | ||
246 | unsigned char port; | ||
247 | }; | ||
248 | |||
249 | struct link_config { | ||
250 | unsigned short supported; /* link capabilities */ | ||
251 | unsigned short advertising; /* advertised capabilities */ | ||
252 | unsigned short requested_speed; /* speed user has requested */ | ||
253 | unsigned short speed; /* actual link speed */ | ||
254 | unsigned char requested_fc; /* flow control user has requested */ | ||
255 | unsigned char fc; /* actual link flow control */ | ||
256 | unsigned char autoneg; /* autonegotiating? */ | ||
257 | unsigned char link_ok; /* link up? */ | ||
258 | }; | ||
259 | |||
260 | #define FW_LEN16(fw_struct) FW_CMD_LEN16(sizeof(fw_struct) / 16) | ||
261 | |||
262 | enum { | ||
263 | MAX_ETH_QSETS = 32, /* # of Ethernet Tx/Rx queue sets */ | ||
264 | MAX_OFLD_QSETS = 16, /* # of offload Tx/Rx queue sets */ | ||
265 | MAX_CTRL_QUEUES = NCHAN, /* # of control Tx queues */ | ||
266 | MAX_RDMA_QUEUES = NCHAN, /* # of streaming RDMA Rx queues */ | ||
267 | }; | ||
268 | |||
269 | enum { | ||
270 | MAX_EGRQ = 128, /* max # of egress queues, including FLs */ | ||
271 | MAX_INGQ = 64 /* max # of interrupt-capable ingress queues */ | ||
272 | }; | ||
273 | |||
274 | struct adapter; | ||
275 | struct vlan_group; | ||
276 | struct sge_rspq; | ||
277 | |||
278 | struct port_info { | ||
279 | struct adapter *adapter; | ||
280 | struct vlan_group *vlan_grp; | ||
281 | u16 viid; | ||
282 | s16 xact_addr_filt; /* index of exact MAC address filter */ | ||
283 | u16 rss_size; /* size of VI's RSS table slice */ | ||
284 | s8 mdio_addr; | ||
285 | u8 port_type; | ||
286 | u8 mod_type; | ||
287 | u8 port_id; | ||
288 | u8 tx_chan; | ||
289 | u8 lport; /* associated offload logical port */ | ||
290 | u8 rx_offload; /* CSO, etc */ | ||
291 | u8 nqsets; /* # of qsets */ | ||
292 | u8 first_qset; /* index of first qset */ | ||
293 | struct link_config link_cfg; | ||
294 | }; | ||
295 | |||
296 | /* port_info.rx_offload flags */ | ||
297 | enum { | ||
298 | RX_CSO = 1 << 0, | ||
299 | }; | ||
300 | |||
301 | struct dentry; | ||
302 | struct work_struct; | ||
303 | |||
304 | enum { /* adapter flags */ | ||
305 | FULL_INIT_DONE = (1 << 0), | ||
306 | USING_MSI = (1 << 1), | ||
307 | USING_MSIX = (1 << 2), | ||
308 | QUEUES_BOUND = (1 << 3), | ||
309 | FW_OK = (1 << 4), | ||
310 | }; | ||
311 | |||
312 | struct rx_sw_desc; | ||
313 | |||
314 | struct sge_fl { /* SGE free-buffer queue state */ | ||
315 | unsigned int avail; /* # of available Rx buffers */ | ||
316 | unsigned int pend_cred; /* new buffers since last FL DB ring */ | ||
317 | unsigned int cidx; /* consumer index */ | ||
318 | unsigned int pidx; /* producer index */ | ||
319 | unsigned long alloc_failed; /* # of times buffer allocation failed */ | ||
320 | unsigned long large_alloc_failed; | ||
321 | unsigned long starving; | ||
322 | /* RO fields */ | ||
323 | unsigned int cntxt_id; /* SGE context id for the free list */ | ||
324 | unsigned int size; /* capacity of free list */ | ||
325 | struct rx_sw_desc *sdesc; /* address of SW Rx descriptor ring */ | ||
326 | __be64 *desc; /* address of HW Rx descriptor ring */ | ||
327 | dma_addr_t addr; /* bus address of HW ring start */ | ||
328 | }; | ||
329 | |||
330 | /* A packet gather list */ | ||
331 | struct pkt_gl { | ||
332 | skb_frag_t frags[MAX_SKB_FRAGS]; | ||
333 | void *va; /* virtual address of first byte */ | ||
334 | unsigned int nfrags; /* # of fragments */ | ||
335 | unsigned int tot_len; /* total length of fragments */ | ||
336 | }; | ||
337 | |||
338 | typedef int (*rspq_handler_t)(struct sge_rspq *q, const __be64 *rsp, | ||
339 | const struct pkt_gl *gl); | ||
340 | |||
341 | struct sge_rspq { /* state for an SGE response queue */ | ||
342 | struct napi_struct napi; | ||
343 | const __be64 *cur_desc; /* current descriptor in queue */ | ||
344 | unsigned int cidx; /* consumer index */ | ||
345 | u8 gen; /* current generation bit */ | ||
346 | u8 intr_params; /* interrupt holdoff parameters */ | ||
347 | u8 next_intr_params; /* holdoff params for next interrupt */ | ||
348 | u8 pktcnt_idx; /* interrupt packet threshold */ | ||
349 | u8 uld; /* ULD handling this queue */ | ||
350 | u8 idx; /* queue index within its group */ | ||
351 | int offset; /* offset into current Rx buffer */ | ||
352 | u16 cntxt_id; /* SGE context id for the response q */ | ||
353 | u16 abs_id; /* absolute SGE id for the response q */ | ||
354 | __be64 *desc; /* address of HW response ring */ | ||
355 | dma_addr_t phys_addr; /* physical address of the ring */ | ||
356 | unsigned int iqe_len; /* entry size */ | ||
357 | unsigned int size; /* capacity of response queue */ | ||
358 | struct adapter *adap; | ||
359 | struct net_device *netdev; /* associated net device */ | ||
360 | rspq_handler_t handler; | ||
361 | }; | ||
362 | |||
363 | struct sge_eth_stats { /* Ethernet queue statistics */ | ||
364 | unsigned long pkts; /* # of ethernet packets */ | ||
365 | unsigned long lro_pkts; /* # of LRO super packets */ | ||
366 | unsigned long lro_merged; /* # of wire packets merged by LRO */ | ||
367 | unsigned long rx_cso; /* # of Rx checksum offloads */ | ||
368 | unsigned long vlan_ex; /* # of Rx VLAN extractions */ | ||
369 | unsigned long rx_drops; /* # of packets dropped due to no mem */ | ||
370 | }; | ||
371 | |||
372 | struct sge_eth_rxq { /* SW Ethernet Rx queue */ | ||
373 | struct sge_rspq rspq; | ||
374 | struct sge_fl fl; | ||
375 | struct sge_eth_stats stats; | ||
376 | } ____cacheline_aligned_in_smp; | ||
377 | |||
378 | struct sge_ofld_stats { /* offload queue statistics */ | ||
379 | unsigned long pkts; /* # of packets */ | ||
380 | unsigned long imm; /* # of immediate-data packets */ | ||
381 | unsigned long an; /* # of asynchronous notifications */ | ||
382 | unsigned long nomem; /* # of responses deferred due to no mem */ | ||
383 | }; | ||
384 | |||
385 | struct sge_ofld_rxq { /* SW offload Rx queue */ | ||
386 | struct sge_rspq rspq; | ||
387 | struct sge_fl fl; | ||
388 | struct sge_ofld_stats stats; | ||
389 | } ____cacheline_aligned_in_smp; | ||
390 | |||
391 | struct tx_desc { | ||
392 | __be64 flit[8]; | ||
393 | }; | ||
394 | |||
395 | struct tx_sw_desc; | ||
396 | |||
397 | struct sge_txq { | ||
398 | unsigned int in_use; /* # of in-use Tx descriptors */ | ||
399 | unsigned int size; /* # of descriptors */ | ||
400 | unsigned int cidx; /* SW consumer index */ | ||
401 | unsigned int pidx; /* producer index */ | ||
402 | unsigned long stops; /* # of times q has been stopped */ | ||
403 | unsigned long restarts; /* # of queue restarts */ | ||
404 | unsigned int cntxt_id; /* SGE context id for the Tx q */ | ||
405 | struct tx_desc *desc; /* address of HW Tx descriptor ring */ | ||
406 | struct tx_sw_desc *sdesc; /* address of SW Tx descriptor ring */ | ||
407 | struct sge_qstat *stat; /* queue status entry */ | ||
408 | dma_addr_t phys_addr; /* physical address of the ring */ | ||
409 | }; | ||
410 | |||
411 | struct sge_eth_txq { /* state for an SGE Ethernet Tx queue */ | ||
412 | struct sge_txq q; | ||
413 | struct netdev_queue *txq; /* associated netdev TX queue */ | ||
414 | unsigned long tso; /* # of TSO requests */ | ||
415 | unsigned long tx_cso; /* # of Tx checksum offloads */ | ||
416 | unsigned long vlan_ins; /* # of Tx VLAN insertions */ | ||
417 | unsigned long mapping_err; /* # of I/O MMU packet mapping errors */ | ||
418 | } ____cacheline_aligned_in_smp; | ||
419 | |||
420 | struct sge_ofld_txq { /* state for an SGE offload Tx queue */ | ||
421 | struct sge_txq q; | ||
422 | struct adapter *adap; | ||
423 | struct sk_buff_head sendq; /* list of backpressured packets */ | ||
424 | struct tasklet_struct qresume_tsk; /* restarts the queue */ | ||
425 | u8 full; /* the Tx ring is full */ | ||
426 | unsigned long mapping_err; /* # of I/O MMU packet mapping errors */ | ||
427 | } ____cacheline_aligned_in_smp; | ||
428 | |||
429 | struct sge_ctrl_txq { /* state for an SGE control Tx queue */ | ||
430 | struct sge_txq q; | ||
431 | struct adapter *adap; | ||
432 | struct sk_buff_head sendq; /* list of backpressured packets */ | ||
433 | struct tasklet_struct qresume_tsk; /* restarts the queue */ | ||
434 | u8 full; /* the Tx ring is full */ | ||
435 | } ____cacheline_aligned_in_smp; | ||
436 | |||
437 | struct sge { | ||
438 | struct sge_eth_txq ethtxq[MAX_ETH_QSETS]; | ||
439 | struct sge_ofld_txq ofldtxq[MAX_OFLD_QSETS]; | ||
440 | struct sge_ctrl_txq ctrlq[MAX_CTRL_QUEUES]; | ||
441 | |||
442 | struct sge_eth_rxq ethrxq[MAX_ETH_QSETS]; | ||
443 | struct sge_ofld_rxq ofldrxq[MAX_OFLD_QSETS]; | ||
444 | struct sge_ofld_rxq rdmarxq[MAX_RDMA_QUEUES]; | ||
445 | struct sge_rspq fw_evtq ____cacheline_aligned_in_smp; | ||
446 | |||
447 | struct sge_rspq intrq ____cacheline_aligned_in_smp; | ||
448 | spinlock_t intrq_lock; | ||
449 | |||
450 | u16 max_ethqsets; /* # of available Ethernet queue sets */ | ||
451 | u16 ethqsets; /* # of active Ethernet queue sets */ | ||
452 | u16 ethtxq_rover; /* Tx queue to clean up next */ | ||
453 | u16 ofldqsets; /* # of active offload queue sets */ | ||
454 | u16 rdmaqs; /* # of available RDMA Rx queues */ | ||
455 | u16 ofld_rxq[MAX_OFLD_QSETS]; | ||
456 | u16 rdma_rxq[NCHAN]; | ||
457 | u16 timer_val[SGE_NTIMERS]; | ||
458 | u8 counter_val[SGE_NCOUNTERS]; | ||
459 | unsigned int starve_thres; | ||
460 | u8 idma_state[2]; | ||
461 | void *egr_map[MAX_EGRQ]; /* qid->queue egress queue map */ | ||
462 | struct sge_rspq *ingr_map[MAX_INGQ]; /* qid->queue ingress queue map */ | ||
463 | DECLARE_BITMAP(starving_fl, MAX_EGRQ); | ||
464 | DECLARE_BITMAP(txq_maperr, MAX_EGRQ); | ||
465 | struct timer_list rx_timer; /* refills starving FLs */ | ||
466 | struct timer_list tx_timer; /* checks Tx queues */ | ||
467 | }; | ||
468 | |||
469 | #define for_each_ethrxq(sge, i) for (i = 0; i < (sge)->ethqsets; i++) | ||
470 | #define for_each_ofldrxq(sge, i) for (i = 0; i < (sge)->ofldqsets; i++) | ||
471 | #define for_each_rdmarxq(sge, i) for (i = 0; i < (sge)->rdmaqs; i++) | ||
472 | |||
473 | struct l2t_data; | ||
474 | |||
475 | struct adapter { | ||
476 | void __iomem *regs; | ||
477 | struct pci_dev *pdev; | ||
478 | struct device *pdev_dev; | ||
479 | unsigned long registered_device_map; | ||
480 | unsigned long open_device_map; | ||
481 | unsigned long flags; | ||
482 | |||
483 | const char *name; | ||
484 | int msg_enable; | ||
485 | |||
486 | struct adapter_params params; | ||
487 | struct cxgb4_virt_res vres; | ||
488 | unsigned int swintr; | ||
489 | |||
490 | unsigned int wol; | ||
491 | |||
492 | struct { | ||
493 | unsigned short vec; | ||
494 | char desc[14]; | ||
495 | } msix_info[MAX_INGQ + 1]; | ||
496 | |||
497 | struct sge sge; | ||
498 | |||
499 | struct net_device *port[MAX_NPORTS]; | ||
500 | u8 chan_map[NCHAN]; /* channel -> port map */ | ||
501 | |||
502 | struct l2t_data *l2t; | ||
503 | void *uld_handle[CXGB4_ULD_MAX]; | ||
504 | struct list_head list_node; | ||
505 | |||
506 | struct tid_info tids; | ||
507 | void **tid_release_head; | ||
508 | spinlock_t tid_release_lock; | ||
509 | struct work_struct tid_release_task; | ||
510 | bool tid_release_task_busy; | ||
511 | |||
512 | struct dentry *debugfs_root; | ||
513 | |||
514 | spinlock_t stats_lock; | ||
515 | }; | ||
516 | |||
517 | static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr) | ||
518 | { | ||
519 | return readl(adap->regs + reg_addr); | ||
520 | } | ||
521 | |||
522 | static inline void t4_write_reg(struct adapter *adap, u32 reg_addr, u32 val) | ||
523 | { | ||
524 | writel(val, adap->regs + reg_addr); | ||
525 | } | ||
526 | |||
527 | #ifndef readq | ||
528 | static inline u64 readq(const volatile void __iomem *addr) | ||
529 | { | ||
530 | return readl(addr) + ((u64)readl(addr + 4) << 32); | ||
531 | } | ||
532 | |||
533 | static inline void writeq(u64 val, volatile void __iomem *addr) | ||
534 | { | ||
535 | writel(val, addr); | ||
536 | writel(val >> 32, addr + 4); | ||
537 | } | ||
538 | #endif | ||
539 | |||
540 | static inline u64 t4_read_reg64(struct adapter *adap, u32 reg_addr) | ||
541 | { | ||
542 | return readq(adap->regs + reg_addr); | ||
543 | } | ||
544 | |||
545 | static inline void t4_write_reg64(struct adapter *adap, u32 reg_addr, u64 val) | ||
546 | { | ||
547 | writeq(val, adap->regs + reg_addr); | ||
548 | } | ||
549 | |||
550 | /** | ||
551 | * netdev2pinfo - return the port_info structure associated with a net_device | ||
552 | * @dev: the netdev | ||
553 | * | ||
554 | * Return the struct port_info associated with a net_device | ||
555 | */ | ||
556 | static inline struct port_info *netdev2pinfo(const struct net_device *dev) | ||
557 | { | ||
558 | return netdev_priv(dev); | ||
559 | } | ||
560 | |||
561 | /** | ||
562 | * adap2pinfo - return the port_info of a port | ||
563 | * @adap: the adapter | ||
564 | * @idx: the port index | ||
565 | * | ||
566 | * Return the port_info structure for the port of the given index. | ||
567 | */ | ||
568 | static inline struct port_info *adap2pinfo(struct adapter *adap, int idx) | ||
569 | { | ||
570 | return netdev_priv(adap->port[idx]); | ||
571 | } | ||
572 | |||
573 | /** | ||
574 | * netdev2adap - return the adapter structure associated with a net_device | ||
575 | * @dev: the netdev | ||
576 | * | ||
577 | * Return the struct adapter associated with a net_device | ||
578 | */ | ||
579 | static inline struct adapter *netdev2adap(const struct net_device *dev) | ||
580 | { | ||
581 | return netdev2pinfo(dev)->adapter; | ||
582 | } | ||
583 | |||
584 | void t4_os_portmod_changed(const struct adapter *adap, int port_id); | ||
585 | void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat); | ||
586 | |||
587 | void *t4_alloc_mem(size_t size); | ||
588 | void t4_free_mem(void *addr); | ||
589 | |||
590 | void t4_free_sge_resources(struct adapter *adap); | ||
591 | irq_handler_t t4_intr_handler(struct adapter *adap); | ||
592 | netdev_tx_t t4_eth_xmit(struct sk_buff *skb, struct net_device *dev); | ||
593 | int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, | ||
594 | const struct pkt_gl *gl); | ||
595 | int t4_mgmt_tx(struct adapter *adap, struct sk_buff *skb); | ||
596 | int t4_ofld_send(struct adapter *adap, struct sk_buff *skb); | ||
597 | int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, | ||
598 | struct net_device *dev, int intr_idx, | ||
599 | struct sge_fl *fl, rspq_handler_t hnd); | ||
600 | int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, | ||
601 | struct net_device *dev, struct netdev_queue *netdevq, | ||
602 | unsigned int iqid); | ||
603 | int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, | ||
604 | struct net_device *dev, unsigned int iqid, | ||
605 | unsigned int cmplqid); | ||
606 | int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq, | ||
607 | struct net_device *dev, unsigned int iqid); | ||
608 | irqreturn_t t4_sge_intr_msix(int irq, void *cookie); | ||
609 | void t4_sge_init(struct adapter *adap); | ||
610 | void t4_sge_start(struct adapter *adap); | ||
611 | void t4_sge_stop(struct adapter *adap); | ||
612 | |||
613 | #define for_each_port(adapter, iter) \ | ||
614 | for (iter = 0; iter < (adapter)->params.nports; ++iter) | ||
615 | |||
616 | static inline unsigned int core_ticks_per_usec(const struct adapter *adap) | ||
617 | { | ||
618 | return adap->params.vpd.cclk / 1000; | ||
619 | } | ||
620 | |||
621 | static inline unsigned int us_to_core_ticks(const struct adapter *adap, | ||
622 | unsigned int us) | ||
623 | { | ||
624 | return (us * adap->params.vpd.cclk) / 1000; | ||
625 | } | ||
626 | |||
627 | void t4_set_reg_field(struct adapter *adap, unsigned int addr, u32 mask, | ||
628 | u32 val); | ||
629 | |||
630 | int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, | ||
631 | void *rpl, bool sleep_ok); | ||
632 | |||
633 | static inline int t4_wr_mbox(struct adapter *adap, int mbox, const void *cmd, | ||
634 | int size, void *rpl) | ||
635 | { | ||
636 | return t4_wr_mbox_meat(adap, mbox, cmd, size, rpl, true); | ||
637 | } | ||
638 | |||
639 | static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd, | ||
640 | int size, void *rpl) | ||
641 | { | ||
642 | return t4_wr_mbox_meat(adap, mbox, cmd, size, rpl, false); | ||
643 | } | ||
644 | |||
645 | void t4_intr_enable(struct adapter *adapter); | ||
646 | void t4_intr_disable(struct adapter *adapter); | ||
647 | void t4_intr_clear(struct adapter *adapter); | ||
648 | int t4_slow_intr_handler(struct adapter *adapter); | ||
649 | |||
650 | int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port, | ||
651 | struct link_config *lc); | ||
652 | int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port); | ||
653 | int t4_seeprom_wp(struct adapter *adapter, bool enable); | ||
654 | int t4_read_flash(struct adapter *adapter, unsigned int addr, | ||
655 | unsigned int nwords, u32 *data, int byte_oriented); | ||
656 | int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size); | ||
657 | int t4_check_fw_version(struct adapter *adapter); | ||
658 | int t4_prep_adapter(struct adapter *adapter); | ||
659 | int t4_port_init(struct adapter *adap, int mbox, int pf, int vf); | ||
660 | void t4_fatal_err(struct adapter *adapter); | ||
661 | void t4_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on); | ||
662 | int t4_set_trace_filter(struct adapter *adapter, const struct trace_params *tp, | ||
663 | int filter_index, int enable); | ||
664 | void t4_get_trace_filter(struct adapter *adapter, struct trace_params *tp, | ||
665 | int filter_index, int *enabled); | ||
666 | int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, | ||
667 | int start, int n, const u16 *rspq, unsigned int nrspq); | ||
668 | int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode, | ||
669 | unsigned int flags); | ||
670 | int t4_read_rss(struct adapter *adapter, u16 *entries); | ||
671 | int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *parity); | ||
672 | int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, | ||
673 | u64 *parity); | ||
674 | |||
675 | void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p); | ||
676 | void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p); | ||
677 | |||
678 | void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log); | ||
679 | void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st); | ||
680 | void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, | ||
681 | struct tp_tcp_stats *v6); | ||
682 | void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, | ||
683 | const unsigned short *alpha, const unsigned short *beta); | ||
684 | |||
685 | void t4_wol_magic_enable(struct adapter *adap, unsigned int port, | ||
686 | const u8 *addr); | ||
687 | int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, | ||
688 | u64 mask0, u64 mask1, unsigned int crc, bool enable); | ||
689 | |||
690 | int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, | ||
691 | enum dev_master master, enum dev_state *state); | ||
692 | int t4_fw_bye(struct adapter *adap, unsigned int mbox); | ||
693 | int t4_early_init(struct adapter *adap, unsigned int mbox); | ||
694 | int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset); | ||
695 | int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
696 | unsigned int vf, unsigned int nparams, const u32 *params, | ||
697 | u32 *val); | ||
698 | int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
699 | unsigned int vf, unsigned int nparams, const u32 *params, | ||
700 | const u32 *val); | ||
701 | int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
702 | unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl, | ||
703 | unsigned int rxqi, unsigned int rxq, unsigned int tc, | ||
704 | unsigned int vi, unsigned int cmask, unsigned int pmask, | ||
705 | unsigned int nexact, unsigned int rcaps, unsigned int wxcaps); | ||
706 | int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port, | ||
707 | unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac, | ||
708 | unsigned int *rss_size); | ||
709 | int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
710 | unsigned int vf, unsigned int viid); | ||
711 | int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid, | ||
712 | int mtu, int promisc, int all_multi, int bcast, bool sleep_ok); | ||
713 | int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, | ||
714 | unsigned int viid, bool free, unsigned int naddr, | ||
715 | const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok); | ||
716 | int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, | ||
717 | int idx, const u8 *addr, bool persist, bool add_smt); | ||
718 | int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid, | ||
719 | bool ucast, u64 vec, bool sleep_ok); | ||
720 | int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid, | ||
721 | bool rx_en, bool tx_en); | ||
722 | int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, | ||
723 | unsigned int nblinks); | ||
724 | int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, | ||
725 | unsigned int mmd, unsigned int reg, u16 *valp); | ||
726 | int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, | ||
727 | unsigned int mmd, unsigned int reg, u16 val); | ||
728 | int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start, | ||
729 | unsigned int pf, unsigned int vf, unsigned int iqid, | ||
730 | unsigned int fl0id, unsigned int fl1id); | ||
731 | int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
732 | unsigned int vf, unsigned int iqtype, unsigned int iqid, | ||
733 | unsigned int fl0id, unsigned int fl1id); | ||
734 | int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
735 | unsigned int vf, unsigned int eqid); | ||
736 | int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
737 | unsigned int vf, unsigned int eqid); | ||
738 | int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
739 | unsigned int vf, unsigned int eqid); | ||
740 | int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl); | ||
741 | #endif /* __CXGB4_H__ */ | ||
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c new file mode 100644 index 000000000000..5f582dba928f --- /dev/null +++ b/drivers/net/cxgb4/cxgb4_main.c | |||
@@ -0,0 +1,3388 @@ | |||
1 | /* | ||
2 | * This file is part of the Chelsio T4 Ethernet driver for Linux. | ||
3 | * | ||
4 | * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved. | ||
5 | * | ||
6 | * This software is available to you under a choice of one of two | ||
7 | * licenses. You may choose to be licensed under the terms of the GNU | ||
8 | * General Public License (GPL) Version 2, available from the file | ||
9 | * COPYING in the main directory of this source tree, or the | ||
10 | * OpenIB.org BSD license below: | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or | ||
13 | * without modification, are permitted provided that the following | ||
14 | * conditions are met: | ||
15 | * | ||
16 | * - Redistributions of source code must retain the above | ||
17 | * copyright notice, this list of conditions and the following | ||
18 | * disclaimer. | ||
19 | * | ||
20 | * - Redistributions in binary form must reproduce the above | ||
21 | * copyright notice, this list of conditions and the following | ||
22 | * disclaimer in the documentation and/or other materials | ||
23 | * provided with the distribution. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
32 | * SOFTWARE. | ||
33 | */ | ||
34 | |||
35 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
36 | |||
37 | #include <linux/bitmap.h> | ||
38 | #include <linux/crc32.h> | ||
39 | #include <linux/ctype.h> | ||
40 | #include <linux/debugfs.h> | ||
41 | #include <linux/err.h> | ||
42 | #include <linux/etherdevice.h> | ||
43 | #include <linux/firmware.h> | ||
44 | #include <linux/if_vlan.h> | ||
45 | #include <linux/init.h> | ||
46 | #include <linux/log2.h> | ||
47 | #include <linux/mdio.h> | ||
48 | #include <linux/module.h> | ||
49 | #include <linux/moduleparam.h> | ||
50 | #include <linux/mutex.h> | ||
51 | #include <linux/netdevice.h> | ||
52 | #include <linux/pci.h> | ||
53 | #include <linux/aer.h> | ||
54 | #include <linux/rtnetlink.h> | ||
55 | #include <linux/sched.h> | ||
56 | #include <linux/seq_file.h> | ||
57 | #include <linux/sockios.h> | ||
58 | #include <linux/vmalloc.h> | ||
59 | #include <linux/workqueue.h> | ||
60 | #include <net/neighbour.h> | ||
61 | #include <net/netevent.h> | ||
62 | #include <asm/uaccess.h> | ||
63 | |||
64 | #include "cxgb4.h" | ||
65 | #include "t4_regs.h" | ||
66 | #include "t4_msg.h" | ||
67 | #include "t4fw_api.h" | ||
68 | #include "l2t.h" | ||
69 | |||
70 | #define DRV_VERSION "1.0.0-ko" | ||
71 | #define DRV_DESC "Chelsio T4 Network Driver" | ||
72 | |||
73 | /* | ||
74 | * Max interrupt hold-off timer value in us. Queues fall back to this value | ||
75 | * under extreme memory pressure so it's largish to give the system time to | ||
76 | * recover. | ||
77 | */ | ||
78 | #define MAX_SGE_TIMERVAL 200U | ||
79 | |||
80 | enum { | ||
81 | MEMWIN0_APERTURE = 65536, | ||
82 | MEMWIN0_BASE = 0x30000, | ||
83 | MEMWIN1_APERTURE = 32768, | ||
84 | MEMWIN1_BASE = 0x28000, | ||
85 | MEMWIN2_APERTURE = 2048, | ||
86 | MEMWIN2_BASE = 0x1b800, | ||
87 | }; | ||
88 | |||
89 | enum { | ||
90 | MAX_TXQ_ENTRIES = 16384, | ||
91 | MAX_CTRL_TXQ_ENTRIES = 1024, | ||
92 | MAX_RSPQ_ENTRIES = 16384, | ||
93 | MAX_RX_BUFFERS = 16384, | ||
94 | MIN_TXQ_ENTRIES = 32, | ||
95 | MIN_CTRL_TXQ_ENTRIES = 32, | ||
96 | MIN_RSPQ_ENTRIES = 128, | ||
97 | MIN_FL_ENTRIES = 16 | ||
98 | }; | ||
99 | |||
100 | #define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \ | ||
101 | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ | ||
102 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) | ||
103 | |||
104 | #define CH_DEVICE(devid) { PCI_VDEVICE(CHELSIO, devid), 0 } | ||
105 | |||
106 | static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = { | ||
107 | CH_DEVICE(0xa000), /* PE10K */ | ||
108 | { 0, } | ||
109 | }; | ||
110 | |||
111 | #define FW_FNAME "cxgb4/t4fw.bin" | ||
112 | |||
113 | MODULE_DESCRIPTION(DRV_DESC); | ||
114 | MODULE_AUTHOR("Chelsio Communications"); | ||
115 | MODULE_LICENSE("Dual BSD/GPL"); | ||
116 | MODULE_VERSION(DRV_VERSION); | ||
117 | MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl); | ||
118 | MODULE_FIRMWARE(FW_FNAME); | ||
119 | |||
120 | static int dflt_msg_enable = DFLT_MSG_ENABLE; | ||
121 | |||
122 | module_param(dflt_msg_enable, int, 0644); | ||
123 | MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T4 default message enable bitmap"); | ||
124 | |||
125 | /* | ||
126 | * The driver uses the best interrupt scheme available on a platform in the | ||
127 | * order MSI-X, MSI, legacy INTx interrupts. This parameter determines which | ||
128 | * of these schemes the driver may consider as follows: | ||
129 | * | ||
130 | * msi = 2: choose from among all three options | ||
131 | * msi = 1: only consider MSI and INTx interrupts | ||
132 | * msi = 0: force INTx interrupts | ||
133 | */ | ||
134 | static int msi = 2; | ||
135 | |||
136 | module_param(msi, int, 0644); | ||
137 | MODULE_PARM_DESC(msi, "whether to use INTx (0), MSI (1) or MSI-X (2)"); | ||
138 | |||
139 | /* | ||
140 | * Queue interrupt hold-off timer values. Queues default to the first of these | ||
141 | * upon creation. | ||
142 | */ | ||
143 | static unsigned int intr_holdoff[SGE_NTIMERS - 1] = { 5, 10, 20, 50, 100 }; | ||
144 | |||
145 | module_param_array(intr_holdoff, uint, NULL, 0644); | ||
146 | MODULE_PARM_DESC(intr_holdoff, "values for queue interrupt hold-off timers " | ||
147 | "0..4 in microseconds"); | ||
148 | |||
149 | static unsigned int intr_cnt[SGE_NCOUNTERS - 1] = { 4, 8, 16 }; | ||
150 | |||
151 | module_param_array(intr_cnt, uint, NULL, 0644); | ||
152 | MODULE_PARM_DESC(intr_cnt, | ||
153 | "thresholds 1..3 for queue interrupt packet counters"); | ||
154 | |||
155 | static int vf_acls; | ||
156 | |||
157 | #ifdef CONFIG_PCI_IOV | ||
158 | module_param(vf_acls, bool, 0644); | ||
159 | MODULE_PARM_DESC(vf_acls, "if set enable virtualization L2 ACL enforcement"); | ||
160 | |||
161 | static unsigned int num_vf[4]; | ||
162 | |||
163 | module_param_array(num_vf, uint, NULL, 0644); | ||
164 | MODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3"); | ||
165 | #endif | ||
166 | |||
167 | static struct dentry *cxgb4_debugfs_root; | ||
168 | |||
169 | static LIST_HEAD(adapter_list); | ||
170 | static DEFINE_MUTEX(uld_mutex); | ||
171 | static struct cxgb4_uld_info ulds[CXGB4_ULD_MAX]; | ||
172 | static const char *uld_str[] = { "RDMA", "iSCSI" }; | ||
173 | |||
174 | static void link_report(struct net_device *dev) | ||
175 | { | ||
176 | if (!netif_carrier_ok(dev)) | ||
177 | netdev_info(dev, "link down\n"); | ||
178 | else { | ||
179 | static const char *fc[] = { "no", "Rx", "Tx", "Tx/Rx" }; | ||
180 | |||
181 | const char *s = "10Mbps"; | ||
182 | const struct port_info *p = netdev_priv(dev); | ||
183 | |||
184 | switch (p->link_cfg.speed) { | ||
185 | case SPEED_10000: | ||
186 | s = "10Gbps"; | ||
187 | break; | ||
188 | case SPEED_1000: | ||
189 | s = "1000Mbps"; | ||
190 | break; | ||
191 | case SPEED_100: | ||
192 | s = "100Mbps"; | ||
193 | break; | ||
194 | } | ||
195 | |||
196 | netdev_info(dev, "link up, %s, full-duplex, %s PAUSE\n", s, | ||
197 | fc[p->link_cfg.fc]); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat) | ||
202 | { | ||
203 | struct net_device *dev = adapter->port[port_id]; | ||
204 | |||
205 | /* Skip changes from disabled ports. */ | ||
206 | if (netif_running(dev) && link_stat != netif_carrier_ok(dev)) { | ||
207 | if (link_stat) | ||
208 | netif_carrier_on(dev); | ||
209 | else | ||
210 | netif_carrier_off(dev); | ||
211 | |||
212 | link_report(dev); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | void t4_os_portmod_changed(const struct adapter *adap, int port_id) | ||
217 | { | ||
218 | static const char *mod_str[] = { | ||
219 | NULL, "LR", "SR", "ER", "passive DA", "active DA" | ||
220 | }; | ||
221 | |||
222 | const struct net_device *dev = adap->port[port_id]; | ||
223 | const struct port_info *pi = netdev_priv(dev); | ||
224 | |||
225 | if (pi->mod_type == FW_PORT_MOD_TYPE_NONE) | ||
226 | netdev_info(dev, "port module unplugged\n"); | ||
227 | else | ||
228 | netdev_info(dev, "%s module inserted\n", mod_str[pi->mod_type]); | ||
229 | } | ||
230 | |||
231 | /* | ||
232 | * Configure the exact and hash address filters to handle a port's multicast | ||
233 | * and secondary unicast MAC addresses. | ||
234 | */ | ||
235 | static int set_addr_filters(const struct net_device *dev, bool sleep) | ||
236 | { | ||
237 | u64 mhash = 0; | ||
238 | u64 uhash = 0; | ||
239 | bool free = true; | ||
240 | u16 filt_idx[7]; | ||
241 | const u8 *addr[7]; | ||
242 | int ret, naddr = 0; | ||
243 | const struct netdev_hw_addr *ha; | ||
244 | int uc_cnt = netdev_uc_count(dev); | ||
245 | int mc_cnt = netdev_mc_count(dev); | ||
246 | const struct port_info *pi = netdev_priv(dev); | ||
247 | |||
248 | /* first do the secondary unicast addresses */ | ||
249 | netdev_for_each_uc_addr(ha, dev) { | ||
250 | addr[naddr++] = ha->addr; | ||
251 | if (--uc_cnt == 0 || naddr >= ARRAY_SIZE(addr)) { | ||
252 | ret = t4_alloc_mac_filt(pi->adapter, 0, pi->viid, free, | ||
253 | naddr, addr, filt_idx, &uhash, sleep); | ||
254 | if (ret < 0) | ||
255 | return ret; | ||
256 | |||
257 | free = false; | ||
258 | naddr = 0; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | /* next set up the multicast addresses */ | ||
263 | netdev_for_each_mc_addr(ha, dev) { | ||
264 | addr[naddr++] = ha->addr; | ||
265 | if (--mc_cnt == 0 || naddr >= ARRAY_SIZE(addr)) { | ||
266 | ret = t4_alloc_mac_filt(pi->adapter, 0, pi->viid, free, | ||
267 | naddr, addr, filt_idx, &mhash, sleep); | ||
268 | if (ret < 0) | ||
269 | return ret; | ||
270 | |||
271 | free = false; | ||
272 | naddr = 0; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | return t4_set_addr_hash(pi->adapter, 0, pi->viid, uhash != 0, | ||
277 | uhash | mhash, sleep); | ||
278 | } | ||
279 | |||
280 | /* | ||
281 | * Set Rx properties of a port, such as promiscruity, address filters, and MTU. | ||
282 | * If @mtu is -1 it is left unchanged. | ||
283 | */ | ||
284 | static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok) | ||
285 | { | ||
286 | int ret; | ||
287 | struct port_info *pi = netdev_priv(dev); | ||
288 | |||
289 | ret = set_addr_filters(dev, sleep_ok); | ||
290 | if (ret == 0) | ||
291 | ret = t4_set_rxmode(pi->adapter, 0, pi->viid, mtu, | ||
292 | (dev->flags & IFF_PROMISC) ? 1 : 0, | ||
293 | (dev->flags & IFF_ALLMULTI) ? 1 : 0, 1, | ||
294 | sleep_ok); | ||
295 | return ret; | ||
296 | } | ||
297 | |||
298 | /** | ||
299 | * link_start - enable a port | ||
300 | * @dev: the port to enable | ||
301 | * | ||
302 | * Performs the MAC and PHY actions needed to enable a port. | ||
303 | */ | ||
304 | static int link_start(struct net_device *dev) | ||
305 | { | ||
306 | int ret; | ||
307 | struct port_info *pi = netdev_priv(dev); | ||
308 | |||
309 | /* | ||
310 | * We do not set address filters and promiscuity here, the stack does | ||
311 | * that step explicitly. | ||
312 | */ | ||
313 | ret = t4_set_rxmode(pi->adapter, 0, pi->viid, dev->mtu, -1, -1, -1, | ||
314 | true); | ||
315 | if (ret == 0) { | ||
316 | ret = t4_change_mac(pi->adapter, 0, pi->viid, | ||
317 | pi->xact_addr_filt, dev->dev_addr, true, | ||
318 | false); | ||
319 | if (ret >= 0) { | ||
320 | pi->xact_addr_filt = ret; | ||
321 | ret = 0; | ||
322 | } | ||
323 | } | ||
324 | if (ret == 0) | ||
325 | ret = t4_link_start(pi->adapter, 0, pi->tx_chan, &pi->link_cfg); | ||
326 | if (ret == 0) | ||
327 | ret = t4_enable_vi(pi->adapter, 0, pi->viid, true, true); | ||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | * Response queue handler for the FW event queue. | ||
333 | */ | ||
334 | static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, | ||
335 | const struct pkt_gl *gl) | ||
336 | { | ||
337 | u8 opcode = ((const struct rss_header *)rsp)->opcode; | ||
338 | |||
339 | rsp++; /* skip RSS header */ | ||
340 | if (likely(opcode == CPL_SGE_EGR_UPDATE)) { | ||
341 | const struct cpl_sge_egr_update *p = (void *)rsp; | ||
342 | unsigned int qid = EGR_QID(ntohl(p->opcode_qid)); | ||
343 | struct sge_txq *txq = q->adap->sge.egr_map[qid]; | ||
344 | |||
345 | txq->restarts++; | ||
346 | if ((u8 *)txq < (u8 *)q->adap->sge.ethrxq) { | ||
347 | struct sge_eth_txq *eq; | ||
348 | |||
349 | eq = container_of(txq, struct sge_eth_txq, q); | ||
350 | netif_tx_wake_queue(eq->txq); | ||
351 | } else { | ||
352 | struct sge_ofld_txq *oq; | ||
353 | |||
354 | oq = container_of(txq, struct sge_ofld_txq, q); | ||
355 | tasklet_schedule(&oq->qresume_tsk); | ||
356 | } | ||
357 | } else if (opcode == CPL_FW6_MSG || opcode == CPL_FW4_MSG) { | ||
358 | const struct cpl_fw6_msg *p = (void *)rsp; | ||
359 | |||
360 | if (p->type == 0) | ||
361 | t4_handle_fw_rpl(q->adap, p->data); | ||
362 | } else if (opcode == CPL_L2T_WRITE_RPL) { | ||
363 | const struct cpl_l2t_write_rpl *p = (void *)rsp; | ||
364 | |||
365 | do_l2t_write_rpl(q->adap, p); | ||
366 | } else | ||
367 | dev_err(q->adap->pdev_dev, | ||
368 | "unexpected CPL %#x on FW event queue\n", opcode); | ||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | /** | ||
373 | * uldrx_handler - response queue handler for ULD queues | ||
374 | * @q: the response queue that received the packet | ||
375 | * @rsp: the response queue descriptor holding the offload message | ||
376 | * @gl: the gather list of packet fragments | ||
377 | * | ||
378 | * Deliver an ingress offload packet to a ULD. All processing is done by | ||
379 | * the ULD, we just maintain statistics. | ||
380 | */ | ||
381 | static int uldrx_handler(struct sge_rspq *q, const __be64 *rsp, | ||
382 | const struct pkt_gl *gl) | ||
383 | { | ||
384 | struct sge_ofld_rxq *rxq = container_of(q, struct sge_ofld_rxq, rspq); | ||
385 | |||
386 | if (ulds[q->uld].rx_handler(q->adap->uld_handle[q->uld], rsp, gl)) { | ||
387 | rxq->stats.nomem++; | ||
388 | return -1; | ||
389 | } | ||
390 | if (gl == NULL) | ||
391 | rxq->stats.imm++; | ||
392 | else if (gl == CXGB4_MSG_AN) | ||
393 | rxq->stats.an++; | ||
394 | else | ||
395 | rxq->stats.pkts++; | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | static void disable_msi(struct adapter *adapter) | ||
400 | { | ||
401 | if (adapter->flags & USING_MSIX) { | ||
402 | pci_disable_msix(adapter->pdev); | ||
403 | adapter->flags &= ~USING_MSIX; | ||
404 | } else if (adapter->flags & USING_MSI) { | ||
405 | pci_disable_msi(adapter->pdev); | ||
406 | adapter->flags &= ~USING_MSI; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | /* | ||
411 | * Interrupt handler for non-data events used with MSI-X. | ||
412 | */ | ||
413 | static irqreturn_t t4_nondata_intr(int irq, void *cookie) | ||
414 | { | ||
415 | struct adapter *adap = cookie; | ||
416 | |||
417 | u32 v = t4_read_reg(adap, MYPF_REG(PL_PF_INT_CAUSE)); | ||
418 | if (v & PFSW) { | ||
419 | adap->swintr = 1; | ||
420 | t4_write_reg(adap, MYPF_REG(PL_PF_INT_CAUSE), v); | ||
421 | } | ||
422 | t4_slow_intr_handler(adap); | ||
423 | return IRQ_HANDLED; | ||
424 | } | ||
425 | |||
426 | /* | ||
427 | * Name the MSI-X interrupts. | ||
428 | */ | ||
429 | static void name_msix_vecs(struct adapter *adap) | ||
430 | { | ||
431 | int i, j, msi_idx = 2, n = sizeof(adap->msix_info[0].desc) - 1; | ||
432 | |||
433 | /* non-data interrupts */ | ||
434 | snprintf(adap->msix_info[0].desc, n, "%s", adap->name); | ||
435 | adap->msix_info[0].desc[n] = 0; | ||
436 | |||
437 | /* FW events */ | ||
438 | snprintf(adap->msix_info[1].desc, n, "%s-FWeventq", adap->name); | ||
439 | adap->msix_info[1].desc[n] = 0; | ||
440 | |||
441 | /* Ethernet queues */ | ||
442 | for_each_port(adap, j) { | ||
443 | struct net_device *d = adap->port[j]; | ||
444 | const struct port_info *pi = netdev_priv(d); | ||
445 | |||
446 | for (i = 0; i < pi->nqsets; i++, msi_idx++) { | ||
447 | snprintf(adap->msix_info[msi_idx].desc, n, "%s-Rx%d", | ||
448 | d->name, i); | ||
449 | adap->msix_info[msi_idx].desc[n] = 0; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | /* offload queues */ | ||
454 | for_each_ofldrxq(&adap->sge, i) { | ||
455 | snprintf(adap->msix_info[msi_idx].desc, n, "%s-ofld%d", | ||
456 | adap->name, i); | ||
457 | adap->msix_info[msi_idx++].desc[n] = 0; | ||
458 | } | ||
459 | for_each_rdmarxq(&adap->sge, i) { | ||
460 | snprintf(adap->msix_info[msi_idx].desc, n, "%s-rdma%d", | ||
461 | adap->name, i); | ||
462 | adap->msix_info[msi_idx++].desc[n] = 0; | ||
463 | } | ||
464 | } | ||
465 | |||
466 | static int request_msix_queue_irqs(struct adapter *adap) | ||
467 | { | ||
468 | struct sge *s = &adap->sge; | ||
469 | int err, ethqidx, ofldqidx = 0, rdmaqidx = 0, msi = 2; | ||
470 | |||
471 | err = request_irq(adap->msix_info[1].vec, t4_sge_intr_msix, 0, | ||
472 | adap->msix_info[1].desc, &s->fw_evtq); | ||
473 | if (err) | ||
474 | return err; | ||
475 | |||
476 | for_each_ethrxq(s, ethqidx) { | ||
477 | err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0, | ||
478 | adap->msix_info[msi].desc, | ||
479 | &s->ethrxq[ethqidx].rspq); | ||
480 | if (err) | ||
481 | goto unwind; | ||
482 | msi++; | ||
483 | } | ||
484 | for_each_ofldrxq(s, ofldqidx) { | ||
485 | err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0, | ||
486 | adap->msix_info[msi].desc, | ||
487 | &s->ofldrxq[ofldqidx].rspq); | ||
488 | if (err) | ||
489 | goto unwind; | ||
490 | msi++; | ||
491 | } | ||
492 | for_each_rdmarxq(s, rdmaqidx) { | ||
493 | err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0, | ||
494 | adap->msix_info[msi].desc, | ||
495 | &s->rdmarxq[rdmaqidx].rspq); | ||
496 | if (err) | ||
497 | goto unwind; | ||
498 | msi++; | ||
499 | } | ||
500 | return 0; | ||
501 | |||
502 | unwind: | ||
503 | while (--rdmaqidx >= 0) | ||
504 | free_irq(adap->msix_info[--msi].vec, | ||
505 | &s->rdmarxq[rdmaqidx].rspq); | ||
506 | while (--ofldqidx >= 0) | ||
507 | free_irq(adap->msix_info[--msi].vec, | ||
508 | &s->ofldrxq[ofldqidx].rspq); | ||
509 | while (--ethqidx >= 0) | ||
510 | free_irq(adap->msix_info[--msi].vec, &s->ethrxq[ethqidx].rspq); | ||
511 | free_irq(adap->msix_info[1].vec, &s->fw_evtq); | ||
512 | return err; | ||
513 | } | ||
514 | |||
515 | static void free_msix_queue_irqs(struct adapter *adap) | ||
516 | { | ||
517 | int i, msi = 2; | ||
518 | struct sge *s = &adap->sge; | ||
519 | |||
520 | free_irq(adap->msix_info[1].vec, &s->fw_evtq); | ||
521 | for_each_ethrxq(s, i) | ||
522 | free_irq(adap->msix_info[msi++].vec, &s->ethrxq[i].rspq); | ||
523 | for_each_ofldrxq(s, i) | ||
524 | free_irq(adap->msix_info[msi++].vec, &s->ofldrxq[i].rspq); | ||
525 | for_each_rdmarxq(s, i) | ||
526 | free_irq(adap->msix_info[msi++].vec, &s->rdmarxq[i].rspq); | ||
527 | } | ||
528 | |||
529 | /** | ||
530 | * setup_rss - configure RSS | ||
531 | * @adap: the adapter | ||
532 | * | ||
533 | * Sets up RSS to distribute packets to multiple receive queues. We | ||
534 | * configure the RSS CPU lookup table to distribute to the number of HW | ||
535 | * receive queues, and the response queue lookup table to narrow that | ||
536 | * down to the response queues actually configured for each port. | ||
537 | * We always configure the RSS mapping for all ports since the mapping | ||
538 | * table has plenty of entries. | ||
539 | */ | ||
540 | static int setup_rss(struct adapter *adap) | ||
541 | { | ||
542 | int i, j, err; | ||
543 | u16 rss[MAX_ETH_QSETS]; | ||
544 | |||
545 | for_each_port(adap, i) { | ||
546 | const struct port_info *pi = adap2pinfo(adap, i); | ||
547 | const struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset]; | ||
548 | |||
549 | for (j = 0; j < pi->nqsets; j++) | ||
550 | rss[j] = q[j].rspq.abs_id; | ||
551 | |||
552 | err = t4_config_rss_range(adap, 0, pi->viid, 0, pi->rss_size, | ||
553 | rss, pi->nqsets); | ||
554 | if (err) | ||
555 | return err; | ||
556 | } | ||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * Wait until all NAPI handlers are descheduled. | ||
562 | */ | ||
563 | static void quiesce_rx(struct adapter *adap) | ||
564 | { | ||
565 | int i; | ||
566 | |||
567 | for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) { | ||
568 | struct sge_rspq *q = adap->sge.ingr_map[i]; | ||
569 | |||
570 | if (q && q->handler) | ||
571 | napi_disable(&q->napi); | ||
572 | } | ||
573 | } | ||
574 | |||
575 | /* | ||
576 | * Enable NAPI scheduling and interrupt generation for all Rx queues. | ||
577 | */ | ||
578 | static void enable_rx(struct adapter *adap) | ||
579 | { | ||
580 | int i; | ||
581 | |||
582 | for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) { | ||
583 | struct sge_rspq *q = adap->sge.ingr_map[i]; | ||
584 | |||
585 | if (!q) | ||
586 | continue; | ||
587 | if (q->handler) | ||
588 | napi_enable(&q->napi); | ||
589 | /* 0-increment GTS to start the timer and enable interrupts */ | ||
590 | t4_write_reg(adap, MYPF_REG(SGE_PF_GTS), | ||
591 | SEINTARM(q->intr_params) | | ||
592 | INGRESSQID(q->cntxt_id)); | ||
593 | } | ||
594 | } | ||
595 | |||
596 | /** | ||
597 | * setup_sge_queues - configure SGE Tx/Rx/response queues | ||
598 | * @adap: the adapter | ||
599 | * | ||
600 | * Determines how many sets of SGE queues to use and initializes them. | ||
601 | * We support multiple queue sets per port if we have MSI-X, otherwise | ||
602 | * just one queue set per port. | ||
603 | */ | ||
604 | static int setup_sge_queues(struct adapter *adap) | ||
605 | { | ||
606 | int err, msi_idx, i, j; | ||
607 | struct sge *s = &adap->sge; | ||
608 | |||
609 | bitmap_zero(s->starving_fl, MAX_EGRQ); | ||
610 | bitmap_zero(s->txq_maperr, MAX_EGRQ); | ||
611 | |||
612 | if (adap->flags & USING_MSIX) | ||
613 | msi_idx = 1; /* vector 0 is for non-queue interrupts */ | ||
614 | else { | ||
615 | err = t4_sge_alloc_rxq(adap, &s->intrq, false, adap->port[0], 0, | ||
616 | NULL, NULL); | ||
617 | if (err) | ||
618 | return err; | ||
619 | msi_idx = -((int)s->intrq.abs_id + 1); | ||
620 | } | ||
621 | |||
622 | err = t4_sge_alloc_rxq(adap, &s->fw_evtq, true, adap->port[0], | ||
623 | msi_idx, NULL, fwevtq_handler); | ||
624 | if (err) { | ||
625 | freeout: t4_free_sge_resources(adap); | ||
626 | return err; | ||
627 | } | ||
628 | |||
629 | for_each_port(adap, i) { | ||
630 | struct net_device *dev = adap->port[i]; | ||
631 | struct port_info *pi = netdev_priv(dev); | ||
632 | struct sge_eth_rxq *q = &s->ethrxq[pi->first_qset]; | ||
633 | struct sge_eth_txq *t = &s->ethtxq[pi->first_qset]; | ||
634 | |||
635 | for (j = 0; j < pi->nqsets; j++, q++) { | ||
636 | if (msi_idx > 0) | ||
637 | msi_idx++; | ||
638 | err = t4_sge_alloc_rxq(adap, &q->rspq, false, dev, | ||
639 | msi_idx, &q->fl, | ||
640 | t4_ethrx_handler); | ||
641 | if (err) | ||
642 | goto freeout; | ||
643 | q->rspq.idx = j; | ||
644 | memset(&q->stats, 0, sizeof(q->stats)); | ||
645 | } | ||
646 | for (j = 0; j < pi->nqsets; j++, t++) { | ||
647 | err = t4_sge_alloc_eth_txq(adap, t, dev, | ||
648 | netdev_get_tx_queue(dev, j), | ||
649 | s->fw_evtq.cntxt_id); | ||
650 | if (err) | ||
651 | goto freeout; | ||
652 | } | ||
653 | } | ||
654 | |||
655 | j = s->ofldqsets / adap->params.nports; /* ofld queues per channel */ | ||
656 | for_each_ofldrxq(s, i) { | ||
657 | struct sge_ofld_rxq *q = &s->ofldrxq[i]; | ||
658 | struct net_device *dev = adap->port[i / j]; | ||
659 | |||
660 | if (msi_idx > 0) | ||
661 | msi_idx++; | ||
662 | err = t4_sge_alloc_rxq(adap, &q->rspq, false, dev, msi_idx, | ||
663 | &q->fl, uldrx_handler); | ||
664 | if (err) | ||
665 | goto freeout; | ||
666 | memset(&q->stats, 0, sizeof(q->stats)); | ||
667 | s->ofld_rxq[i] = q->rspq.abs_id; | ||
668 | err = t4_sge_alloc_ofld_txq(adap, &s->ofldtxq[i], dev, | ||
669 | s->fw_evtq.cntxt_id); | ||
670 | if (err) | ||
671 | goto freeout; | ||
672 | } | ||
673 | |||
674 | for_each_rdmarxq(s, i) { | ||
675 | struct sge_ofld_rxq *q = &s->rdmarxq[i]; | ||
676 | |||
677 | if (msi_idx > 0) | ||
678 | msi_idx++; | ||
679 | err = t4_sge_alloc_rxq(adap, &q->rspq, false, adap->port[i], | ||
680 | msi_idx, &q->fl, uldrx_handler); | ||
681 | if (err) | ||
682 | goto freeout; | ||
683 | memset(&q->stats, 0, sizeof(q->stats)); | ||
684 | s->rdma_rxq[i] = q->rspq.abs_id; | ||
685 | } | ||
686 | |||
687 | for_each_port(adap, i) { | ||
688 | /* | ||
689 | * Note that ->rdmarxq[i].rspq.cntxt_id below is 0 if we don't | ||
690 | * have RDMA queues, and that's the right value. | ||
691 | */ | ||
692 | err = t4_sge_alloc_ctrl_txq(adap, &s->ctrlq[i], adap->port[i], | ||
693 | s->fw_evtq.cntxt_id, | ||
694 | s->rdmarxq[i].rspq.cntxt_id); | ||
695 | if (err) | ||
696 | goto freeout; | ||
697 | } | ||
698 | |||
699 | t4_write_reg(adap, MPS_TRC_RSS_CONTROL, | ||
700 | RSSCONTROL(netdev2pinfo(adap->port[0])->tx_chan) | | ||
701 | QUEUENUMBER(s->ethrxq[0].rspq.abs_id)); | ||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | /* | ||
706 | * Returns 0 if new FW was successfully loaded, a positive errno if a load was | ||
707 | * started but failed, and a negative errno if flash load couldn't start. | ||
708 | */ | ||
709 | static int upgrade_fw(struct adapter *adap) | ||
710 | { | ||
711 | int ret; | ||
712 | u32 vers; | ||
713 | const struct fw_hdr *hdr; | ||
714 | const struct firmware *fw; | ||
715 | struct device *dev = adap->pdev_dev; | ||
716 | |||
717 | ret = request_firmware(&fw, FW_FNAME, dev); | ||
718 | if (ret < 0) { | ||
719 | dev_err(dev, "unable to load firmware image " FW_FNAME | ||
720 | ", error %d\n", ret); | ||
721 | return ret; | ||
722 | } | ||
723 | |||
724 | hdr = (const struct fw_hdr *)fw->data; | ||
725 | vers = ntohl(hdr->fw_ver); | ||
726 | if (FW_HDR_FW_VER_MAJOR_GET(vers) != FW_VERSION_MAJOR) { | ||
727 | ret = -EINVAL; /* wrong major version, won't do */ | ||
728 | goto out; | ||
729 | } | ||
730 | |||
731 | /* | ||
732 | * If the flash FW is unusable or we found something newer, load it. | ||
733 | */ | ||
734 | if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != FW_VERSION_MAJOR || | ||
735 | vers > adap->params.fw_vers) { | ||
736 | ret = -t4_load_fw(adap, fw->data, fw->size); | ||
737 | if (!ret) | ||
738 | dev_info(dev, "firmware upgraded to version %pI4 from " | ||
739 | FW_FNAME "\n", &hdr->fw_ver); | ||
740 | } | ||
741 | out: release_firmware(fw); | ||
742 | return ret; | ||
743 | } | ||
744 | |||
745 | /* | ||
746 | * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. | ||
747 | * The allocated memory is cleared. | ||
748 | */ | ||
749 | void *t4_alloc_mem(size_t size) | ||
750 | { | ||
751 | void *p = kmalloc(size, GFP_KERNEL); | ||
752 | |||
753 | if (!p) | ||
754 | p = vmalloc(size); | ||
755 | if (p) | ||
756 | memset(p, 0, size); | ||
757 | return p; | ||
758 | } | ||
759 | |||
760 | /* | ||
761 | * Free memory allocated through alloc_mem(). | ||
762 | */ | ||
763 | void t4_free_mem(void *addr) | ||
764 | { | ||
765 | if (is_vmalloc_addr(addr)) | ||
766 | vfree(addr); | ||
767 | else | ||
768 | kfree(addr); | ||
769 | } | ||
770 | |||
771 | static inline int is_offload(const struct adapter *adap) | ||
772 | { | ||
773 | return adap->params.offload; | ||
774 | } | ||
775 | |||
776 | /* | ||
777 | * Implementation of ethtool operations. | ||
778 | */ | ||
779 | |||
780 | static u32 get_msglevel(struct net_device *dev) | ||
781 | { | ||
782 | return netdev2adap(dev)->msg_enable; | ||
783 | } | ||
784 | |||
785 | static void set_msglevel(struct net_device *dev, u32 val) | ||
786 | { | ||
787 | netdev2adap(dev)->msg_enable = val; | ||
788 | } | ||
789 | |||
790 | static char stats_strings[][ETH_GSTRING_LEN] = { | ||
791 | "TxOctetsOK ", | ||
792 | "TxFramesOK ", | ||
793 | "TxBroadcastFrames ", | ||
794 | "TxMulticastFrames ", | ||
795 | "TxUnicastFrames ", | ||
796 | "TxErrorFrames ", | ||
797 | |||
798 | "TxFrames64 ", | ||
799 | "TxFrames65To127 ", | ||
800 | "TxFrames128To255 ", | ||
801 | "TxFrames256To511 ", | ||
802 | "TxFrames512To1023 ", | ||
803 | "TxFrames1024To1518 ", | ||
804 | "TxFrames1519ToMax ", | ||
805 | |||
806 | "TxFramesDropped ", | ||
807 | "TxPauseFrames ", | ||
808 | "TxPPP0Frames ", | ||
809 | "TxPPP1Frames ", | ||
810 | "TxPPP2Frames ", | ||
811 | "TxPPP3Frames ", | ||
812 | "TxPPP4Frames ", | ||
813 | "TxPPP5Frames ", | ||
814 | "TxPPP6Frames ", | ||
815 | "TxPPP7Frames ", | ||
816 | |||
817 | "RxOctetsOK ", | ||
818 | "RxFramesOK ", | ||
819 | "RxBroadcastFrames ", | ||
820 | "RxMulticastFrames ", | ||
821 | "RxUnicastFrames ", | ||
822 | |||
823 | "RxFramesTooLong ", | ||
824 | "RxJabberErrors ", | ||
825 | "RxFCSErrors ", | ||
826 | "RxLengthErrors ", | ||
827 | "RxSymbolErrors ", | ||
828 | "RxRuntFrames ", | ||
829 | |||
830 | "RxFrames64 ", | ||
831 | "RxFrames65To127 ", | ||
832 | "RxFrames128To255 ", | ||
833 | "RxFrames256To511 ", | ||
834 | "RxFrames512To1023 ", | ||
835 | "RxFrames1024To1518 ", | ||
836 | "RxFrames1519ToMax ", | ||
837 | |||
838 | "RxPauseFrames ", | ||
839 | "RxPPP0Frames ", | ||
840 | "RxPPP1Frames ", | ||
841 | "RxPPP2Frames ", | ||
842 | "RxPPP3Frames ", | ||
843 | "RxPPP4Frames ", | ||
844 | "RxPPP5Frames ", | ||
845 | "RxPPP6Frames ", | ||
846 | "RxPPP7Frames ", | ||
847 | |||
848 | "RxBG0FramesDropped ", | ||
849 | "RxBG1FramesDropped ", | ||
850 | "RxBG2FramesDropped ", | ||
851 | "RxBG3FramesDropped ", | ||
852 | "RxBG0FramesTrunc ", | ||
853 | "RxBG1FramesTrunc ", | ||
854 | "RxBG2FramesTrunc ", | ||
855 | "RxBG3FramesTrunc ", | ||
856 | |||
857 | "TSO ", | ||
858 | "TxCsumOffload ", | ||
859 | "RxCsumGood ", | ||
860 | "VLANextractions ", | ||
861 | "VLANinsertions ", | ||
862 | }; | ||
863 | |||
864 | static int get_sset_count(struct net_device *dev, int sset) | ||
865 | { | ||
866 | switch (sset) { | ||
867 | case ETH_SS_STATS: | ||
868 | return ARRAY_SIZE(stats_strings); | ||
869 | default: | ||
870 | return -EOPNOTSUPP; | ||
871 | } | ||
872 | } | ||
873 | |||
874 | #define T4_REGMAP_SIZE (160 * 1024) | ||
875 | |||
876 | static int get_regs_len(struct net_device *dev) | ||
877 | { | ||
878 | return T4_REGMAP_SIZE; | ||
879 | } | ||
880 | |||
881 | static int get_eeprom_len(struct net_device *dev) | ||
882 | { | ||
883 | return EEPROMSIZE; | ||
884 | } | ||
885 | |||
886 | static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | ||
887 | { | ||
888 | struct adapter *adapter = netdev2adap(dev); | ||
889 | |||
890 | strcpy(info->driver, KBUILD_MODNAME); | ||
891 | strcpy(info->version, DRV_VERSION); | ||
892 | strcpy(info->bus_info, pci_name(adapter->pdev)); | ||
893 | |||
894 | if (!adapter->params.fw_vers) | ||
895 | strcpy(info->fw_version, "N/A"); | ||
896 | else | ||
897 | snprintf(info->fw_version, sizeof(info->fw_version), | ||
898 | "%u.%u.%u.%u, TP %u.%u.%u.%u", | ||
899 | FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers), | ||
900 | FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers), | ||
901 | FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers), | ||
902 | FW_HDR_FW_VER_BUILD_GET(adapter->params.fw_vers), | ||
903 | FW_HDR_FW_VER_MAJOR_GET(adapter->params.tp_vers), | ||
904 | FW_HDR_FW_VER_MINOR_GET(adapter->params.tp_vers), | ||
905 | FW_HDR_FW_VER_MICRO_GET(adapter->params.tp_vers), | ||
906 | FW_HDR_FW_VER_BUILD_GET(adapter->params.tp_vers)); | ||
907 | } | ||
908 | |||
909 | static void get_strings(struct net_device *dev, u32 stringset, u8 *data) | ||
910 | { | ||
911 | if (stringset == ETH_SS_STATS) | ||
912 | memcpy(data, stats_strings, sizeof(stats_strings)); | ||
913 | } | ||
914 | |||
915 | /* | ||
916 | * port stats maintained per queue of the port. They should be in the same | ||
917 | * order as in stats_strings above. | ||
918 | */ | ||
919 | struct queue_port_stats { | ||
920 | u64 tso; | ||
921 | u64 tx_csum; | ||
922 | u64 rx_csum; | ||
923 | u64 vlan_ex; | ||
924 | u64 vlan_ins; | ||
925 | }; | ||
926 | |||
927 | static void collect_sge_port_stats(const struct adapter *adap, | ||
928 | const struct port_info *p, struct queue_port_stats *s) | ||
929 | { | ||
930 | int i; | ||
931 | const struct sge_eth_txq *tx = &adap->sge.ethtxq[p->first_qset]; | ||
932 | const struct sge_eth_rxq *rx = &adap->sge.ethrxq[p->first_qset]; | ||
933 | |||
934 | memset(s, 0, sizeof(*s)); | ||
935 | for (i = 0; i < p->nqsets; i++, rx++, tx++) { | ||
936 | s->tso += tx->tso; | ||
937 | s->tx_csum += tx->tx_cso; | ||
938 | s->rx_csum += rx->stats.rx_cso; | ||
939 | s->vlan_ex += rx->stats.vlan_ex; | ||
940 | s->vlan_ins += tx->vlan_ins; | ||
941 | } | ||
942 | } | ||
943 | |||
944 | static void get_stats(struct net_device *dev, struct ethtool_stats *stats, | ||
945 | u64 *data) | ||
946 | { | ||
947 | struct port_info *pi = netdev_priv(dev); | ||
948 | struct adapter *adapter = pi->adapter; | ||
949 | |||
950 | t4_get_port_stats(adapter, pi->tx_chan, (struct port_stats *)data); | ||
951 | |||
952 | data += sizeof(struct port_stats) / sizeof(u64); | ||
953 | collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data); | ||
954 | } | ||
955 | |||
956 | /* | ||
957 | * Return a version number to identify the type of adapter. The scheme is: | ||
958 | * - bits 0..9: chip version | ||
959 | * - bits 10..15: chip revision | ||
960 | */ | ||
961 | static inline unsigned int mk_adap_vers(const struct adapter *ap) | ||
962 | { | ||
963 | return 4 | (ap->params.rev << 10); | ||
964 | } | ||
965 | |||
966 | static void reg_block_dump(struct adapter *ap, void *buf, unsigned int start, | ||
967 | unsigned int end) | ||
968 | { | ||
969 | u32 *p = buf + start; | ||
970 | |||
971 | for ( ; start <= end; start += sizeof(u32)) | ||
972 | *p++ = t4_read_reg(ap, start); | ||
973 | } | ||
974 | |||
975 | static void get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
976 | void *buf) | ||
977 | { | ||
978 | static const unsigned int reg_ranges[] = { | ||
979 | 0x1008, 0x1108, | ||
980 | 0x1180, 0x11b4, | ||
981 | 0x11fc, 0x123c, | ||
982 | 0x1300, 0x173c, | ||
983 | 0x1800, 0x18fc, | ||
984 | 0x3000, 0x30d8, | ||
985 | 0x30e0, 0x5924, | ||
986 | 0x5960, 0x59d4, | ||
987 | 0x5a00, 0x5af8, | ||
988 | 0x6000, 0x6098, | ||
989 | 0x6100, 0x6150, | ||
990 | 0x6200, 0x6208, | ||
991 | 0x6240, 0x6248, | ||
992 | 0x6280, 0x6338, | ||
993 | 0x6370, 0x638c, | ||
994 | 0x6400, 0x643c, | ||
995 | 0x6500, 0x6524, | ||
996 | 0x6a00, 0x6a38, | ||
997 | 0x6a60, 0x6a78, | ||
998 | 0x6b00, 0x6b84, | ||
999 | 0x6bf0, 0x6c84, | ||
1000 | 0x6cf0, 0x6d84, | ||
1001 | 0x6df0, 0x6e84, | ||
1002 | 0x6ef0, 0x6f84, | ||
1003 | 0x6ff0, 0x7084, | ||
1004 | 0x70f0, 0x7184, | ||
1005 | 0x71f0, 0x7284, | ||
1006 | 0x72f0, 0x7384, | ||
1007 | 0x73f0, 0x7450, | ||
1008 | 0x7500, 0x7530, | ||
1009 | 0x7600, 0x761c, | ||
1010 | 0x7680, 0x76cc, | ||
1011 | 0x7700, 0x7798, | ||
1012 | 0x77c0, 0x77fc, | ||
1013 | 0x7900, 0x79fc, | ||
1014 | 0x7b00, 0x7c38, | ||
1015 | 0x7d00, 0x7efc, | ||
1016 | 0x8dc0, 0x8e1c, | ||
1017 | 0x8e30, 0x8e78, | ||
1018 | 0x8ea0, 0x8f6c, | ||
1019 | 0x8fc0, 0x9074, | ||
1020 | 0x90fc, 0x90fc, | ||
1021 | 0x9400, 0x9458, | ||
1022 | 0x9600, 0x96bc, | ||
1023 | 0x9800, 0x9808, | ||
1024 | 0x9820, 0x983c, | ||
1025 | 0x9850, 0x9864, | ||
1026 | 0x9c00, 0x9c6c, | ||
1027 | 0x9c80, 0x9cec, | ||
1028 | 0x9d00, 0x9d6c, | ||
1029 | 0x9d80, 0x9dec, | ||
1030 | 0x9e00, 0x9e6c, | ||
1031 | 0x9e80, 0x9eec, | ||
1032 | 0x9f00, 0x9f6c, | ||
1033 | 0x9f80, 0x9fec, | ||
1034 | 0xd004, 0xd03c, | ||
1035 | 0xdfc0, 0xdfe0, | ||
1036 | 0xe000, 0xea7c, | ||
1037 | 0xf000, 0x11190, | ||
1038 | 0x19040, 0x19124, | ||
1039 | 0x19150, 0x191b0, | ||
1040 | 0x191d0, 0x191e8, | ||
1041 | 0x19238, 0x1924c, | ||
1042 | 0x193f8, 0x19474, | ||
1043 | 0x19490, 0x194f8, | ||
1044 | 0x19800, 0x19f30, | ||
1045 | 0x1a000, 0x1a06c, | ||
1046 | 0x1a0b0, 0x1a120, | ||
1047 | 0x1a128, 0x1a138, | ||
1048 | 0x1a190, 0x1a1c4, | ||
1049 | 0x1a1fc, 0x1a1fc, | ||
1050 | 0x1e040, 0x1e04c, | ||
1051 | 0x1e240, 0x1e28c, | ||
1052 | 0x1e2c0, 0x1e2c0, | ||
1053 | 0x1e2e0, 0x1e2e0, | ||
1054 | 0x1e300, 0x1e384, | ||
1055 | 0x1e3c0, 0x1e3c8, | ||
1056 | 0x1e440, 0x1e44c, | ||
1057 | 0x1e640, 0x1e68c, | ||
1058 | 0x1e6c0, 0x1e6c0, | ||
1059 | 0x1e6e0, 0x1e6e0, | ||
1060 | 0x1e700, 0x1e784, | ||
1061 | 0x1e7c0, 0x1e7c8, | ||
1062 | 0x1e840, 0x1e84c, | ||
1063 | 0x1ea40, 0x1ea8c, | ||
1064 | 0x1eac0, 0x1eac0, | ||
1065 | 0x1eae0, 0x1eae0, | ||
1066 | 0x1eb00, 0x1eb84, | ||
1067 | 0x1ebc0, 0x1ebc8, | ||
1068 | 0x1ec40, 0x1ec4c, | ||
1069 | 0x1ee40, 0x1ee8c, | ||
1070 | 0x1eec0, 0x1eec0, | ||
1071 | 0x1eee0, 0x1eee0, | ||
1072 | 0x1ef00, 0x1ef84, | ||
1073 | 0x1efc0, 0x1efc8, | ||
1074 | 0x1f040, 0x1f04c, | ||
1075 | 0x1f240, 0x1f28c, | ||
1076 | 0x1f2c0, 0x1f2c0, | ||
1077 | 0x1f2e0, 0x1f2e0, | ||
1078 | 0x1f300, 0x1f384, | ||
1079 | 0x1f3c0, 0x1f3c8, | ||
1080 | 0x1f440, 0x1f44c, | ||
1081 | 0x1f640, 0x1f68c, | ||
1082 | 0x1f6c0, 0x1f6c0, | ||
1083 | 0x1f6e0, 0x1f6e0, | ||
1084 | 0x1f700, 0x1f784, | ||
1085 | 0x1f7c0, 0x1f7c8, | ||
1086 | 0x1f840, 0x1f84c, | ||
1087 | 0x1fa40, 0x1fa8c, | ||
1088 | 0x1fac0, 0x1fac0, | ||
1089 | 0x1fae0, 0x1fae0, | ||
1090 | 0x1fb00, 0x1fb84, | ||
1091 | 0x1fbc0, 0x1fbc8, | ||
1092 | 0x1fc40, 0x1fc4c, | ||
1093 | 0x1fe40, 0x1fe8c, | ||
1094 | 0x1fec0, 0x1fec0, | ||
1095 | 0x1fee0, 0x1fee0, | ||
1096 | 0x1ff00, 0x1ff84, | ||
1097 | 0x1ffc0, 0x1ffc8, | ||
1098 | 0x20000, 0x2002c, | ||
1099 | 0x20100, 0x2013c, | ||
1100 | 0x20190, 0x201c8, | ||
1101 | 0x20200, 0x20318, | ||
1102 | 0x20400, 0x20528, | ||
1103 | 0x20540, 0x20614, | ||
1104 | 0x21000, 0x21040, | ||
1105 | 0x2104c, 0x21060, | ||
1106 | 0x210c0, 0x210ec, | ||
1107 | 0x21200, 0x21268, | ||
1108 | 0x21270, 0x21284, | ||
1109 | 0x212fc, 0x21388, | ||
1110 | 0x21400, 0x21404, | ||
1111 | 0x21500, 0x21518, | ||
1112 | 0x2152c, 0x2153c, | ||
1113 | 0x21550, 0x21554, | ||
1114 | 0x21600, 0x21600, | ||
1115 | 0x21608, 0x21628, | ||
1116 | 0x21630, 0x2163c, | ||
1117 | 0x21700, 0x2171c, | ||
1118 | 0x21780, 0x2178c, | ||
1119 | 0x21800, 0x21c38, | ||
1120 | 0x21c80, 0x21d7c, | ||
1121 | 0x21e00, 0x21e04, | ||
1122 | 0x22000, 0x2202c, | ||
1123 | 0x22100, 0x2213c, | ||
1124 | 0x22190, 0x221c8, | ||
1125 | 0x22200, 0x22318, | ||
1126 | 0x22400, 0x22528, | ||
1127 | 0x22540, 0x22614, | ||
1128 | 0x23000, 0x23040, | ||
1129 | 0x2304c, 0x23060, | ||
1130 | 0x230c0, 0x230ec, | ||
1131 | 0x23200, 0x23268, | ||
1132 | 0x23270, 0x23284, | ||
1133 | 0x232fc, 0x23388, | ||
1134 | 0x23400, 0x23404, | ||
1135 | 0x23500, 0x23518, | ||
1136 | 0x2352c, 0x2353c, | ||
1137 | 0x23550, 0x23554, | ||
1138 | 0x23600, 0x23600, | ||
1139 | 0x23608, 0x23628, | ||
1140 | 0x23630, 0x2363c, | ||
1141 | 0x23700, 0x2371c, | ||
1142 | 0x23780, 0x2378c, | ||
1143 | 0x23800, 0x23c38, | ||
1144 | 0x23c80, 0x23d7c, | ||
1145 | 0x23e00, 0x23e04, | ||
1146 | 0x24000, 0x2402c, | ||
1147 | 0x24100, 0x2413c, | ||
1148 | 0x24190, 0x241c8, | ||
1149 | 0x24200, 0x24318, | ||
1150 | 0x24400, 0x24528, | ||
1151 | 0x24540, 0x24614, | ||
1152 | 0x25000, 0x25040, | ||
1153 | 0x2504c, 0x25060, | ||
1154 | 0x250c0, 0x250ec, | ||
1155 | 0x25200, 0x25268, | ||
1156 | 0x25270, 0x25284, | ||
1157 | 0x252fc, 0x25388, | ||
1158 | 0x25400, 0x25404, | ||
1159 | 0x25500, 0x25518, | ||
1160 | 0x2552c, 0x2553c, | ||
1161 | 0x25550, 0x25554, | ||
1162 | 0x25600, 0x25600, | ||
1163 | 0x25608, 0x25628, | ||
1164 | 0x25630, 0x2563c, | ||
1165 | 0x25700, 0x2571c, | ||
1166 | 0x25780, 0x2578c, | ||
1167 | 0x25800, 0x25c38, | ||
1168 | 0x25c80, 0x25d7c, | ||
1169 | 0x25e00, 0x25e04, | ||
1170 | 0x26000, 0x2602c, | ||
1171 | 0x26100, 0x2613c, | ||
1172 | 0x26190, 0x261c8, | ||
1173 | 0x26200, 0x26318, | ||
1174 | 0x26400, 0x26528, | ||
1175 | 0x26540, 0x26614, | ||
1176 | 0x27000, 0x27040, | ||
1177 | 0x2704c, 0x27060, | ||
1178 | 0x270c0, 0x270ec, | ||
1179 | 0x27200, 0x27268, | ||
1180 | 0x27270, 0x27284, | ||
1181 | 0x272fc, 0x27388, | ||
1182 | 0x27400, 0x27404, | ||
1183 | 0x27500, 0x27518, | ||
1184 | 0x2752c, 0x2753c, | ||
1185 | 0x27550, 0x27554, | ||
1186 | 0x27600, 0x27600, | ||
1187 | 0x27608, 0x27628, | ||
1188 | 0x27630, 0x2763c, | ||
1189 | 0x27700, 0x2771c, | ||
1190 | 0x27780, 0x2778c, | ||
1191 | 0x27800, 0x27c38, | ||
1192 | 0x27c80, 0x27d7c, | ||
1193 | 0x27e00, 0x27e04 | ||
1194 | }; | ||
1195 | |||
1196 | int i; | ||
1197 | struct adapter *ap = netdev2adap(dev); | ||
1198 | |||
1199 | regs->version = mk_adap_vers(ap); | ||
1200 | |||
1201 | memset(buf, 0, T4_REGMAP_SIZE); | ||
1202 | for (i = 0; i < ARRAY_SIZE(reg_ranges); i += 2) | ||
1203 | reg_block_dump(ap, buf, reg_ranges[i], reg_ranges[i + 1]); | ||
1204 | } | ||
1205 | |||
1206 | static int restart_autoneg(struct net_device *dev) | ||
1207 | { | ||
1208 | struct port_info *p = netdev_priv(dev); | ||
1209 | |||
1210 | if (!netif_running(dev)) | ||
1211 | return -EAGAIN; | ||
1212 | if (p->link_cfg.autoneg != AUTONEG_ENABLE) | ||
1213 | return -EINVAL; | ||
1214 | t4_restart_aneg(p->adapter, 0, p->tx_chan); | ||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
1218 | static int identify_port(struct net_device *dev, u32 data) | ||
1219 | { | ||
1220 | if (data == 0) | ||
1221 | data = 2; /* default to 2 seconds */ | ||
1222 | |||
1223 | return t4_identify_port(netdev2adap(dev), 0, netdev2pinfo(dev)->viid, | ||
1224 | data * 5); | ||
1225 | } | ||
1226 | |||
1227 | static unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps) | ||
1228 | { | ||
1229 | unsigned int v = 0; | ||
1230 | |||
1231 | if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XAUI) { | ||
1232 | v |= SUPPORTED_TP; | ||
1233 | if (caps & FW_PORT_CAP_SPEED_100M) | ||
1234 | v |= SUPPORTED_100baseT_Full; | ||
1235 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
1236 | v |= SUPPORTED_1000baseT_Full; | ||
1237 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
1238 | v |= SUPPORTED_10000baseT_Full; | ||
1239 | } else if (type == FW_PORT_TYPE_KX4 || type == FW_PORT_TYPE_KX) { | ||
1240 | v |= SUPPORTED_Backplane; | ||
1241 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
1242 | v |= SUPPORTED_1000baseKX_Full; | ||
1243 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
1244 | v |= SUPPORTED_10000baseKX4_Full; | ||
1245 | } else if (type == FW_PORT_TYPE_KR) | ||
1246 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full; | ||
1247 | else if (type == FW_PORT_TYPE_FIBER) | ||
1248 | v |= SUPPORTED_FIBRE; | ||
1249 | |||
1250 | if (caps & FW_PORT_CAP_ANEG) | ||
1251 | v |= SUPPORTED_Autoneg; | ||
1252 | return v; | ||
1253 | } | ||
1254 | |||
1255 | static unsigned int to_fw_linkcaps(unsigned int caps) | ||
1256 | { | ||
1257 | unsigned int v = 0; | ||
1258 | |||
1259 | if (caps & ADVERTISED_100baseT_Full) | ||
1260 | v |= FW_PORT_CAP_SPEED_100M; | ||
1261 | if (caps & ADVERTISED_1000baseT_Full) | ||
1262 | v |= FW_PORT_CAP_SPEED_1G; | ||
1263 | if (caps & ADVERTISED_10000baseT_Full) | ||
1264 | v |= FW_PORT_CAP_SPEED_10G; | ||
1265 | return v; | ||
1266 | } | ||
1267 | |||
1268 | static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1269 | { | ||
1270 | const struct port_info *p = netdev_priv(dev); | ||
1271 | |||
1272 | if (p->port_type == FW_PORT_TYPE_BT_SGMII || | ||
1273 | p->port_type == FW_PORT_TYPE_BT_XAUI) | ||
1274 | cmd->port = PORT_TP; | ||
1275 | else if (p->port_type == FW_PORT_TYPE_FIBER) | ||
1276 | cmd->port = PORT_FIBRE; | ||
1277 | else if (p->port_type == FW_PORT_TYPE_TWINAX) | ||
1278 | cmd->port = PORT_DA; | ||
1279 | else | ||
1280 | cmd->port = PORT_OTHER; | ||
1281 | |||
1282 | if (p->mdio_addr >= 0) { | ||
1283 | cmd->phy_address = p->mdio_addr; | ||
1284 | cmd->transceiver = XCVR_EXTERNAL; | ||
1285 | cmd->mdio_support = p->port_type == FW_PORT_TYPE_BT_SGMII ? | ||
1286 | MDIO_SUPPORTS_C22 : MDIO_SUPPORTS_C45; | ||
1287 | } else { | ||
1288 | cmd->phy_address = 0; /* not really, but no better option */ | ||
1289 | cmd->transceiver = XCVR_INTERNAL; | ||
1290 | cmd->mdio_support = 0; | ||
1291 | } | ||
1292 | |||
1293 | cmd->supported = from_fw_linkcaps(p->port_type, p->link_cfg.supported); | ||
1294 | cmd->advertising = from_fw_linkcaps(p->port_type, | ||
1295 | p->link_cfg.advertising); | ||
1296 | cmd->speed = netif_carrier_ok(dev) ? p->link_cfg.speed : 0; | ||
1297 | cmd->duplex = DUPLEX_FULL; | ||
1298 | cmd->autoneg = p->link_cfg.autoneg; | ||
1299 | cmd->maxtxpkt = 0; | ||
1300 | cmd->maxrxpkt = 0; | ||
1301 | return 0; | ||
1302 | } | ||
1303 | |||
1304 | static unsigned int speed_to_caps(int speed) | ||
1305 | { | ||
1306 | if (speed == SPEED_100) | ||
1307 | return FW_PORT_CAP_SPEED_100M; | ||
1308 | if (speed == SPEED_1000) | ||
1309 | return FW_PORT_CAP_SPEED_1G; | ||
1310 | if (speed == SPEED_10000) | ||
1311 | return FW_PORT_CAP_SPEED_10G; | ||
1312 | return 0; | ||
1313 | } | ||
1314 | |||
1315 | static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1316 | { | ||
1317 | unsigned int cap; | ||
1318 | struct port_info *p = netdev_priv(dev); | ||
1319 | struct link_config *lc = &p->link_cfg; | ||
1320 | |||
1321 | if (cmd->duplex != DUPLEX_FULL) /* only full-duplex supported */ | ||
1322 | return -EINVAL; | ||
1323 | |||
1324 | if (!(lc->supported & FW_PORT_CAP_ANEG)) { | ||
1325 | /* | ||
1326 | * PHY offers a single speed. See if that's what's | ||
1327 | * being requested. | ||
1328 | */ | ||
1329 | if (cmd->autoneg == AUTONEG_DISABLE && | ||
1330 | (lc->supported & speed_to_caps(cmd->speed))) | ||
1331 | return 0; | ||
1332 | return -EINVAL; | ||
1333 | } | ||
1334 | |||
1335 | if (cmd->autoneg == AUTONEG_DISABLE) { | ||
1336 | cap = speed_to_caps(cmd->speed); | ||
1337 | |||
1338 | if (!(lc->supported & cap) || cmd->speed == SPEED_1000 || | ||
1339 | cmd->speed == SPEED_10000) | ||
1340 | return -EINVAL; | ||
1341 | lc->requested_speed = cap; | ||
1342 | lc->advertising = 0; | ||
1343 | } else { | ||
1344 | cap = to_fw_linkcaps(cmd->advertising); | ||
1345 | if (!(lc->supported & cap)) | ||
1346 | return -EINVAL; | ||
1347 | lc->requested_speed = 0; | ||
1348 | lc->advertising = cap | FW_PORT_CAP_ANEG; | ||
1349 | } | ||
1350 | lc->autoneg = cmd->autoneg; | ||
1351 | |||
1352 | if (netif_running(dev)) | ||
1353 | return t4_link_start(p->adapter, 0, p->tx_chan, lc); | ||
1354 | return 0; | ||
1355 | } | ||
1356 | |||
1357 | static void get_pauseparam(struct net_device *dev, | ||
1358 | struct ethtool_pauseparam *epause) | ||
1359 | { | ||
1360 | struct port_info *p = netdev_priv(dev); | ||
1361 | |||
1362 | epause->autoneg = (p->link_cfg.requested_fc & PAUSE_AUTONEG) != 0; | ||
1363 | epause->rx_pause = (p->link_cfg.fc & PAUSE_RX) != 0; | ||
1364 | epause->tx_pause = (p->link_cfg.fc & PAUSE_TX) != 0; | ||
1365 | } | ||
1366 | |||
1367 | static int set_pauseparam(struct net_device *dev, | ||
1368 | struct ethtool_pauseparam *epause) | ||
1369 | { | ||
1370 | struct port_info *p = netdev_priv(dev); | ||
1371 | struct link_config *lc = &p->link_cfg; | ||
1372 | |||
1373 | if (epause->autoneg == AUTONEG_DISABLE) | ||
1374 | lc->requested_fc = 0; | ||
1375 | else if (lc->supported & FW_PORT_CAP_ANEG) | ||
1376 | lc->requested_fc = PAUSE_AUTONEG; | ||
1377 | else | ||
1378 | return -EINVAL; | ||
1379 | |||
1380 | if (epause->rx_pause) | ||
1381 | lc->requested_fc |= PAUSE_RX; | ||
1382 | if (epause->tx_pause) | ||
1383 | lc->requested_fc |= PAUSE_TX; | ||
1384 | if (netif_running(dev)) | ||
1385 | return t4_link_start(p->adapter, 0, p->tx_chan, lc); | ||
1386 | return 0; | ||
1387 | } | ||
1388 | |||
1389 | static u32 get_rx_csum(struct net_device *dev) | ||
1390 | { | ||
1391 | struct port_info *p = netdev_priv(dev); | ||
1392 | |||
1393 | return p->rx_offload & RX_CSO; | ||
1394 | } | ||
1395 | |||
1396 | static int set_rx_csum(struct net_device *dev, u32 data) | ||
1397 | { | ||
1398 | struct port_info *p = netdev_priv(dev); | ||
1399 | |||
1400 | if (data) | ||
1401 | p->rx_offload |= RX_CSO; | ||
1402 | else | ||
1403 | p->rx_offload &= ~RX_CSO; | ||
1404 | return 0; | ||
1405 | } | ||
1406 | |||
1407 | static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e) | ||
1408 | { | ||
1409 | const struct port_info *pi = netdev_priv(dev); | ||
1410 | const struct sge *s = &pi->adapter->sge; | ||
1411 | |||
1412 | e->rx_max_pending = MAX_RX_BUFFERS; | ||
1413 | e->rx_mini_max_pending = MAX_RSPQ_ENTRIES; | ||
1414 | e->rx_jumbo_max_pending = 0; | ||
1415 | e->tx_max_pending = MAX_TXQ_ENTRIES; | ||
1416 | |||
1417 | e->rx_pending = s->ethrxq[pi->first_qset].fl.size - 8; | ||
1418 | e->rx_mini_pending = s->ethrxq[pi->first_qset].rspq.size; | ||
1419 | e->rx_jumbo_pending = 0; | ||
1420 | e->tx_pending = s->ethtxq[pi->first_qset].q.size; | ||
1421 | } | ||
1422 | |||
1423 | static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e) | ||
1424 | { | ||
1425 | int i; | ||
1426 | const struct port_info *pi = netdev_priv(dev); | ||
1427 | struct adapter *adapter = pi->adapter; | ||
1428 | struct sge *s = &adapter->sge; | ||
1429 | |||
1430 | if (e->rx_pending > MAX_RX_BUFFERS || e->rx_jumbo_pending || | ||
1431 | e->tx_pending > MAX_TXQ_ENTRIES || | ||
1432 | e->rx_mini_pending > MAX_RSPQ_ENTRIES || | ||
1433 | e->rx_mini_pending < MIN_RSPQ_ENTRIES || | ||
1434 | e->rx_pending < MIN_FL_ENTRIES || e->tx_pending < MIN_TXQ_ENTRIES) | ||
1435 | return -EINVAL; | ||
1436 | |||
1437 | if (adapter->flags & FULL_INIT_DONE) | ||
1438 | return -EBUSY; | ||
1439 | |||
1440 | for (i = 0; i < pi->nqsets; ++i) { | ||
1441 | s->ethtxq[pi->first_qset + i].q.size = e->tx_pending; | ||
1442 | s->ethrxq[pi->first_qset + i].fl.size = e->rx_pending + 8; | ||
1443 | s->ethrxq[pi->first_qset + i].rspq.size = e->rx_mini_pending; | ||
1444 | } | ||
1445 | return 0; | ||
1446 | } | ||
1447 | |||
1448 | static int closest_timer(const struct sge *s, int time) | ||
1449 | { | ||
1450 | int i, delta, match = 0, min_delta = INT_MAX; | ||
1451 | |||
1452 | for (i = 0; i < ARRAY_SIZE(s->timer_val); i++) { | ||
1453 | delta = time - s->timer_val[i]; | ||
1454 | if (delta < 0) | ||
1455 | delta = -delta; | ||
1456 | if (delta < min_delta) { | ||
1457 | min_delta = delta; | ||
1458 | match = i; | ||
1459 | } | ||
1460 | } | ||
1461 | return match; | ||
1462 | } | ||
1463 | |||
1464 | static int closest_thres(const struct sge *s, int thres) | ||
1465 | { | ||
1466 | int i, delta, match = 0, min_delta = INT_MAX; | ||
1467 | |||
1468 | for (i = 0; i < ARRAY_SIZE(s->counter_val); i++) { | ||
1469 | delta = thres - s->counter_val[i]; | ||
1470 | if (delta < 0) | ||
1471 | delta = -delta; | ||
1472 | if (delta < min_delta) { | ||
1473 | min_delta = delta; | ||
1474 | match = i; | ||
1475 | } | ||
1476 | } | ||
1477 | return match; | ||
1478 | } | ||
1479 | |||
1480 | /* | ||
1481 | * Return a queue's interrupt hold-off time in us. 0 means no timer. | ||
1482 | */ | ||
1483 | static unsigned int qtimer_val(const struct adapter *adap, | ||
1484 | const struct sge_rspq *q) | ||
1485 | { | ||
1486 | unsigned int idx = q->intr_params >> 1; | ||
1487 | |||
1488 | return idx < SGE_NTIMERS ? adap->sge.timer_val[idx] : 0; | ||
1489 | } | ||
1490 | |||
1491 | /** | ||
1492 | * set_rxq_intr_params - set a queue's interrupt holdoff parameters | ||
1493 | * @adap: the adapter | ||
1494 | * @q: the Rx queue | ||
1495 | * @us: the hold-off time in us, or 0 to disable timer | ||
1496 | * @cnt: the hold-off packet count, or 0 to disable counter | ||
1497 | * | ||
1498 | * Sets an Rx queue's interrupt hold-off time and packet count. At least | ||
1499 | * one of the two needs to be enabled for the queue to generate interrupts. | ||
1500 | */ | ||
1501 | static int set_rxq_intr_params(struct adapter *adap, struct sge_rspq *q, | ||
1502 | unsigned int us, unsigned int cnt) | ||
1503 | { | ||
1504 | if ((us | cnt) == 0) | ||
1505 | cnt = 1; | ||
1506 | |||
1507 | if (cnt) { | ||
1508 | int err; | ||
1509 | u32 v, new_idx; | ||
1510 | |||
1511 | new_idx = closest_thres(&adap->sge, cnt); | ||
1512 | if (q->desc && q->pktcnt_idx != new_idx) { | ||
1513 | /* the queue has already been created, update it */ | ||
1514 | v = FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) | | ||
1515 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH) | | ||
1516 | FW_PARAMS_PARAM_YZ(q->cntxt_id); | ||
1517 | err = t4_set_params(adap, 0, 0, 0, 1, &v, &new_idx); | ||
1518 | if (err) | ||
1519 | return err; | ||
1520 | } | ||
1521 | q->pktcnt_idx = new_idx; | ||
1522 | } | ||
1523 | |||
1524 | us = us == 0 ? 6 : closest_timer(&adap->sge, us); | ||
1525 | q->intr_params = QINTR_TIMER_IDX(us) | (cnt > 0 ? QINTR_CNT_EN : 0); | ||
1526 | return 0; | ||
1527 | } | ||
1528 | |||
1529 | static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | ||
1530 | { | ||
1531 | const struct port_info *pi = netdev_priv(dev); | ||
1532 | struct adapter *adap = pi->adapter; | ||
1533 | |||
1534 | return set_rxq_intr_params(adap, &adap->sge.ethrxq[pi->first_qset].rspq, | ||
1535 | c->rx_coalesce_usecs, c->rx_max_coalesced_frames); | ||
1536 | } | ||
1537 | |||
1538 | static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | ||
1539 | { | ||
1540 | const struct port_info *pi = netdev_priv(dev); | ||
1541 | const struct adapter *adap = pi->adapter; | ||
1542 | const struct sge_rspq *rq = &adap->sge.ethrxq[pi->first_qset].rspq; | ||
1543 | |||
1544 | c->rx_coalesce_usecs = qtimer_val(adap, rq); | ||
1545 | c->rx_max_coalesced_frames = (rq->intr_params & QINTR_CNT_EN) ? | ||
1546 | adap->sge.counter_val[rq->pktcnt_idx] : 0; | ||
1547 | return 0; | ||
1548 | } | ||
1549 | |||
1550 | /* | ||
1551 | * Translate a physical EEPROM address to virtual. The first 1K is accessed | ||
1552 | * through virtual addresses starting at 31K, the rest is accessed through | ||
1553 | * virtual addresses starting at 0. This mapping is correct only for PF0. | ||
1554 | */ | ||
1555 | static int eeprom_ptov(unsigned int phys_addr) | ||
1556 | { | ||
1557 | if (phys_addr < 1024) | ||
1558 | return phys_addr + (31 << 10); | ||
1559 | if (phys_addr < EEPROMSIZE) | ||
1560 | return phys_addr - 1024; | ||
1561 | return -EINVAL; | ||
1562 | } | ||
1563 | |||
1564 | /* | ||
1565 | * The next two routines implement eeprom read/write from physical addresses. | ||
1566 | * The physical->virtual translation is correct only for PF0. | ||
1567 | */ | ||
1568 | static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v) | ||
1569 | { | ||
1570 | int vaddr = eeprom_ptov(phys_addr); | ||
1571 | |||
1572 | if (vaddr >= 0) | ||
1573 | vaddr = pci_read_vpd(adap->pdev, vaddr, sizeof(u32), v); | ||
1574 | return vaddr < 0 ? vaddr : 0; | ||
1575 | } | ||
1576 | |||
1577 | static int eeprom_wr_phys(struct adapter *adap, unsigned int phys_addr, u32 v) | ||
1578 | { | ||
1579 | int vaddr = eeprom_ptov(phys_addr); | ||
1580 | |||
1581 | if (vaddr >= 0) | ||
1582 | vaddr = pci_write_vpd(adap->pdev, vaddr, sizeof(u32), &v); | ||
1583 | return vaddr < 0 ? vaddr : 0; | ||
1584 | } | ||
1585 | |||
1586 | #define EEPROM_MAGIC 0x38E2F10C | ||
1587 | |||
1588 | static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e, | ||
1589 | u8 *data) | ||
1590 | { | ||
1591 | int i, err = 0; | ||
1592 | struct adapter *adapter = netdev2adap(dev); | ||
1593 | |||
1594 | u8 *buf = kmalloc(EEPROMSIZE, GFP_KERNEL); | ||
1595 | if (!buf) | ||
1596 | return -ENOMEM; | ||
1597 | |||
1598 | e->magic = EEPROM_MAGIC; | ||
1599 | for (i = e->offset & ~3; !err && i < e->offset + e->len; i += 4) | ||
1600 | err = eeprom_rd_phys(adapter, i, (u32 *)&buf[i]); | ||
1601 | |||
1602 | if (!err) | ||
1603 | memcpy(data, buf + e->offset, e->len); | ||
1604 | kfree(buf); | ||
1605 | return err; | ||
1606 | } | ||
1607 | |||
1608 | static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | ||
1609 | u8 *data) | ||
1610 | { | ||
1611 | u8 *buf; | ||
1612 | int err = 0; | ||
1613 | u32 aligned_offset, aligned_len, *p; | ||
1614 | struct adapter *adapter = netdev2adap(dev); | ||
1615 | |||
1616 | if (eeprom->magic != EEPROM_MAGIC) | ||
1617 | return -EINVAL; | ||
1618 | |||
1619 | aligned_offset = eeprom->offset & ~3; | ||
1620 | aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3; | ||
1621 | |||
1622 | if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) { | ||
1623 | /* | ||
1624 | * RMW possibly needed for first or last words. | ||
1625 | */ | ||
1626 | buf = kmalloc(aligned_len, GFP_KERNEL); | ||
1627 | if (!buf) | ||
1628 | return -ENOMEM; | ||
1629 | err = eeprom_rd_phys(adapter, aligned_offset, (u32 *)buf); | ||
1630 | if (!err && aligned_len > 4) | ||
1631 | err = eeprom_rd_phys(adapter, | ||
1632 | aligned_offset + aligned_len - 4, | ||
1633 | (u32 *)&buf[aligned_len - 4]); | ||
1634 | if (err) | ||
1635 | goto out; | ||
1636 | memcpy(buf + (eeprom->offset & 3), data, eeprom->len); | ||
1637 | } else | ||
1638 | buf = data; | ||
1639 | |||
1640 | err = t4_seeprom_wp(adapter, false); | ||
1641 | if (err) | ||
1642 | goto out; | ||
1643 | |||
1644 | for (p = (u32 *)buf; !err && aligned_len; aligned_len -= 4, p++) { | ||
1645 | err = eeprom_wr_phys(adapter, aligned_offset, *p); | ||
1646 | aligned_offset += 4; | ||
1647 | } | ||
1648 | |||
1649 | if (!err) | ||
1650 | err = t4_seeprom_wp(adapter, true); | ||
1651 | out: | ||
1652 | if (buf != data) | ||
1653 | kfree(buf); | ||
1654 | return err; | ||
1655 | } | ||
1656 | |||
1657 | static int set_flash(struct net_device *netdev, struct ethtool_flash *ef) | ||
1658 | { | ||
1659 | int ret; | ||
1660 | const struct firmware *fw; | ||
1661 | struct adapter *adap = netdev2adap(netdev); | ||
1662 | |||
1663 | ef->data[sizeof(ef->data) - 1] = '\0'; | ||
1664 | ret = request_firmware(&fw, ef->data, adap->pdev_dev); | ||
1665 | if (ret < 0) | ||
1666 | return ret; | ||
1667 | |||
1668 | ret = t4_load_fw(adap, fw->data, fw->size); | ||
1669 | release_firmware(fw); | ||
1670 | if (!ret) | ||
1671 | dev_info(adap->pdev_dev, "loaded firmware %s\n", ef->data); | ||
1672 | return ret; | ||
1673 | } | ||
1674 | |||
1675 | #define WOL_SUPPORTED (WAKE_BCAST | WAKE_MAGIC) | ||
1676 | #define BCAST_CRC 0xa0ccc1a6 | ||
1677 | |||
1678 | static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | ||
1679 | { | ||
1680 | wol->supported = WAKE_BCAST | WAKE_MAGIC; | ||
1681 | wol->wolopts = netdev2adap(dev)->wol; | ||
1682 | memset(&wol->sopass, 0, sizeof(wol->sopass)); | ||
1683 | } | ||
1684 | |||
1685 | static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | ||
1686 | { | ||
1687 | int err = 0; | ||
1688 | struct port_info *pi = netdev_priv(dev); | ||
1689 | |||
1690 | if (wol->wolopts & ~WOL_SUPPORTED) | ||
1691 | return -EINVAL; | ||
1692 | t4_wol_magic_enable(pi->adapter, pi->tx_chan, | ||
1693 | (wol->wolopts & WAKE_MAGIC) ? dev->dev_addr : NULL); | ||
1694 | if (wol->wolopts & WAKE_BCAST) { | ||
1695 | err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0xfe, ~0ULL, | ||
1696 | ~0ULL, 0, false); | ||
1697 | if (!err) | ||
1698 | err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 1, | ||
1699 | ~6ULL, ~0ULL, BCAST_CRC, true); | ||
1700 | } else | ||
1701 | t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0, 0, 0, 0, false); | ||
1702 | return err; | ||
1703 | } | ||
1704 | |||
1705 | static int set_tso(struct net_device *dev, u32 value) | ||
1706 | { | ||
1707 | if (value) | ||
1708 | dev->features |= NETIF_F_TSO | NETIF_F_TSO6; | ||
1709 | else | ||
1710 | dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); | ||
1711 | return 0; | ||
1712 | } | ||
1713 | |||
1714 | static struct ethtool_ops cxgb_ethtool_ops = { | ||
1715 | .get_settings = get_settings, | ||
1716 | .set_settings = set_settings, | ||
1717 | .get_drvinfo = get_drvinfo, | ||
1718 | .get_msglevel = get_msglevel, | ||
1719 | .set_msglevel = set_msglevel, | ||
1720 | .get_ringparam = get_sge_param, | ||
1721 | .set_ringparam = set_sge_param, | ||
1722 | .get_coalesce = get_coalesce, | ||
1723 | .set_coalesce = set_coalesce, | ||
1724 | .get_eeprom_len = get_eeprom_len, | ||
1725 | .get_eeprom = get_eeprom, | ||
1726 | .set_eeprom = set_eeprom, | ||
1727 | .get_pauseparam = get_pauseparam, | ||
1728 | .set_pauseparam = set_pauseparam, | ||
1729 | .get_rx_csum = get_rx_csum, | ||
1730 | .set_rx_csum = set_rx_csum, | ||
1731 | .set_tx_csum = ethtool_op_set_tx_ipv6_csum, | ||
1732 | .set_sg = ethtool_op_set_sg, | ||
1733 | .get_link = ethtool_op_get_link, | ||
1734 | .get_strings = get_strings, | ||
1735 | .phys_id = identify_port, | ||
1736 | .nway_reset = restart_autoneg, | ||
1737 | .get_sset_count = get_sset_count, | ||
1738 | .get_ethtool_stats = get_stats, | ||
1739 | .get_regs_len = get_regs_len, | ||
1740 | .get_regs = get_regs, | ||
1741 | .get_wol = get_wol, | ||
1742 | .set_wol = set_wol, | ||
1743 | .set_tso = set_tso, | ||
1744 | .flash_device = set_flash, | ||
1745 | }; | ||
1746 | |||
1747 | /* | ||
1748 | * debugfs support | ||
1749 | */ | ||
1750 | |||
1751 | static int mem_open(struct inode *inode, struct file *file) | ||
1752 | { | ||
1753 | file->private_data = inode->i_private; | ||
1754 | return 0; | ||
1755 | } | ||
1756 | |||
1757 | static ssize_t mem_read(struct file *file, char __user *buf, size_t count, | ||
1758 | loff_t *ppos) | ||
1759 | { | ||
1760 | loff_t pos = *ppos; | ||
1761 | loff_t avail = file->f_path.dentry->d_inode->i_size; | ||
1762 | unsigned int mem = (uintptr_t)file->private_data & 3; | ||
1763 | struct adapter *adap = file->private_data - mem; | ||
1764 | |||
1765 | if (pos < 0) | ||
1766 | return -EINVAL; | ||
1767 | if (pos >= avail) | ||
1768 | return 0; | ||
1769 | if (count > avail - pos) | ||
1770 | count = avail - pos; | ||
1771 | |||
1772 | while (count) { | ||
1773 | size_t len; | ||
1774 | int ret, ofst; | ||
1775 | __be32 data[16]; | ||
1776 | |||
1777 | if (mem == MEM_MC) | ||
1778 | ret = t4_mc_read(adap, pos, data, NULL); | ||
1779 | else | ||
1780 | ret = t4_edc_read(adap, mem, pos, data, NULL); | ||
1781 | if (ret) | ||
1782 | return ret; | ||
1783 | |||
1784 | ofst = pos % sizeof(data); | ||
1785 | len = min(count, sizeof(data) - ofst); | ||
1786 | if (copy_to_user(buf, (u8 *)data + ofst, len)) | ||
1787 | return -EFAULT; | ||
1788 | |||
1789 | buf += len; | ||
1790 | pos += len; | ||
1791 | count -= len; | ||
1792 | } | ||
1793 | count = pos - *ppos; | ||
1794 | *ppos = pos; | ||
1795 | return count; | ||
1796 | } | ||
1797 | |||
1798 | static const struct file_operations mem_debugfs_fops = { | ||
1799 | .owner = THIS_MODULE, | ||
1800 | .open = mem_open, | ||
1801 | .read = mem_read, | ||
1802 | }; | ||
1803 | |||
1804 | static void __devinit add_debugfs_mem(struct adapter *adap, const char *name, | ||
1805 | unsigned int idx, unsigned int size_mb) | ||
1806 | { | ||
1807 | struct dentry *de; | ||
1808 | |||
1809 | de = debugfs_create_file(name, S_IRUSR, adap->debugfs_root, | ||
1810 | (void *)adap + idx, &mem_debugfs_fops); | ||
1811 | if (de && de->d_inode) | ||
1812 | de->d_inode->i_size = size_mb << 20; | ||
1813 | } | ||
1814 | |||
1815 | static int __devinit setup_debugfs(struct adapter *adap) | ||
1816 | { | ||
1817 | int i; | ||
1818 | |||
1819 | if (IS_ERR_OR_NULL(adap->debugfs_root)) | ||
1820 | return -1; | ||
1821 | |||
1822 | i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE); | ||
1823 | if (i & EDRAM0_ENABLE) | ||
1824 | add_debugfs_mem(adap, "edc0", MEM_EDC0, 5); | ||
1825 | if (i & EDRAM1_ENABLE) | ||
1826 | add_debugfs_mem(adap, "edc1", MEM_EDC1, 5); | ||
1827 | if (i & EXT_MEM_ENABLE) | ||
1828 | add_debugfs_mem(adap, "mc", MEM_MC, | ||
1829 | EXT_MEM_SIZE_GET(t4_read_reg(adap, MA_EXT_MEMORY_BAR))); | ||
1830 | if (adap->l2t) | ||
1831 | debugfs_create_file("l2t", S_IRUSR, adap->debugfs_root, adap, | ||
1832 | &t4_l2t_fops); | ||
1833 | return 0; | ||
1834 | } | ||
1835 | |||
1836 | /* | ||
1837 | * upper-layer driver support | ||
1838 | */ | ||
1839 | |||
1840 | /* | ||
1841 | * Allocate an active-open TID and set it to the supplied value. | ||
1842 | */ | ||
1843 | int cxgb4_alloc_atid(struct tid_info *t, void *data) | ||
1844 | { | ||
1845 | int atid = -1; | ||
1846 | |||
1847 | spin_lock_bh(&t->atid_lock); | ||
1848 | if (t->afree) { | ||
1849 | union aopen_entry *p = t->afree; | ||
1850 | |||
1851 | atid = p - t->atid_tab; | ||
1852 | t->afree = p->next; | ||
1853 | p->data = data; | ||
1854 | t->atids_in_use++; | ||
1855 | } | ||
1856 | spin_unlock_bh(&t->atid_lock); | ||
1857 | return atid; | ||
1858 | } | ||
1859 | EXPORT_SYMBOL(cxgb4_alloc_atid); | ||
1860 | |||
1861 | /* | ||
1862 | * Release an active-open TID. | ||
1863 | */ | ||
1864 | void cxgb4_free_atid(struct tid_info *t, unsigned int atid) | ||
1865 | { | ||
1866 | union aopen_entry *p = &t->atid_tab[atid]; | ||
1867 | |||
1868 | spin_lock_bh(&t->atid_lock); | ||
1869 | p->next = t->afree; | ||
1870 | t->afree = p; | ||
1871 | t->atids_in_use--; | ||
1872 | spin_unlock_bh(&t->atid_lock); | ||
1873 | } | ||
1874 | EXPORT_SYMBOL(cxgb4_free_atid); | ||
1875 | |||
1876 | /* | ||
1877 | * Allocate a server TID and set it to the supplied value. | ||
1878 | */ | ||
1879 | int cxgb4_alloc_stid(struct tid_info *t, int family, void *data) | ||
1880 | { | ||
1881 | int stid; | ||
1882 | |||
1883 | spin_lock_bh(&t->stid_lock); | ||
1884 | if (family == PF_INET) { | ||
1885 | stid = find_first_zero_bit(t->stid_bmap, t->nstids); | ||
1886 | if (stid < t->nstids) | ||
1887 | __set_bit(stid, t->stid_bmap); | ||
1888 | else | ||
1889 | stid = -1; | ||
1890 | } else { | ||
1891 | stid = bitmap_find_free_region(t->stid_bmap, t->nstids, 2); | ||
1892 | if (stid < 0) | ||
1893 | stid = -1; | ||
1894 | } | ||
1895 | if (stid >= 0) { | ||
1896 | t->stid_tab[stid].data = data; | ||
1897 | stid += t->stid_base; | ||
1898 | t->stids_in_use++; | ||
1899 | } | ||
1900 | spin_unlock_bh(&t->stid_lock); | ||
1901 | return stid; | ||
1902 | } | ||
1903 | EXPORT_SYMBOL(cxgb4_alloc_stid); | ||
1904 | |||
1905 | /* | ||
1906 | * Release a server TID. | ||
1907 | */ | ||
1908 | void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family) | ||
1909 | { | ||
1910 | stid -= t->stid_base; | ||
1911 | spin_lock_bh(&t->stid_lock); | ||
1912 | if (family == PF_INET) | ||
1913 | __clear_bit(stid, t->stid_bmap); | ||
1914 | else | ||
1915 | bitmap_release_region(t->stid_bmap, stid, 2); | ||
1916 | t->stid_tab[stid].data = NULL; | ||
1917 | t->stids_in_use--; | ||
1918 | spin_unlock_bh(&t->stid_lock); | ||
1919 | } | ||
1920 | EXPORT_SYMBOL(cxgb4_free_stid); | ||
1921 | |||
1922 | /* | ||
1923 | * Populate a TID_RELEASE WR. Caller must properly size the skb. | ||
1924 | */ | ||
1925 | static void mk_tid_release(struct sk_buff *skb, unsigned int chan, | ||
1926 | unsigned int tid) | ||
1927 | { | ||
1928 | struct cpl_tid_release *req; | ||
1929 | |||
1930 | set_wr_txq(skb, CPL_PRIORITY_SETUP, chan); | ||
1931 | req = (struct cpl_tid_release *)__skb_put(skb, sizeof(*req)); | ||
1932 | INIT_TP_WR(req, tid); | ||
1933 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, tid)); | ||
1934 | } | ||
1935 | |||
1936 | /* | ||
1937 | * Queue a TID release request and if necessary schedule a work queue to | ||
1938 | * process it. | ||
1939 | */ | ||
1940 | void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, | ||
1941 | unsigned int tid) | ||
1942 | { | ||
1943 | void **p = &t->tid_tab[tid]; | ||
1944 | struct adapter *adap = container_of(t, struct adapter, tids); | ||
1945 | |||
1946 | spin_lock_bh(&adap->tid_release_lock); | ||
1947 | *p = adap->tid_release_head; | ||
1948 | /* Low 2 bits encode the Tx channel number */ | ||
1949 | adap->tid_release_head = (void **)((uintptr_t)p | chan); | ||
1950 | if (!adap->tid_release_task_busy) { | ||
1951 | adap->tid_release_task_busy = true; | ||
1952 | schedule_work(&adap->tid_release_task); | ||
1953 | } | ||
1954 | spin_unlock_bh(&adap->tid_release_lock); | ||
1955 | } | ||
1956 | EXPORT_SYMBOL(cxgb4_queue_tid_release); | ||
1957 | |||
1958 | /* | ||
1959 | * Process the list of pending TID release requests. | ||
1960 | */ | ||
1961 | static void process_tid_release_list(struct work_struct *work) | ||
1962 | { | ||
1963 | struct sk_buff *skb; | ||
1964 | struct adapter *adap; | ||
1965 | |||
1966 | adap = container_of(work, struct adapter, tid_release_task); | ||
1967 | |||
1968 | spin_lock_bh(&adap->tid_release_lock); | ||
1969 | while (adap->tid_release_head) { | ||
1970 | void **p = adap->tid_release_head; | ||
1971 | unsigned int chan = (uintptr_t)p & 3; | ||
1972 | p = (void *)p - chan; | ||
1973 | |||
1974 | adap->tid_release_head = *p; | ||
1975 | *p = NULL; | ||
1976 | spin_unlock_bh(&adap->tid_release_lock); | ||
1977 | |||
1978 | while (!(skb = alloc_skb(sizeof(struct cpl_tid_release), | ||
1979 | GFP_KERNEL))) | ||
1980 | schedule_timeout_uninterruptible(1); | ||
1981 | |||
1982 | mk_tid_release(skb, chan, p - adap->tids.tid_tab); | ||
1983 | t4_ofld_send(adap, skb); | ||
1984 | spin_lock_bh(&adap->tid_release_lock); | ||
1985 | } | ||
1986 | adap->tid_release_task_busy = false; | ||
1987 | spin_unlock_bh(&adap->tid_release_lock); | ||
1988 | } | ||
1989 | |||
1990 | /* | ||
1991 | * Release a TID and inform HW. If we are unable to allocate the release | ||
1992 | * message we defer to a work queue. | ||
1993 | */ | ||
1994 | void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid) | ||
1995 | { | ||
1996 | void *old; | ||
1997 | struct sk_buff *skb; | ||
1998 | struct adapter *adap = container_of(t, struct adapter, tids); | ||
1999 | |||
2000 | old = t->tid_tab[tid]; | ||
2001 | skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_ATOMIC); | ||
2002 | if (likely(skb)) { | ||
2003 | t->tid_tab[tid] = NULL; | ||
2004 | mk_tid_release(skb, chan, tid); | ||
2005 | t4_ofld_send(adap, skb); | ||
2006 | } else | ||
2007 | cxgb4_queue_tid_release(t, chan, tid); | ||
2008 | if (old) | ||
2009 | atomic_dec(&t->tids_in_use); | ||
2010 | } | ||
2011 | EXPORT_SYMBOL(cxgb4_remove_tid); | ||
2012 | |||
2013 | /* | ||
2014 | * Allocate and initialize the TID tables. Returns 0 on success. | ||
2015 | */ | ||
2016 | static int tid_init(struct tid_info *t) | ||
2017 | { | ||
2018 | size_t size; | ||
2019 | unsigned int natids = t->natids; | ||
2020 | |||
2021 | size = t->ntids * sizeof(*t->tid_tab) + natids * sizeof(*t->atid_tab) + | ||
2022 | t->nstids * sizeof(*t->stid_tab) + | ||
2023 | BITS_TO_LONGS(t->nstids) * sizeof(long); | ||
2024 | t->tid_tab = t4_alloc_mem(size); | ||
2025 | if (!t->tid_tab) | ||
2026 | return -ENOMEM; | ||
2027 | |||
2028 | t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids]; | ||
2029 | t->stid_tab = (struct serv_entry *)&t->atid_tab[natids]; | ||
2030 | t->stid_bmap = (unsigned long *)&t->stid_tab[t->nstids]; | ||
2031 | spin_lock_init(&t->stid_lock); | ||
2032 | spin_lock_init(&t->atid_lock); | ||
2033 | |||
2034 | t->stids_in_use = 0; | ||
2035 | t->afree = NULL; | ||
2036 | t->atids_in_use = 0; | ||
2037 | atomic_set(&t->tids_in_use, 0); | ||
2038 | |||
2039 | /* Setup the free list for atid_tab and clear the stid bitmap. */ | ||
2040 | if (natids) { | ||
2041 | while (--natids) | ||
2042 | t->atid_tab[natids - 1].next = &t->atid_tab[natids]; | ||
2043 | t->afree = t->atid_tab; | ||
2044 | } | ||
2045 | bitmap_zero(t->stid_bmap, t->nstids); | ||
2046 | return 0; | ||
2047 | } | ||
2048 | |||
2049 | /** | ||
2050 | * cxgb4_create_server - create an IP server | ||
2051 | * @dev: the device | ||
2052 | * @stid: the server TID | ||
2053 | * @sip: local IP address to bind server to | ||
2054 | * @sport: the server's TCP port | ||
2055 | * @queue: queue to direct messages from this server to | ||
2056 | * | ||
2057 | * Create an IP server for the given port and address. | ||
2058 | * Returns <0 on error and one of the %NET_XMIT_* values on success. | ||
2059 | */ | ||
2060 | int cxgb4_create_server(const struct net_device *dev, unsigned int stid, | ||
2061 | __be32 sip, __be16 sport, unsigned int queue) | ||
2062 | { | ||
2063 | unsigned int chan; | ||
2064 | struct sk_buff *skb; | ||
2065 | struct adapter *adap; | ||
2066 | struct cpl_pass_open_req *req; | ||
2067 | |||
2068 | skb = alloc_skb(sizeof(*req), GFP_KERNEL); | ||
2069 | if (!skb) | ||
2070 | return -ENOMEM; | ||
2071 | |||
2072 | adap = netdev2adap(dev); | ||
2073 | req = (struct cpl_pass_open_req *)__skb_put(skb, sizeof(*req)); | ||
2074 | INIT_TP_WR(req, 0); | ||
2075 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ, stid)); | ||
2076 | req->local_port = sport; | ||
2077 | req->peer_port = htons(0); | ||
2078 | req->local_ip = sip; | ||
2079 | req->peer_ip = htonl(0); | ||
2080 | chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan; | ||
2081 | req->opt0 = cpu_to_be64(TX_CHAN(chan)); | ||
2082 | req->opt1 = cpu_to_be64(CONN_POLICY_ASK | | ||
2083 | SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); | ||
2084 | return t4_mgmt_tx(adap, skb); | ||
2085 | } | ||
2086 | EXPORT_SYMBOL(cxgb4_create_server); | ||
2087 | |||
2088 | /** | ||
2089 | * cxgb4_create_server6 - create an IPv6 server | ||
2090 | * @dev: the device | ||
2091 | * @stid: the server TID | ||
2092 | * @sip: local IPv6 address to bind server to | ||
2093 | * @sport: the server's TCP port | ||
2094 | * @queue: queue to direct messages from this server to | ||
2095 | * | ||
2096 | * Create an IPv6 server for the given port and address. | ||
2097 | * Returns <0 on error and one of the %NET_XMIT_* values on success. | ||
2098 | */ | ||
2099 | int cxgb4_create_server6(const struct net_device *dev, unsigned int stid, | ||
2100 | const struct in6_addr *sip, __be16 sport, | ||
2101 | unsigned int queue) | ||
2102 | { | ||
2103 | unsigned int chan; | ||
2104 | struct sk_buff *skb; | ||
2105 | struct adapter *adap; | ||
2106 | struct cpl_pass_open_req6 *req; | ||
2107 | |||
2108 | skb = alloc_skb(sizeof(*req), GFP_KERNEL); | ||
2109 | if (!skb) | ||
2110 | return -ENOMEM; | ||
2111 | |||
2112 | adap = netdev2adap(dev); | ||
2113 | req = (struct cpl_pass_open_req6 *)__skb_put(skb, sizeof(*req)); | ||
2114 | INIT_TP_WR(req, 0); | ||
2115 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ6, stid)); | ||
2116 | req->local_port = sport; | ||
2117 | req->peer_port = htons(0); | ||
2118 | req->local_ip_hi = *(__be64 *)(sip->s6_addr); | ||
2119 | req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8); | ||
2120 | req->peer_ip_hi = cpu_to_be64(0); | ||
2121 | req->peer_ip_lo = cpu_to_be64(0); | ||
2122 | chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan; | ||
2123 | req->opt0 = cpu_to_be64(TX_CHAN(chan)); | ||
2124 | req->opt1 = cpu_to_be64(CONN_POLICY_ASK | | ||
2125 | SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); | ||
2126 | return t4_mgmt_tx(adap, skb); | ||
2127 | } | ||
2128 | EXPORT_SYMBOL(cxgb4_create_server6); | ||
2129 | |||
2130 | /** | ||
2131 | * cxgb4_best_mtu - find the entry in the MTU table closest to an MTU | ||
2132 | * @mtus: the HW MTU table | ||
2133 | * @mtu: the target MTU | ||
2134 | * @idx: index of selected entry in the MTU table | ||
2135 | * | ||
2136 | * Returns the index and the value in the HW MTU table that is closest to | ||
2137 | * but does not exceed @mtu, unless @mtu is smaller than any value in the | ||
2138 | * table, in which case that smallest available value is selected. | ||
2139 | */ | ||
2140 | unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu, | ||
2141 | unsigned int *idx) | ||
2142 | { | ||
2143 | unsigned int i = 0; | ||
2144 | |||
2145 | while (i < NMTUS - 1 && mtus[i + 1] <= mtu) | ||
2146 | ++i; | ||
2147 | if (idx) | ||
2148 | *idx = i; | ||
2149 | return mtus[i]; | ||
2150 | } | ||
2151 | EXPORT_SYMBOL(cxgb4_best_mtu); | ||
2152 | |||
2153 | /** | ||
2154 | * cxgb4_port_chan - get the HW channel of a port | ||
2155 | * @dev: the net device for the port | ||
2156 | * | ||
2157 | * Return the HW Tx channel of the given port. | ||
2158 | */ | ||
2159 | unsigned int cxgb4_port_chan(const struct net_device *dev) | ||
2160 | { | ||
2161 | return netdev2pinfo(dev)->tx_chan; | ||
2162 | } | ||
2163 | EXPORT_SYMBOL(cxgb4_port_chan); | ||
2164 | |||
2165 | /** | ||
2166 | * cxgb4_port_viid - get the VI id of a port | ||
2167 | * @dev: the net device for the port | ||
2168 | * | ||
2169 | * Return the VI id of the given port. | ||
2170 | */ | ||
2171 | unsigned int cxgb4_port_viid(const struct net_device *dev) | ||
2172 | { | ||
2173 | return netdev2pinfo(dev)->viid; | ||
2174 | } | ||
2175 | EXPORT_SYMBOL(cxgb4_port_viid); | ||
2176 | |||
2177 | /** | ||
2178 | * cxgb4_port_idx - get the index of a port | ||
2179 | * @dev: the net device for the port | ||
2180 | * | ||
2181 | * Return the index of the given port. | ||
2182 | */ | ||
2183 | unsigned int cxgb4_port_idx(const struct net_device *dev) | ||
2184 | { | ||
2185 | return netdev2pinfo(dev)->port_id; | ||
2186 | } | ||
2187 | EXPORT_SYMBOL(cxgb4_port_idx); | ||
2188 | |||
2189 | /** | ||
2190 | * cxgb4_netdev_by_hwid - return the net device of a HW port | ||
2191 | * @pdev: identifies the adapter | ||
2192 | * @id: the HW port id | ||
2193 | * | ||
2194 | * Return the net device associated with the interface with the given HW | ||
2195 | * id. | ||
2196 | */ | ||
2197 | struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id) | ||
2198 | { | ||
2199 | const struct adapter *adap = pci_get_drvdata(pdev); | ||
2200 | |||
2201 | if (!adap || id >= NCHAN) | ||
2202 | return NULL; | ||
2203 | id = adap->chan_map[id]; | ||
2204 | return id < MAX_NPORTS ? adap->port[id] : NULL; | ||
2205 | } | ||
2206 | EXPORT_SYMBOL(cxgb4_netdev_by_hwid); | ||
2207 | |||
2208 | void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4, | ||
2209 | struct tp_tcp_stats *v6) | ||
2210 | { | ||
2211 | struct adapter *adap = pci_get_drvdata(pdev); | ||
2212 | |||
2213 | spin_lock(&adap->stats_lock); | ||
2214 | t4_tp_get_tcp_stats(adap, v4, v6); | ||
2215 | spin_unlock(&adap->stats_lock); | ||
2216 | } | ||
2217 | EXPORT_SYMBOL(cxgb4_get_tcp_stats); | ||
2218 | |||
2219 | void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask, | ||
2220 | const unsigned int *pgsz_order) | ||
2221 | { | ||
2222 | struct adapter *adap = netdev2adap(dev); | ||
2223 | |||
2224 | t4_write_reg(adap, ULP_RX_ISCSI_TAGMASK, tag_mask); | ||
2225 | t4_write_reg(adap, ULP_RX_ISCSI_PSZ, HPZ0(pgsz_order[0]) | | ||
2226 | HPZ1(pgsz_order[1]) | HPZ2(pgsz_order[2]) | | ||
2227 | HPZ3(pgsz_order[3])); | ||
2228 | } | ||
2229 | EXPORT_SYMBOL(cxgb4_iscsi_init); | ||
2230 | |||
2231 | static struct pci_driver cxgb4_driver; | ||
2232 | |||
2233 | static void check_neigh_update(struct neighbour *neigh) | ||
2234 | { | ||
2235 | const struct device *parent; | ||
2236 | const struct net_device *netdev = neigh->dev; | ||
2237 | |||
2238 | if (netdev->priv_flags & IFF_802_1Q_VLAN) | ||
2239 | netdev = vlan_dev_real_dev(netdev); | ||
2240 | parent = netdev->dev.parent; | ||
2241 | if (parent && parent->driver == &cxgb4_driver.driver) | ||
2242 | t4_l2t_update(dev_get_drvdata(parent), neigh); | ||
2243 | } | ||
2244 | |||
2245 | static int netevent_cb(struct notifier_block *nb, unsigned long event, | ||
2246 | void *data) | ||
2247 | { | ||
2248 | switch (event) { | ||
2249 | case NETEVENT_NEIGH_UPDATE: | ||
2250 | check_neigh_update(data); | ||
2251 | break; | ||
2252 | case NETEVENT_PMTU_UPDATE: | ||
2253 | case NETEVENT_REDIRECT: | ||
2254 | default: | ||
2255 | break; | ||
2256 | } | ||
2257 | return 0; | ||
2258 | } | ||
2259 | |||
2260 | static bool netevent_registered; | ||
2261 | static struct notifier_block cxgb4_netevent_nb = { | ||
2262 | .notifier_call = netevent_cb | ||
2263 | }; | ||
2264 | |||
2265 | static void uld_attach(struct adapter *adap, unsigned int uld) | ||
2266 | { | ||
2267 | void *handle; | ||
2268 | struct cxgb4_lld_info lli; | ||
2269 | |||
2270 | lli.pdev = adap->pdev; | ||
2271 | lli.l2t = adap->l2t; | ||
2272 | lli.tids = &adap->tids; | ||
2273 | lli.ports = adap->port; | ||
2274 | lli.vr = &adap->vres; | ||
2275 | lli.mtus = adap->params.mtus; | ||
2276 | if (uld == CXGB4_ULD_RDMA) { | ||
2277 | lli.rxq_ids = adap->sge.rdma_rxq; | ||
2278 | lli.nrxq = adap->sge.rdmaqs; | ||
2279 | } else if (uld == CXGB4_ULD_ISCSI) { | ||
2280 | lli.rxq_ids = adap->sge.ofld_rxq; | ||
2281 | lli.nrxq = adap->sge.ofldqsets; | ||
2282 | } | ||
2283 | lli.ntxq = adap->sge.ofldqsets; | ||
2284 | lli.nchan = adap->params.nports; | ||
2285 | lli.nports = adap->params.nports; | ||
2286 | lli.wr_cred = adap->params.ofldq_wr_cred; | ||
2287 | lli.adapter_type = adap->params.rev; | ||
2288 | lli.iscsi_iolen = MAXRXDATA_GET(t4_read_reg(adap, TP_PARA_REG2)); | ||
2289 | lli.udb_density = 1 << QUEUESPERPAGEPF0_GET( | ||
2290 | t4_read_reg(adap, SGE_EGRESS_QUEUES_PER_PAGE_PF)); | ||
2291 | lli.ucq_density = 1 << QUEUESPERPAGEPF0_GET( | ||
2292 | t4_read_reg(adap, SGE_INGRESS_QUEUES_PER_PAGE_PF)); | ||
2293 | lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS); | ||
2294 | lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL); | ||
2295 | lli.fw_vers = adap->params.fw_vers; | ||
2296 | |||
2297 | handle = ulds[uld].add(&lli); | ||
2298 | if (IS_ERR(handle)) { | ||
2299 | dev_warn(adap->pdev_dev, | ||
2300 | "could not attach to the %s driver, error %ld\n", | ||
2301 | uld_str[uld], PTR_ERR(handle)); | ||
2302 | return; | ||
2303 | } | ||
2304 | |||
2305 | adap->uld_handle[uld] = handle; | ||
2306 | |||
2307 | if (!netevent_registered) { | ||
2308 | register_netevent_notifier(&cxgb4_netevent_nb); | ||
2309 | netevent_registered = true; | ||
2310 | } | ||
2311 | } | ||
2312 | |||
2313 | static void attach_ulds(struct adapter *adap) | ||
2314 | { | ||
2315 | unsigned int i; | ||
2316 | |||
2317 | mutex_lock(&uld_mutex); | ||
2318 | list_add_tail(&adap->list_node, &adapter_list); | ||
2319 | for (i = 0; i < CXGB4_ULD_MAX; i++) | ||
2320 | if (ulds[i].add) | ||
2321 | uld_attach(adap, i); | ||
2322 | mutex_unlock(&uld_mutex); | ||
2323 | } | ||
2324 | |||
2325 | static void detach_ulds(struct adapter *adap) | ||
2326 | { | ||
2327 | unsigned int i; | ||
2328 | |||
2329 | mutex_lock(&uld_mutex); | ||
2330 | list_del(&adap->list_node); | ||
2331 | for (i = 0; i < CXGB4_ULD_MAX; i++) | ||
2332 | if (adap->uld_handle[i]) { | ||
2333 | ulds[i].state_change(adap->uld_handle[i], | ||
2334 | CXGB4_STATE_DETACH); | ||
2335 | adap->uld_handle[i] = NULL; | ||
2336 | } | ||
2337 | if (netevent_registered && list_empty(&adapter_list)) { | ||
2338 | unregister_netevent_notifier(&cxgb4_netevent_nb); | ||
2339 | netevent_registered = false; | ||
2340 | } | ||
2341 | mutex_unlock(&uld_mutex); | ||
2342 | } | ||
2343 | |||
2344 | static void notify_ulds(struct adapter *adap, enum cxgb4_state new_state) | ||
2345 | { | ||
2346 | unsigned int i; | ||
2347 | |||
2348 | mutex_lock(&uld_mutex); | ||
2349 | for (i = 0; i < CXGB4_ULD_MAX; i++) | ||
2350 | if (adap->uld_handle[i]) | ||
2351 | ulds[i].state_change(adap->uld_handle[i], new_state); | ||
2352 | mutex_unlock(&uld_mutex); | ||
2353 | } | ||
2354 | |||
2355 | /** | ||
2356 | * cxgb4_register_uld - register an upper-layer driver | ||
2357 | * @type: the ULD type | ||
2358 | * @p: the ULD methods | ||
2359 | * | ||
2360 | * Registers an upper-layer driver with this driver and notifies the ULD | ||
2361 | * about any presently available devices that support its type. Returns | ||
2362 | * %-EBUSY if a ULD of the same type is already registered. | ||
2363 | */ | ||
2364 | int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p) | ||
2365 | { | ||
2366 | int ret = 0; | ||
2367 | struct adapter *adap; | ||
2368 | |||
2369 | if (type >= CXGB4_ULD_MAX) | ||
2370 | return -EINVAL; | ||
2371 | mutex_lock(&uld_mutex); | ||
2372 | if (ulds[type].add) { | ||
2373 | ret = -EBUSY; | ||
2374 | goto out; | ||
2375 | } | ||
2376 | ulds[type] = *p; | ||
2377 | list_for_each_entry(adap, &adapter_list, list_node) | ||
2378 | uld_attach(adap, type); | ||
2379 | out: mutex_unlock(&uld_mutex); | ||
2380 | return ret; | ||
2381 | } | ||
2382 | EXPORT_SYMBOL(cxgb4_register_uld); | ||
2383 | |||
2384 | /** | ||
2385 | * cxgb4_unregister_uld - unregister an upper-layer driver | ||
2386 | * @type: the ULD type | ||
2387 | * | ||
2388 | * Unregisters an existing upper-layer driver. | ||
2389 | */ | ||
2390 | int cxgb4_unregister_uld(enum cxgb4_uld type) | ||
2391 | { | ||
2392 | struct adapter *adap; | ||
2393 | |||
2394 | if (type >= CXGB4_ULD_MAX) | ||
2395 | return -EINVAL; | ||
2396 | mutex_lock(&uld_mutex); | ||
2397 | list_for_each_entry(adap, &adapter_list, list_node) | ||
2398 | adap->uld_handle[type] = NULL; | ||
2399 | ulds[type].add = NULL; | ||
2400 | mutex_unlock(&uld_mutex); | ||
2401 | return 0; | ||
2402 | } | ||
2403 | EXPORT_SYMBOL(cxgb4_unregister_uld); | ||
2404 | |||
2405 | /** | ||
2406 | * cxgb_up - enable the adapter | ||
2407 | * @adap: adapter being enabled | ||
2408 | * | ||
2409 | * Called when the first port is enabled, this function performs the | ||
2410 | * actions necessary to make an adapter operational, such as completing | ||
2411 | * the initialization of HW modules, and enabling interrupts. | ||
2412 | * | ||
2413 | * Must be called with the rtnl lock held. | ||
2414 | */ | ||
2415 | static int cxgb_up(struct adapter *adap) | ||
2416 | { | ||
2417 | int err = 0; | ||
2418 | |||
2419 | if (!(adap->flags & FULL_INIT_DONE)) { | ||
2420 | err = setup_sge_queues(adap); | ||
2421 | if (err) | ||
2422 | goto out; | ||
2423 | err = setup_rss(adap); | ||
2424 | if (err) { | ||
2425 | t4_free_sge_resources(adap); | ||
2426 | goto out; | ||
2427 | } | ||
2428 | if (adap->flags & USING_MSIX) | ||
2429 | name_msix_vecs(adap); | ||
2430 | adap->flags |= FULL_INIT_DONE; | ||
2431 | } | ||
2432 | |||
2433 | if (adap->flags & USING_MSIX) { | ||
2434 | err = request_irq(adap->msix_info[0].vec, t4_nondata_intr, 0, | ||
2435 | adap->msix_info[0].desc, adap); | ||
2436 | if (err) | ||
2437 | goto irq_err; | ||
2438 | |||
2439 | err = request_msix_queue_irqs(adap); | ||
2440 | if (err) { | ||
2441 | free_irq(adap->msix_info[0].vec, adap); | ||
2442 | goto irq_err; | ||
2443 | } | ||
2444 | } else { | ||
2445 | err = request_irq(adap->pdev->irq, t4_intr_handler(adap), | ||
2446 | (adap->flags & USING_MSI) ? 0 : IRQF_SHARED, | ||
2447 | adap->name, adap); | ||
2448 | if (err) | ||
2449 | goto irq_err; | ||
2450 | } | ||
2451 | enable_rx(adap); | ||
2452 | t4_sge_start(adap); | ||
2453 | t4_intr_enable(adap); | ||
2454 | notify_ulds(adap, CXGB4_STATE_UP); | ||
2455 | out: | ||
2456 | return err; | ||
2457 | irq_err: | ||
2458 | dev_err(adap->pdev_dev, "request_irq failed, err %d\n", err); | ||
2459 | goto out; | ||
2460 | } | ||
2461 | |||
2462 | static void cxgb_down(struct adapter *adapter) | ||
2463 | { | ||
2464 | t4_intr_disable(adapter); | ||
2465 | cancel_work_sync(&adapter->tid_release_task); | ||
2466 | adapter->tid_release_task_busy = false; | ||
2467 | |||
2468 | if (adapter->flags & USING_MSIX) { | ||
2469 | free_msix_queue_irqs(adapter); | ||
2470 | free_irq(adapter->msix_info[0].vec, adapter); | ||
2471 | } else | ||
2472 | free_irq(adapter->pdev->irq, adapter); | ||
2473 | quiesce_rx(adapter); | ||
2474 | } | ||
2475 | |||
2476 | /* | ||
2477 | * net_device operations | ||
2478 | */ | ||
2479 | static int cxgb_open(struct net_device *dev) | ||
2480 | { | ||
2481 | int err; | ||
2482 | struct port_info *pi = netdev_priv(dev); | ||
2483 | struct adapter *adapter = pi->adapter; | ||
2484 | |||
2485 | if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) | ||
2486 | return err; | ||
2487 | |||
2488 | dev->real_num_tx_queues = pi->nqsets; | ||
2489 | set_bit(pi->tx_chan, &adapter->open_device_map); | ||
2490 | link_start(dev); | ||
2491 | netif_tx_start_all_queues(dev); | ||
2492 | return 0; | ||
2493 | } | ||
2494 | |||
2495 | static int cxgb_close(struct net_device *dev) | ||
2496 | { | ||
2497 | int ret; | ||
2498 | struct port_info *pi = netdev_priv(dev); | ||
2499 | struct adapter *adapter = pi->adapter; | ||
2500 | |||
2501 | netif_tx_stop_all_queues(dev); | ||
2502 | netif_carrier_off(dev); | ||
2503 | ret = t4_enable_vi(adapter, 0, pi->viid, false, false); | ||
2504 | |||
2505 | clear_bit(pi->tx_chan, &adapter->open_device_map); | ||
2506 | |||
2507 | if (!adapter->open_device_map) | ||
2508 | cxgb_down(adapter); | ||
2509 | return 0; | ||
2510 | } | ||
2511 | |||
2512 | static struct net_device_stats *cxgb_get_stats(struct net_device *dev) | ||
2513 | { | ||
2514 | struct port_stats stats; | ||
2515 | struct port_info *p = netdev_priv(dev); | ||
2516 | struct adapter *adapter = p->adapter; | ||
2517 | struct net_device_stats *ns = &dev->stats; | ||
2518 | |||
2519 | spin_lock(&adapter->stats_lock); | ||
2520 | t4_get_port_stats(adapter, p->tx_chan, &stats); | ||
2521 | spin_unlock(&adapter->stats_lock); | ||
2522 | |||
2523 | ns->tx_bytes = stats.tx_octets; | ||
2524 | ns->tx_packets = stats.tx_frames; | ||
2525 | ns->rx_bytes = stats.rx_octets; | ||
2526 | ns->rx_packets = stats.rx_frames; | ||
2527 | ns->multicast = stats.rx_mcast_frames; | ||
2528 | |||
2529 | /* detailed rx_errors */ | ||
2530 | ns->rx_length_errors = stats.rx_jabber + stats.rx_too_long + | ||
2531 | stats.rx_runt; | ||
2532 | ns->rx_over_errors = 0; | ||
2533 | ns->rx_crc_errors = stats.rx_fcs_err; | ||
2534 | ns->rx_frame_errors = stats.rx_symbol_err; | ||
2535 | ns->rx_fifo_errors = stats.rx_ovflow0 + stats.rx_ovflow1 + | ||
2536 | stats.rx_ovflow2 + stats.rx_ovflow3 + | ||
2537 | stats.rx_trunc0 + stats.rx_trunc1 + | ||
2538 | stats.rx_trunc2 + stats.rx_trunc3; | ||
2539 | ns->rx_missed_errors = 0; | ||
2540 | |||
2541 | /* detailed tx_errors */ | ||
2542 | ns->tx_aborted_errors = 0; | ||
2543 | ns->tx_carrier_errors = 0; | ||
2544 | ns->tx_fifo_errors = 0; | ||
2545 | ns->tx_heartbeat_errors = 0; | ||
2546 | ns->tx_window_errors = 0; | ||
2547 | |||
2548 | ns->tx_errors = stats.tx_error_frames; | ||
2549 | ns->rx_errors = stats.rx_symbol_err + stats.rx_fcs_err + | ||
2550 | ns->rx_length_errors + stats.rx_len_err + ns->rx_fifo_errors; | ||
2551 | return ns; | ||
2552 | } | ||
2553 | |||
2554 | static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd) | ||
2555 | { | ||
2556 | int ret = 0, prtad, devad; | ||
2557 | struct port_info *pi = netdev_priv(dev); | ||
2558 | struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data; | ||
2559 | |||
2560 | switch (cmd) { | ||
2561 | case SIOCGMIIPHY: | ||
2562 | if (pi->mdio_addr < 0) | ||
2563 | return -EOPNOTSUPP; | ||
2564 | data->phy_id = pi->mdio_addr; | ||
2565 | break; | ||
2566 | case SIOCGMIIREG: | ||
2567 | case SIOCSMIIREG: | ||
2568 | if (mdio_phy_id_is_c45(data->phy_id)) { | ||
2569 | prtad = mdio_phy_id_prtad(data->phy_id); | ||
2570 | devad = mdio_phy_id_devad(data->phy_id); | ||
2571 | } else if (data->phy_id < 32) { | ||
2572 | prtad = data->phy_id; | ||
2573 | devad = 0; | ||
2574 | data->reg_num &= 0x1f; | ||
2575 | } else | ||
2576 | return -EINVAL; | ||
2577 | |||
2578 | if (cmd == SIOCGMIIREG) | ||
2579 | ret = t4_mdio_rd(pi->adapter, 0, prtad, devad, | ||
2580 | data->reg_num, &data->val_out); | ||
2581 | else | ||
2582 | ret = t4_mdio_wr(pi->adapter, 0, prtad, devad, | ||
2583 | data->reg_num, data->val_in); | ||
2584 | break; | ||
2585 | default: | ||
2586 | return -EOPNOTSUPP; | ||
2587 | } | ||
2588 | return ret; | ||
2589 | } | ||
2590 | |||
2591 | static void cxgb_set_rxmode(struct net_device *dev) | ||
2592 | { | ||
2593 | /* unfortunately we can't return errors to the stack */ | ||
2594 | set_rxmode(dev, -1, false); | ||
2595 | } | ||
2596 | |||
2597 | static int cxgb_change_mtu(struct net_device *dev, int new_mtu) | ||
2598 | { | ||
2599 | int ret; | ||
2600 | struct port_info *pi = netdev_priv(dev); | ||
2601 | |||
2602 | if (new_mtu < 81 || new_mtu > MAX_MTU) /* accommodate SACK */ | ||
2603 | return -EINVAL; | ||
2604 | ret = t4_set_rxmode(pi->adapter, 0, pi->viid, new_mtu, -1, -1, -1, | ||
2605 | true); | ||
2606 | if (!ret) | ||
2607 | dev->mtu = new_mtu; | ||
2608 | return ret; | ||
2609 | } | ||
2610 | |||
2611 | static int cxgb_set_mac_addr(struct net_device *dev, void *p) | ||
2612 | { | ||
2613 | int ret; | ||
2614 | struct sockaddr *addr = p; | ||
2615 | struct port_info *pi = netdev_priv(dev); | ||
2616 | |||
2617 | if (!is_valid_ether_addr(addr->sa_data)) | ||
2618 | return -EINVAL; | ||
2619 | |||
2620 | ret = t4_change_mac(pi->adapter, 0, pi->viid, pi->xact_addr_filt, | ||
2621 | addr->sa_data, true, true); | ||
2622 | if (ret < 0) | ||
2623 | return ret; | ||
2624 | |||
2625 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | ||
2626 | pi->xact_addr_filt = ret; | ||
2627 | return 0; | ||
2628 | } | ||
2629 | |||
2630 | static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp) | ||
2631 | { | ||
2632 | struct port_info *pi = netdev_priv(dev); | ||
2633 | |||
2634 | pi->vlan_grp = grp; | ||
2635 | t4_set_vlan_accel(pi->adapter, 1 << pi->tx_chan, grp != NULL); | ||
2636 | } | ||
2637 | |||
2638 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
2639 | static void cxgb_netpoll(struct net_device *dev) | ||
2640 | { | ||
2641 | struct port_info *pi = netdev_priv(dev); | ||
2642 | struct adapter *adap = pi->adapter; | ||
2643 | |||
2644 | if (adap->flags & USING_MSIX) { | ||
2645 | int i; | ||
2646 | struct sge_eth_rxq *rx = &adap->sge.ethrxq[pi->first_qset]; | ||
2647 | |||
2648 | for (i = pi->nqsets; i; i--, rx++) | ||
2649 | t4_sge_intr_msix(0, &rx->rspq); | ||
2650 | } else | ||
2651 | t4_intr_handler(adap)(0, adap); | ||
2652 | } | ||
2653 | #endif | ||
2654 | |||
2655 | static const struct net_device_ops cxgb4_netdev_ops = { | ||
2656 | .ndo_open = cxgb_open, | ||
2657 | .ndo_stop = cxgb_close, | ||
2658 | .ndo_start_xmit = t4_eth_xmit, | ||
2659 | .ndo_get_stats = cxgb_get_stats, | ||
2660 | .ndo_set_rx_mode = cxgb_set_rxmode, | ||
2661 | .ndo_set_mac_address = cxgb_set_mac_addr, | ||
2662 | .ndo_validate_addr = eth_validate_addr, | ||
2663 | .ndo_do_ioctl = cxgb_ioctl, | ||
2664 | .ndo_change_mtu = cxgb_change_mtu, | ||
2665 | .ndo_vlan_rx_register = vlan_rx_register, | ||
2666 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
2667 | .ndo_poll_controller = cxgb_netpoll, | ||
2668 | #endif | ||
2669 | }; | ||
2670 | |||
2671 | void t4_fatal_err(struct adapter *adap) | ||
2672 | { | ||
2673 | t4_set_reg_field(adap, SGE_CONTROL, GLOBALENABLE, 0); | ||
2674 | t4_intr_disable(adap); | ||
2675 | dev_alert(adap->pdev_dev, "encountered fatal error, adapter stopped\n"); | ||
2676 | } | ||
2677 | |||
2678 | static void setup_memwin(struct adapter *adap) | ||
2679 | { | ||
2680 | u32 bar0; | ||
2681 | |||
2682 | bar0 = pci_resource_start(adap->pdev, 0); /* truncation intentional */ | ||
2683 | t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 0), | ||
2684 | (bar0 + MEMWIN0_BASE) | BIR(0) | | ||
2685 | WINDOW(ilog2(MEMWIN0_APERTURE) - 10)); | ||
2686 | t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 1), | ||
2687 | (bar0 + MEMWIN1_BASE) | BIR(0) | | ||
2688 | WINDOW(ilog2(MEMWIN1_APERTURE) - 10)); | ||
2689 | t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2), | ||
2690 | (bar0 + MEMWIN2_BASE) | BIR(0) | | ||
2691 | WINDOW(ilog2(MEMWIN2_APERTURE) - 10)); | ||
2692 | } | ||
2693 | |||
2694 | /* | ||
2695 | * Max # of ATIDs. The absolute HW max is 16K but we keep it lower. | ||
2696 | */ | ||
2697 | #define MAX_ATIDS 8192U | ||
2698 | |||
2699 | /* | ||
2700 | * Phase 0 of initialization: contact FW, obtain config, perform basic init. | ||
2701 | */ | ||
2702 | static int adap_init0(struct adapter *adap) | ||
2703 | { | ||
2704 | int ret; | ||
2705 | u32 v, port_vec; | ||
2706 | enum dev_state state; | ||
2707 | u32 params[7], val[7]; | ||
2708 | struct fw_caps_config_cmd c; | ||
2709 | |||
2710 | ret = t4_check_fw_version(adap); | ||
2711 | if (ret == -EINVAL || ret > 0) { | ||
2712 | if (upgrade_fw(adap) >= 0) /* recache FW version */ | ||
2713 | ret = t4_check_fw_version(adap); | ||
2714 | } | ||
2715 | if (ret < 0) | ||
2716 | return ret; | ||
2717 | |||
2718 | /* contact FW, request master */ | ||
2719 | ret = t4_fw_hello(adap, 0, 0, MASTER_MUST, &state); | ||
2720 | if (ret < 0) { | ||
2721 | dev_err(adap->pdev_dev, "could not connect to FW, error %d\n", | ||
2722 | ret); | ||
2723 | return ret; | ||
2724 | } | ||
2725 | |||
2726 | /* reset device */ | ||
2727 | ret = t4_fw_reset(adap, 0, PIORSTMODE | PIORST); | ||
2728 | if (ret < 0) | ||
2729 | goto bye; | ||
2730 | |||
2731 | /* get device capabilities */ | ||
2732 | memset(&c, 0, sizeof(c)); | ||
2733 | c.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | | ||
2734 | FW_CMD_REQUEST | FW_CMD_READ); | ||
2735 | c.retval_len16 = htonl(FW_LEN16(c)); | ||
2736 | ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c); | ||
2737 | if (ret < 0) | ||
2738 | goto bye; | ||
2739 | |||
2740 | /* select capabilities we'll be using */ | ||
2741 | if (c.niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) { | ||
2742 | if (!vf_acls) | ||
2743 | c.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM); | ||
2744 | else | ||
2745 | c.niccaps = htons(FW_CAPS_CONFIG_NIC_VM); | ||
2746 | } else if (vf_acls) { | ||
2747 | dev_err(adap->pdev_dev, "virtualization ACLs not supported"); | ||
2748 | goto bye; | ||
2749 | } | ||
2750 | c.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | | ||
2751 | FW_CMD_REQUEST | FW_CMD_WRITE); | ||
2752 | ret = t4_wr_mbox(adap, 0, &c, sizeof(c), NULL); | ||
2753 | if (ret < 0) | ||
2754 | goto bye; | ||
2755 | |||
2756 | ret = t4_config_glbl_rss(adap, 0, | ||
2757 | FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL, | ||
2758 | FW_RSS_GLB_CONFIG_CMD_TNLMAPEN | | ||
2759 | FW_RSS_GLB_CONFIG_CMD_TNLALLLKP); | ||
2760 | if (ret < 0) | ||
2761 | goto bye; | ||
2762 | |||
2763 | ret = t4_cfg_pfvf(adap, 0, 0, 0, 64, 64, 64, 0, 0, 4, 0xf, 0xf, 16, | ||
2764 | FW_CMD_CAP_PF, FW_CMD_CAP_PF); | ||
2765 | if (ret < 0) | ||
2766 | goto bye; | ||
2767 | |||
2768 | for (v = 0; v < SGE_NTIMERS - 1; v++) | ||
2769 | adap->sge.timer_val[v] = min(intr_holdoff[v], MAX_SGE_TIMERVAL); | ||
2770 | adap->sge.timer_val[SGE_NTIMERS - 1] = MAX_SGE_TIMERVAL; | ||
2771 | adap->sge.counter_val[0] = 1; | ||
2772 | for (v = 1; v < SGE_NCOUNTERS; v++) | ||
2773 | adap->sge.counter_val[v] = min(intr_cnt[v - 1], | ||
2774 | THRESHOLD_3_MASK); | ||
2775 | t4_sge_init(adap); | ||
2776 | |||
2777 | /* get basic stuff going */ | ||
2778 | ret = t4_early_init(adap, 0); | ||
2779 | if (ret < 0) | ||
2780 | goto bye; | ||
2781 | |||
2782 | #define FW_PARAM_DEV(param) \ | ||
2783 | (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \ | ||
2784 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param)) | ||
2785 | |||
2786 | #define FW_PARAM_PFVF(param) \ | ||
2787 | (FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \ | ||
2788 | FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param)) | ||
2789 | |||
2790 | params[0] = FW_PARAM_DEV(PORTVEC); | ||
2791 | params[1] = FW_PARAM_PFVF(L2T_START); | ||
2792 | params[2] = FW_PARAM_PFVF(L2T_END); | ||
2793 | params[3] = FW_PARAM_PFVF(FILTER_START); | ||
2794 | params[4] = FW_PARAM_PFVF(FILTER_END); | ||
2795 | ret = t4_query_params(adap, 0, 0, 0, 5, params, val); | ||
2796 | if (ret < 0) | ||
2797 | goto bye; | ||
2798 | port_vec = val[0]; | ||
2799 | adap->tids.ftid_base = val[3]; | ||
2800 | adap->tids.nftids = val[4] - val[3] + 1; | ||
2801 | |||
2802 | if (c.ofldcaps) { | ||
2803 | /* query offload-related parameters */ | ||
2804 | params[0] = FW_PARAM_DEV(NTID); | ||
2805 | params[1] = FW_PARAM_PFVF(SERVER_START); | ||
2806 | params[2] = FW_PARAM_PFVF(SERVER_END); | ||
2807 | params[3] = FW_PARAM_PFVF(TDDP_START); | ||
2808 | params[4] = FW_PARAM_PFVF(TDDP_END); | ||
2809 | params[5] = FW_PARAM_DEV(FLOWC_BUFFIFO_SZ); | ||
2810 | ret = t4_query_params(adap, 0, 0, 0, 6, params, val); | ||
2811 | if (ret < 0) | ||
2812 | goto bye; | ||
2813 | adap->tids.ntids = val[0]; | ||
2814 | adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS); | ||
2815 | adap->tids.stid_base = val[1]; | ||
2816 | adap->tids.nstids = val[2] - val[1] + 1; | ||
2817 | adap->vres.ddp.start = val[3]; | ||
2818 | adap->vres.ddp.size = val[4] - val[3] + 1; | ||
2819 | adap->params.ofldq_wr_cred = val[5]; | ||
2820 | adap->params.offload = 1; | ||
2821 | } | ||
2822 | if (c.rdmacaps) { | ||
2823 | params[0] = FW_PARAM_PFVF(STAG_START); | ||
2824 | params[1] = FW_PARAM_PFVF(STAG_END); | ||
2825 | params[2] = FW_PARAM_PFVF(RQ_START); | ||
2826 | params[3] = FW_PARAM_PFVF(RQ_END); | ||
2827 | params[4] = FW_PARAM_PFVF(PBL_START); | ||
2828 | params[5] = FW_PARAM_PFVF(PBL_END); | ||
2829 | ret = t4_query_params(adap, 0, 0, 0, 6, params, val); | ||
2830 | if (ret < 0) | ||
2831 | goto bye; | ||
2832 | adap->vres.stag.start = val[0]; | ||
2833 | adap->vres.stag.size = val[1] - val[0] + 1; | ||
2834 | adap->vres.rq.start = val[2]; | ||
2835 | adap->vres.rq.size = val[3] - val[2] + 1; | ||
2836 | adap->vres.pbl.start = val[4]; | ||
2837 | adap->vres.pbl.size = val[5] - val[4] + 1; | ||
2838 | } | ||
2839 | if (c.iscsicaps) { | ||
2840 | params[0] = FW_PARAM_PFVF(ISCSI_START); | ||
2841 | params[1] = FW_PARAM_PFVF(ISCSI_END); | ||
2842 | ret = t4_query_params(adap, 0, 0, 0, 2, params, val); | ||
2843 | if (ret < 0) | ||
2844 | goto bye; | ||
2845 | adap->vres.iscsi.start = val[0]; | ||
2846 | adap->vres.iscsi.size = val[1] - val[0] + 1; | ||
2847 | } | ||
2848 | #undef FW_PARAM_PFVF | ||
2849 | #undef FW_PARAM_DEV | ||
2850 | |||
2851 | adap->params.nports = hweight32(port_vec); | ||
2852 | adap->params.portvec = port_vec; | ||
2853 | adap->flags |= FW_OK; | ||
2854 | |||
2855 | /* These are finalized by FW initialization, load their values now */ | ||
2856 | v = t4_read_reg(adap, TP_TIMER_RESOLUTION); | ||
2857 | adap->params.tp.tre = TIMERRESOLUTION_GET(v); | ||
2858 | t4_read_mtu_tbl(adap, adap->params.mtus, NULL); | ||
2859 | t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd, | ||
2860 | adap->params.b_wnd); | ||
2861 | |||
2862 | /* tweak some settings */ | ||
2863 | t4_write_reg(adap, TP_SHIFT_CNT, 0x64f8849); | ||
2864 | t4_write_reg(adap, ULP_RX_TDDP_PSZ, HPZ0(PAGE_SHIFT - 12)); | ||
2865 | t4_write_reg(adap, TP_PIO_ADDR, TP_INGRESS_CONFIG); | ||
2866 | v = t4_read_reg(adap, TP_PIO_DATA); | ||
2867 | t4_write_reg(adap, TP_PIO_DATA, v & ~CSUM_HAS_PSEUDO_HDR); | ||
2868 | setup_memwin(adap); | ||
2869 | return 0; | ||
2870 | |||
2871 | /* | ||
2872 | * If a command timed out or failed with EIO FW does not operate within | ||
2873 | * its spec or something catastrophic happened to HW/FW, stop issuing | ||
2874 | * commands. | ||
2875 | */ | ||
2876 | bye: if (ret != -ETIMEDOUT && ret != -EIO) | ||
2877 | t4_fw_bye(adap, 0); | ||
2878 | return ret; | ||
2879 | } | ||
2880 | |||
2881 | static inline bool is_10g_port(const struct link_config *lc) | ||
2882 | { | ||
2883 | return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0; | ||
2884 | } | ||
2885 | |||
2886 | static inline void init_rspq(struct sge_rspq *q, u8 timer_idx, u8 pkt_cnt_idx, | ||
2887 | unsigned int size, unsigned int iqe_size) | ||
2888 | { | ||
2889 | q->intr_params = QINTR_TIMER_IDX(timer_idx) | | ||
2890 | (pkt_cnt_idx < SGE_NCOUNTERS ? QINTR_CNT_EN : 0); | ||
2891 | q->pktcnt_idx = pkt_cnt_idx < SGE_NCOUNTERS ? pkt_cnt_idx : 0; | ||
2892 | q->iqe_len = iqe_size; | ||
2893 | q->size = size; | ||
2894 | } | ||
2895 | |||
2896 | /* | ||
2897 | * Perform default configuration of DMA queues depending on the number and type | ||
2898 | * of ports we found and the number of available CPUs. Most settings can be | ||
2899 | * modified by the admin prior to actual use. | ||
2900 | */ | ||
2901 | static void __devinit cfg_queues(struct adapter *adap) | ||
2902 | { | ||
2903 | struct sge *s = &adap->sge; | ||
2904 | int i, q10g = 0, n10g = 0, qidx = 0; | ||
2905 | |||
2906 | for_each_port(adap, i) | ||
2907 | n10g += is_10g_port(&adap2pinfo(adap, i)->link_cfg); | ||
2908 | |||
2909 | /* | ||
2910 | * We default to 1 queue per non-10G port and up to # of cores queues | ||
2911 | * per 10G port. | ||
2912 | */ | ||
2913 | if (n10g) | ||
2914 | q10g = (MAX_ETH_QSETS - (adap->params.nports - n10g)) / n10g; | ||
2915 | if (q10g > num_online_cpus()) | ||
2916 | q10g = num_online_cpus(); | ||
2917 | |||
2918 | for_each_port(adap, i) { | ||
2919 | struct port_info *pi = adap2pinfo(adap, i); | ||
2920 | |||
2921 | pi->first_qset = qidx; | ||
2922 | pi->nqsets = is_10g_port(&pi->link_cfg) ? q10g : 1; | ||
2923 | qidx += pi->nqsets; | ||
2924 | } | ||
2925 | |||
2926 | s->ethqsets = qidx; | ||
2927 | s->max_ethqsets = qidx; /* MSI-X may lower it later */ | ||
2928 | |||
2929 | if (is_offload(adap)) { | ||
2930 | /* | ||
2931 | * For offload we use 1 queue/channel if all ports are up to 1G, | ||
2932 | * otherwise we divide all available queues amongst the channels | ||
2933 | * capped by the number of available cores. | ||
2934 | */ | ||
2935 | if (n10g) { | ||
2936 | i = min_t(int, ARRAY_SIZE(s->ofldrxq), | ||
2937 | num_online_cpus()); | ||
2938 | s->ofldqsets = roundup(i, adap->params.nports); | ||
2939 | } else | ||
2940 | s->ofldqsets = adap->params.nports; | ||
2941 | /* For RDMA one Rx queue per channel suffices */ | ||
2942 | s->rdmaqs = adap->params.nports; | ||
2943 | } | ||
2944 | |||
2945 | for (i = 0; i < ARRAY_SIZE(s->ethrxq); i++) { | ||
2946 | struct sge_eth_rxq *r = &s->ethrxq[i]; | ||
2947 | |||
2948 | init_rspq(&r->rspq, 0, 0, 1024, 64); | ||
2949 | r->fl.size = 72; | ||
2950 | } | ||
2951 | |||
2952 | for (i = 0; i < ARRAY_SIZE(s->ethtxq); i++) | ||
2953 | s->ethtxq[i].q.size = 1024; | ||
2954 | |||
2955 | for (i = 0; i < ARRAY_SIZE(s->ctrlq); i++) | ||
2956 | s->ctrlq[i].q.size = 512; | ||
2957 | |||
2958 | for (i = 0; i < ARRAY_SIZE(s->ofldtxq); i++) | ||
2959 | s->ofldtxq[i].q.size = 1024; | ||
2960 | |||
2961 | for (i = 0; i < ARRAY_SIZE(s->ofldrxq); i++) { | ||
2962 | struct sge_ofld_rxq *r = &s->ofldrxq[i]; | ||
2963 | |||
2964 | init_rspq(&r->rspq, 0, 0, 1024, 64); | ||
2965 | r->rspq.uld = CXGB4_ULD_ISCSI; | ||
2966 | r->fl.size = 72; | ||
2967 | } | ||
2968 | |||
2969 | for (i = 0; i < ARRAY_SIZE(s->rdmarxq); i++) { | ||
2970 | struct sge_ofld_rxq *r = &s->rdmarxq[i]; | ||
2971 | |||
2972 | init_rspq(&r->rspq, 0, 0, 511, 64); | ||
2973 | r->rspq.uld = CXGB4_ULD_RDMA; | ||
2974 | r->fl.size = 72; | ||
2975 | } | ||
2976 | |||
2977 | init_rspq(&s->fw_evtq, 6, 0, 512, 64); | ||
2978 | init_rspq(&s->intrq, 6, 0, 2 * MAX_INGQ, 64); | ||
2979 | } | ||
2980 | |||
2981 | /* | ||
2982 | * Reduce the number of Ethernet queues across all ports to at most n. | ||
2983 | * n provides at least one queue per port. | ||
2984 | */ | ||
2985 | static void __devinit reduce_ethqs(struct adapter *adap, int n) | ||
2986 | { | ||
2987 | int i; | ||
2988 | struct port_info *pi; | ||
2989 | |||
2990 | while (n < adap->sge.ethqsets) | ||
2991 | for_each_port(adap, i) { | ||
2992 | pi = adap2pinfo(adap, i); | ||
2993 | if (pi->nqsets > 1) { | ||
2994 | pi->nqsets--; | ||
2995 | adap->sge.ethqsets--; | ||
2996 | if (adap->sge.ethqsets <= n) | ||
2997 | break; | ||
2998 | } | ||
2999 | } | ||
3000 | |||
3001 | n = 0; | ||
3002 | for_each_port(adap, i) { | ||
3003 | pi = adap2pinfo(adap, i); | ||
3004 | pi->first_qset = n; | ||
3005 | n += pi->nqsets; | ||
3006 | } | ||
3007 | } | ||
3008 | |||
3009 | /* 2 MSI-X vectors needed for the FW queue and non-data interrupts */ | ||
3010 | #define EXTRA_VECS 2 | ||
3011 | |||
3012 | static int __devinit enable_msix(struct adapter *adap) | ||
3013 | { | ||
3014 | int ofld_need = 0; | ||
3015 | int i, err, want, need; | ||
3016 | struct sge *s = &adap->sge; | ||
3017 | unsigned int nchan = adap->params.nports; | ||
3018 | struct msix_entry entries[MAX_INGQ + 1]; | ||
3019 | |||
3020 | for (i = 0; i < ARRAY_SIZE(entries); ++i) | ||
3021 | entries[i].entry = i; | ||
3022 | |||
3023 | want = s->max_ethqsets + EXTRA_VECS; | ||
3024 | if (is_offload(adap)) { | ||
3025 | want += s->rdmaqs + s->ofldqsets; | ||
3026 | /* need nchan for each possible ULD */ | ||
3027 | ofld_need = 2 * nchan; | ||
3028 | } | ||
3029 | need = adap->params.nports + EXTRA_VECS + ofld_need; | ||
3030 | |||
3031 | while ((err = pci_enable_msix(adap->pdev, entries, want)) >= need) | ||
3032 | want = err; | ||
3033 | |||
3034 | if (!err) { | ||
3035 | /* | ||
3036 | * Distribute available vectors to the various queue groups. | ||
3037 | * Every group gets its minimum requirement and NIC gets top | ||
3038 | * priority for leftovers. | ||
3039 | */ | ||
3040 | i = want - EXTRA_VECS - ofld_need; | ||
3041 | if (i < s->max_ethqsets) { | ||
3042 | s->max_ethqsets = i; | ||
3043 | if (i < s->ethqsets) | ||
3044 | reduce_ethqs(adap, i); | ||
3045 | } | ||
3046 | if (is_offload(adap)) { | ||
3047 | i = want - EXTRA_VECS - s->max_ethqsets; | ||
3048 | i -= ofld_need - nchan; | ||
3049 | s->ofldqsets = (i / nchan) * nchan; /* round down */ | ||
3050 | } | ||
3051 | for (i = 0; i < want; ++i) | ||
3052 | adap->msix_info[i].vec = entries[i].vector; | ||
3053 | } else if (err > 0) | ||
3054 | dev_info(adap->pdev_dev, | ||
3055 | "only %d MSI-X vectors left, not using MSI-X\n", err); | ||
3056 | return err; | ||
3057 | } | ||
3058 | |||
3059 | #undef EXTRA_VECS | ||
3060 | |||
3061 | static void __devinit print_port_info(struct adapter *adap) | ||
3062 | { | ||
3063 | static const char *base[] = { | ||
3064 | "R", "KX4", "T", "KX", "T", "KR", "CX4" | ||
3065 | }; | ||
3066 | |||
3067 | int i; | ||
3068 | char buf[80]; | ||
3069 | |||
3070 | for_each_port(adap, i) { | ||
3071 | struct net_device *dev = adap->port[i]; | ||
3072 | const struct port_info *pi = netdev_priv(dev); | ||
3073 | char *bufp = buf; | ||
3074 | |||
3075 | if (!test_bit(i, &adap->registered_device_map)) | ||
3076 | continue; | ||
3077 | |||
3078 | if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M) | ||
3079 | bufp += sprintf(bufp, "100/"); | ||
3080 | if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G) | ||
3081 | bufp += sprintf(bufp, "1000/"); | ||
3082 | if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) | ||
3083 | bufp += sprintf(bufp, "10G/"); | ||
3084 | if (bufp != buf) | ||
3085 | --bufp; | ||
3086 | sprintf(bufp, "BASE-%s", base[pi->port_type]); | ||
3087 | |||
3088 | netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s\n", | ||
3089 | adap->params.vpd.id, adap->params.rev, | ||
3090 | buf, is_offload(adap) ? "R" : "", | ||
3091 | adap->params.pci.width, | ||
3092 | (adap->flags & USING_MSIX) ? " MSI-X" : | ||
3093 | (adap->flags & USING_MSI) ? " MSI" : ""); | ||
3094 | if (adap->name == dev->name) | ||
3095 | netdev_info(dev, "S/N: %s, E/C: %s\n", | ||
3096 | adap->params.vpd.sn, adap->params.vpd.ec); | ||
3097 | } | ||
3098 | } | ||
3099 | |||
3100 | #define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | NETIF_F_TSO6 |\ | ||
3101 | NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA) | ||
3102 | |||
3103 | static int __devinit init_one(struct pci_dev *pdev, | ||
3104 | const struct pci_device_id *ent) | ||
3105 | { | ||
3106 | int func, i, err; | ||
3107 | struct port_info *pi; | ||
3108 | unsigned int highdma = 0; | ||
3109 | struct adapter *adapter = NULL; | ||
3110 | |||
3111 | printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION); | ||
3112 | |||
3113 | err = pci_request_regions(pdev, KBUILD_MODNAME); | ||
3114 | if (err) { | ||
3115 | /* Just info, some other driver may have claimed the device. */ | ||
3116 | dev_info(&pdev->dev, "cannot obtain PCI resources\n"); | ||
3117 | return err; | ||
3118 | } | ||
3119 | |||
3120 | /* We control everything through PF 0 */ | ||
3121 | func = PCI_FUNC(pdev->devfn); | ||
3122 | if (func > 0) | ||
3123 | goto sriov; | ||
3124 | |||
3125 | err = pci_enable_device(pdev); | ||
3126 | if (err) { | ||
3127 | dev_err(&pdev->dev, "cannot enable PCI device\n"); | ||
3128 | goto out_release_regions; | ||
3129 | } | ||
3130 | |||
3131 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { | ||
3132 | highdma = NETIF_F_HIGHDMA; | ||
3133 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); | ||
3134 | if (err) { | ||
3135 | dev_err(&pdev->dev, "unable to obtain 64-bit DMA for " | ||
3136 | "coherent allocations\n"); | ||
3137 | goto out_disable_device; | ||
3138 | } | ||
3139 | } else { | ||
3140 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
3141 | if (err) { | ||
3142 | dev_err(&pdev->dev, "no usable DMA configuration\n"); | ||
3143 | goto out_disable_device; | ||
3144 | } | ||
3145 | } | ||
3146 | |||
3147 | pci_enable_pcie_error_reporting(pdev); | ||
3148 | pci_set_master(pdev); | ||
3149 | pci_save_state(pdev); | ||
3150 | |||
3151 | adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); | ||
3152 | if (!adapter) { | ||
3153 | err = -ENOMEM; | ||
3154 | goto out_disable_device; | ||
3155 | } | ||
3156 | |||
3157 | adapter->regs = pci_ioremap_bar(pdev, 0); | ||
3158 | if (!adapter->regs) { | ||
3159 | dev_err(&pdev->dev, "cannot map device registers\n"); | ||
3160 | err = -ENOMEM; | ||
3161 | goto out_free_adapter; | ||
3162 | } | ||
3163 | |||
3164 | adapter->pdev = pdev; | ||
3165 | adapter->pdev_dev = &pdev->dev; | ||
3166 | adapter->name = pci_name(pdev); | ||
3167 | adapter->msg_enable = dflt_msg_enable; | ||
3168 | memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map)); | ||
3169 | |||
3170 | spin_lock_init(&adapter->stats_lock); | ||
3171 | spin_lock_init(&adapter->tid_release_lock); | ||
3172 | |||
3173 | INIT_WORK(&adapter->tid_release_task, process_tid_release_list); | ||
3174 | |||
3175 | err = t4_prep_adapter(adapter); | ||
3176 | if (err) | ||
3177 | goto out_unmap_bar; | ||
3178 | err = adap_init0(adapter); | ||
3179 | if (err) | ||
3180 | goto out_unmap_bar; | ||
3181 | |||
3182 | for_each_port(adapter, i) { | ||
3183 | struct net_device *netdev; | ||
3184 | |||
3185 | netdev = alloc_etherdev_mq(sizeof(struct port_info), | ||
3186 | MAX_ETH_QSETS); | ||
3187 | if (!netdev) { | ||
3188 | err = -ENOMEM; | ||
3189 | goto out_free_dev; | ||
3190 | } | ||
3191 | |||
3192 | SET_NETDEV_DEV(netdev, &pdev->dev); | ||
3193 | |||
3194 | adapter->port[i] = netdev; | ||
3195 | pi = netdev_priv(netdev); | ||
3196 | pi->adapter = adapter; | ||
3197 | pi->xact_addr_filt = -1; | ||
3198 | pi->rx_offload = RX_CSO; | ||
3199 | pi->port_id = i; | ||
3200 | netif_carrier_off(netdev); | ||
3201 | netif_tx_stop_all_queues(netdev); | ||
3202 | netdev->irq = pdev->irq; | ||
3203 | |||
3204 | netdev->features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6; | ||
3205 | netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; | ||
3206 | netdev->features |= NETIF_F_GRO | highdma; | ||
3207 | netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | ||
3208 | netdev->vlan_features = netdev->features & VLAN_FEAT; | ||
3209 | |||
3210 | netdev->netdev_ops = &cxgb4_netdev_ops; | ||
3211 | SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops); | ||
3212 | } | ||
3213 | |||
3214 | pci_set_drvdata(pdev, adapter); | ||
3215 | |||
3216 | if (adapter->flags & FW_OK) { | ||
3217 | err = t4_port_init(adapter, 0, 0, 0); | ||
3218 | if (err) | ||
3219 | goto out_free_dev; | ||
3220 | } | ||
3221 | |||
3222 | /* | ||
3223 | * Configure queues and allocate tables now, they can be needed as | ||
3224 | * soon as the first register_netdev completes. | ||
3225 | */ | ||
3226 | cfg_queues(adapter); | ||
3227 | |||
3228 | adapter->l2t = t4_init_l2t(); | ||
3229 | if (!adapter->l2t) { | ||
3230 | /* We tolerate a lack of L2T, giving up some functionality */ | ||
3231 | dev_warn(&pdev->dev, "could not allocate L2T, continuing\n"); | ||
3232 | adapter->params.offload = 0; | ||
3233 | } | ||
3234 | |||
3235 | if (is_offload(adapter) && tid_init(&adapter->tids) < 0) { | ||
3236 | dev_warn(&pdev->dev, "could not allocate TID table, " | ||
3237 | "continuing\n"); | ||
3238 | adapter->params.offload = 0; | ||
3239 | } | ||
3240 | |||
3241 | /* | ||
3242 | * The card is now ready to go. If any errors occur during device | ||
3243 | * registration we do not fail the whole card but rather proceed only | ||
3244 | * with the ports we manage to register successfully. However we must | ||
3245 | * register at least one net device. | ||
3246 | */ | ||
3247 | for_each_port(adapter, i) { | ||
3248 | err = register_netdev(adapter->port[i]); | ||
3249 | if (err) | ||
3250 | dev_warn(&pdev->dev, | ||
3251 | "cannot register net device %s, skipping\n", | ||
3252 | adapter->port[i]->name); | ||
3253 | else { | ||
3254 | /* | ||
3255 | * Change the name we use for messages to the name of | ||
3256 | * the first successfully registered interface. | ||
3257 | */ | ||
3258 | if (!adapter->registered_device_map) | ||
3259 | adapter->name = adapter->port[i]->name; | ||
3260 | |||
3261 | __set_bit(i, &adapter->registered_device_map); | ||
3262 | adapter->chan_map[adap2pinfo(adapter, i)->tx_chan] = i; | ||
3263 | } | ||
3264 | } | ||
3265 | if (!adapter->registered_device_map) { | ||
3266 | dev_err(&pdev->dev, "could not register any net devices\n"); | ||
3267 | goto out_free_dev; | ||
3268 | } | ||
3269 | |||
3270 | if (cxgb4_debugfs_root) { | ||
3271 | adapter->debugfs_root = debugfs_create_dir(pci_name(pdev), | ||
3272 | cxgb4_debugfs_root); | ||
3273 | setup_debugfs(adapter); | ||
3274 | } | ||
3275 | |||
3276 | /* See what interrupts we'll be using */ | ||
3277 | if (msi > 1 && enable_msix(adapter) == 0) | ||
3278 | adapter->flags |= USING_MSIX; | ||
3279 | else if (msi > 0 && pci_enable_msi(pdev) == 0) | ||
3280 | adapter->flags |= USING_MSI; | ||
3281 | |||
3282 | if (is_offload(adapter)) | ||
3283 | attach_ulds(adapter); | ||
3284 | |||
3285 | print_port_info(adapter); | ||
3286 | |||
3287 | sriov: | ||
3288 | #ifdef CONFIG_PCI_IOV | ||
3289 | if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0) | ||
3290 | if (pci_enable_sriov(pdev, num_vf[func]) == 0) | ||
3291 | dev_info(&pdev->dev, | ||
3292 | "instantiated %u virtual functions\n", | ||
3293 | num_vf[func]); | ||
3294 | #endif | ||
3295 | return 0; | ||
3296 | |||
3297 | out_free_dev: | ||
3298 | t4_free_mem(adapter->tids.tid_tab); | ||
3299 | t4_free_mem(adapter->l2t); | ||
3300 | for_each_port(adapter, i) | ||
3301 | if (adapter->port[i]) | ||
3302 | free_netdev(adapter->port[i]); | ||
3303 | if (adapter->flags & FW_OK) | ||
3304 | t4_fw_bye(adapter, 0); | ||
3305 | out_unmap_bar: | ||
3306 | iounmap(adapter->regs); | ||
3307 | out_free_adapter: | ||
3308 | kfree(adapter); | ||
3309 | out_disable_device: | ||
3310 | pci_disable_pcie_error_reporting(pdev); | ||
3311 | pci_disable_device(pdev); | ||
3312 | out_release_regions: | ||
3313 | pci_release_regions(pdev); | ||
3314 | pci_set_drvdata(pdev, NULL); | ||
3315 | return err; | ||
3316 | } | ||
3317 | |||
3318 | static void __devexit remove_one(struct pci_dev *pdev) | ||
3319 | { | ||
3320 | struct adapter *adapter = pci_get_drvdata(pdev); | ||
3321 | |||
3322 | pci_disable_sriov(pdev); | ||
3323 | |||
3324 | if (adapter) { | ||
3325 | int i; | ||
3326 | |||
3327 | if (is_offload(adapter)) | ||
3328 | detach_ulds(adapter); | ||
3329 | |||
3330 | for_each_port(adapter, i) | ||
3331 | if (test_bit(i, &adapter->registered_device_map)) | ||
3332 | unregister_netdev(adapter->port[i]); | ||
3333 | |||
3334 | if (adapter->debugfs_root) | ||
3335 | debugfs_remove_recursive(adapter->debugfs_root); | ||
3336 | |||
3337 | t4_sge_stop(adapter); | ||
3338 | t4_free_sge_resources(adapter); | ||
3339 | t4_free_mem(adapter->l2t); | ||
3340 | t4_free_mem(adapter->tids.tid_tab); | ||
3341 | disable_msi(adapter); | ||
3342 | |||
3343 | for_each_port(adapter, i) | ||
3344 | if (adapter->port[i]) | ||
3345 | free_netdev(adapter->port[i]); | ||
3346 | |||
3347 | if (adapter->flags & FW_OK) | ||
3348 | t4_fw_bye(adapter, 0); | ||
3349 | iounmap(adapter->regs); | ||
3350 | kfree(adapter); | ||
3351 | pci_disable_pcie_error_reporting(pdev); | ||
3352 | pci_disable_device(pdev); | ||
3353 | pci_release_regions(pdev); | ||
3354 | pci_set_drvdata(pdev, NULL); | ||
3355 | } else if (PCI_FUNC(pdev->devfn) > 0) | ||
3356 | pci_release_regions(pdev); | ||
3357 | } | ||
3358 | |||
3359 | static struct pci_driver cxgb4_driver = { | ||
3360 | .name = KBUILD_MODNAME, | ||
3361 | .id_table = cxgb4_pci_tbl, | ||
3362 | .probe = init_one, | ||
3363 | .remove = __devexit_p(remove_one), | ||
3364 | }; | ||
3365 | |||
3366 | static int __init cxgb4_init_module(void) | ||
3367 | { | ||
3368 | int ret; | ||
3369 | |||
3370 | /* Debugfs support is optional, just warn if this fails */ | ||
3371 | cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); | ||
3372 | if (!cxgb4_debugfs_root) | ||
3373 | pr_warning("could not create debugfs entry, continuing\n"); | ||
3374 | |||
3375 | ret = pci_register_driver(&cxgb4_driver); | ||
3376 | if (ret < 0) | ||
3377 | debugfs_remove(cxgb4_debugfs_root); | ||
3378 | return ret; | ||
3379 | } | ||
3380 | |||
3381 | static void __exit cxgb4_cleanup_module(void) | ||
3382 | { | ||
3383 | pci_unregister_driver(&cxgb4_driver); | ||
3384 | debugfs_remove(cxgb4_debugfs_root); /* NULL ok */ | ||
3385 | } | ||
3386 | |||
3387 | module_init(cxgb4_init_module); | ||
3388 | module_exit(cxgb4_cleanup_module); | ||
diff --git a/drivers/net/cxgb4/cxgb4_uld.h b/drivers/net/cxgb4/cxgb4_uld.h new file mode 100644 index 000000000000..5b98546ac92d --- /dev/null +++ b/drivers/net/cxgb4/cxgb4_uld.h | |||
@@ -0,0 +1,239 @@ | |||
1 | /* | ||
2 | * This file is part of the Chelsio T4 Ethernet driver for Linux. | ||
3 | * | ||
4 | * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved. | ||
5 | * | ||
6 | * This software is available to you under a choice of one of two | ||
7 | * licenses. You may choose to be licensed under the terms of the GNU | ||
8 | * General Public License (GPL) Version 2, available from the file | ||
9 | * COPYING in the main directory of this source tree, or the | ||
10 | * OpenIB.org BSD license below: | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or | ||
13 | * without modification, are permitted provided that the following | ||
14 | * conditions are met: | ||
15 | * | ||
16 | * - Redistributions of source code must retain the above | ||
17 | * copyright notice, this list of conditions and the following | ||
18 | * disclaimer. | ||
19 | * | ||
20 | * - Redistributions in binary form must reproduce the above | ||
21 | * copyright notice, this list of conditions and the following | ||
22 | * disclaimer in the documentation and/or other materials | ||
23 | * provided with the distribution. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
32 | * SOFTWARE. | ||
33 | */ | ||
34 | |||
35 | #ifndef __CXGB4_OFLD_H | ||
36 | #define __CXGB4_OFLD_H | ||
37 | |||
38 | #include <linux/cache.h> | ||
39 | #include <linux/spinlock.h> | ||
40 | #include <linux/skbuff.h> | ||
41 | #include <asm/atomic.h> | ||
42 | |||
43 | /* CPL message priority levels */ | ||
44 | enum { | ||
45 | CPL_PRIORITY_DATA = 0, /* data messages */ | ||
46 | CPL_PRIORITY_SETUP = 1, /* connection setup messages */ | ||
47 | CPL_PRIORITY_TEARDOWN = 0, /* connection teardown messages */ | ||
48 | CPL_PRIORITY_LISTEN = 1, /* listen start/stop messages */ | ||
49 | CPL_PRIORITY_ACK = 1, /* RX ACK messages */ | ||
50 | CPL_PRIORITY_CONTROL = 1 /* control messages */ | ||
51 | }; | ||
52 | |||
53 | #define INIT_TP_WR(w, tid) do { \ | ||
54 | (w)->wr.wr_hi = htonl(FW_WR_OP(FW_TP_WR) | \ | ||
55 | FW_WR_IMMDLEN(sizeof(*w) - sizeof(w->wr))); \ | ||
56 | (w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*w), 16)) | \ | ||
57 | FW_WR_FLOWID(tid)); \ | ||
58 | (w)->wr.wr_lo = cpu_to_be64(0); \ | ||
59 | } while (0) | ||
60 | |||
61 | #define INIT_TP_WR_CPL(w, cpl, tid) do { \ | ||
62 | INIT_TP_WR(w, tid); \ | ||
63 | OPCODE_TID(w) = htonl(MK_OPCODE_TID(cpl, tid)); \ | ||
64 | } while (0) | ||
65 | |||
66 | #define INIT_ULPTX_WR(w, wrlen, atomic, tid) do { \ | ||
67 | (w)->wr.wr_hi = htonl(FW_WR_OP(FW_ULPTX_WR) | FW_WR_ATOMIC(atomic)); \ | ||
68 | (w)->wr.wr_mid = htonl(FW_WR_LEN16(DIV_ROUND_UP(wrlen, 16)) | \ | ||
69 | FW_WR_FLOWID(tid)); \ | ||
70 | (w)->wr.wr_lo = cpu_to_be64(0); \ | ||
71 | } while (0) | ||
72 | |||
73 | /* Special asynchronous notification message */ | ||
74 | #define CXGB4_MSG_AN ((void *)1) | ||
75 | |||
76 | struct serv_entry { | ||
77 | void *data; | ||
78 | }; | ||
79 | |||
80 | union aopen_entry { | ||
81 | void *data; | ||
82 | union aopen_entry *next; | ||
83 | }; | ||
84 | |||
85 | /* | ||
86 | * Holds the size, base address, free list start, etc of the TID, server TID, | ||
87 | * and active-open TID tables. The tables themselves are allocated dynamically. | ||
88 | */ | ||
89 | struct tid_info { | ||
90 | void **tid_tab; | ||
91 | unsigned int ntids; | ||
92 | |||
93 | struct serv_entry *stid_tab; | ||
94 | unsigned long *stid_bmap; | ||
95 | unsigned int nstids; | ||
96 | unsigned int stid_base; | ||
97 | |||
98 | union aopen_entry *atid_tab; | ||
99 | unsigned int natids; | ||
100 | |||
101 | unsigned int nftids; | ||
102 | unsigned int ftid_base; | ||
103 | |||
104 | spinlock_t atid_lock ____cacheline_aligned_in_smp; | ||
105 | union aopen_entry *afree; | ||
106 | unsigned int atids_in_use; | ||
107 | |||
108 | spinlock_t stid_lock; | ||
109 | unsigned int stids_in_use; | ||
110 | |||
111 | atomic_t tids_in_use; | ||
112 | }; | ||
113 | |||
114 | static inline void *lookup_tid(const struct tid_info *t, unsigned int tid) | ||
115 | { | ||
116 | return tid < t->ntids ? t->tid_tab[tid] : NULL; | ||
117 | } | ||
118 | |||
119 | static inline void *lookup_atid(const struct tid_info *t, unsigned int atid) | ||
120 | { | ||
121 | return atid < t->natids ? t->atid_tab[atid].data : NULL; | ||
122 | } | ||
123 | |||
124 | static inline void *lookup_stid(const struct tid_info *t, unsigned int stid) | ||
125 | { | ||
126 | stid -= t->stid_base; | ||
127 | return stid < t->nstids ? t->stid_tab[stid].data : NULL; | ||
128 | } | ||
129 | |||
130 | static inline void cxgb4_insert_tid(struct tid_info *t, void *data, | ||
131 | unsigned int tid) | ||
132 | { | ||
133 | t->tid_tab[tid] = data; | ||
134 | atomic_inc(&t->tids_in_use); | ||
135 | } | ||
136 | |||
137 | int cxgb4_alloc_atid(struct tid_info *t, void *data); | ||
138 | int cxgb4_alloc_stid(struct tid_info *t, int family, void *data); | ||
139 | void cxgb4_free_atid(struct tid_info *t, unsigned int atid); | ||
140 | void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family); | ||
141 | void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid); | ||
142 | void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, | ||
143 | unsigned int tid); | ||
144 | |||
145 | struct in6_addr; | ||
146 | |||
147 | int cxgb4_create_server(const struct net_device *dev, unsigned int stid, | ||
148 | __be32 sip, __be16 sport, unsigned int queue); | ||
149 | int cxgb4_create_server6(const struct net_device *dev, unsigned int stid, | ||
150 | const struct in6_addr *sip, __be16 sport, | ||
151 | unsigned int queue); | ||
152 | |||
153 | static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue) | ||
154 | { | ||
155 | skb_set_queue_mapping(skb, (queue << 1) | prio); | ||
156 | } | ||
157 | |||
158 | enum cxgb4_uld { | ||
159 | CXGB4_ULD_RDMA, | ||
160 | CXGB4_ULD_ISCSI, | ||
161 | CXGB4_ULD_MAX | ||
162 | }; | ||
163 | |||
164 | enum cxgb4_state { | ||
165 | CXGB4_STATE_UP, | ||
166 | CXGB4_STATE_START_RECOVERY, | ||
167 | CXGB4_STATE_DOWN, | ||
168 | CXGB4_STATE_DETACH | ||
169 | }; | ||
170 | |||
171 | struct pci_dev; | ||
172 | struct l2t_data; | ||
173 | struct net_device; | ||
174 | struct pkt_gl; | ||
175 | struct tp_tcp_stats; | ||
176 | |||
177 | struct cxgb4_range { | ||
178 | unsigned int start; | ||
179 | unsigned int size; | ||
180 | }; | ||
181 | |||
182 | struct cxgb4_virt_res { /* virtualized HW resources */ | ||
183 | struct cxgb4_range ddp; | ||
184 | struct cxgb4_range iscsi; | ||
185 | struct cxgb4_range stag; | ||
186 | struct cxgb4_range rq; | ||
187 | struct cxgb4_range pbl; | ||
188 | }; | ||
189 | |||
190 | /* | ||
191 | * Block of information the LLD provides to ULDs attaching to a device. | ||
192 | */ | ||
193 | struct cxgb4_lld_info { | ||
194 | struct pci_dev *pdev; /* associated PCI device */ | ||
195 | struct l2t_data *l2t; /* L2 table */ | ||
196 | struct tid_info *tids; /* TID table */ | ||
197 | struct net_device **ports; /* device ports */ | ||
198 | const struct cxgb4_virt_res *vr; /* assorted HW resources */ | ||
199 | const unsigned short *mtus; /* MTU table */ | ||
200 | const unsigned short *rxq_ids; /* the ULD's Rx queue ids */ | ||
201 | unsigned short nrxq; /* # of Rx queues */ | ||
202 | unsigned short ntxq; /* # of Tx queues */ | ||
203 | unsigned char nchan:4; /* # of channels */ | ||
204 | unsigned char nports:4; /* # of ports */ | ||
205 | unsigned char wr_cred; /* WR 16-byte credits */ | ||
206 | unsigned char adapter_type; /* type of adapter */ | ||
207 | unsigned char fw_api_ver; /* FW API version */ | ||
208 | unsigned int fw_vers; /* FW version */ | ||
209 | unsigned int iscsi_iolen; /* iSCSI max I/O length */ | ||
210 | unsigned short udb_density; /* # of user DB/page */ | ||
211 | unsigned short ucq_density; /* # of user CQs/page */ | ||
212 | void __iomem *gts_reg; /* address of GTS register */ | ||
213 | void __iomem *db_reg; /* address of kernel doorbell */ | ||
214 | }; | ||
215 | |||
216 | struct cxgb4_uld_info { | ||
217 | const char *name; | ||
218 | void *(*add)(const struct cxgb4_lld_info *p); | ||
219 | int (*rx_handler)(void *handle, const __be64 *rsp, | ||
220 | const struct pkt_gl *gl); | ||
221 | int (*state_change)(void *handle, enum cxgb4_state new_state); | ||
222 | }; | ||
223 | |||
224 | int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p); | ||
225 | int cxgb4_unregister_uld(enum cxgb4_uld type); | ||
226 | int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb); | ||
227 | unsigned int cxgb4_port_chan(const struct net_device *dev); | ||
228 | unsigned int cxgb4_port_viid(const struct net_device *dev); | ||
229 | unsigned int cxgb4_port_idx(const struct net_device *dev); | ||
230 | struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id); | ||
231 | unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu, | ||
232 | unsigned int *idx); | ||
233 | void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4, | ||
234 | struct tp_tcp_stats *v6); | ||
235 | void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask, | ||
236 | const unsigned int *pgsz_order); | ||
237 | struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl, | ||
238 | unsigned int skb_len, unsigned int pull_len); | ||
239 | #endif /* !__CXGB4_OFLD_H */ | ||
diff --git a/drivers/net/cxgb4/l2t.c b/drivers/net/cxgb4/l2t.c new file mode 100644 index 000000000000..9f96724a133a --- /dev/null +++ b/drivers/net/cxgb4/l2t.c | |||
@@ -0,0 +1,624 @@ | |||
1 | /* | ||
2 | * This file is part of the Chelsio T4 Ethernet driver for Linux. | ||
3 | * | ||
4 | * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved. | ||
5 | * | ||
6 | * This software is available to you under a choice of one of two | ||
7 | * licenses. You may choose to be licensed under the terms of the GNU | ||
8 | * General Public License (GPL) Version 2, available from the file | ||
9 | * COPYING in the main directory of this source tree, or the | ||
10 | * OpenIB.org BSD license below: | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or | ||
13 | * without modification, are permitted provided that the following | ||
14 | * conditions are met: | ||
15 | * | ||
16 | * - Redistributions of source code must retain the above | ||
17 | * copyright notice, this list of conditions and the following | ||
18 | * disclaimer. | ||
19 | * | ||
20 | * - Redistributions in binary form must reproduce the above | ||
21 | * copyright notice, this list of conditions and the following | ||
22 | * disclaimer in the documentation and/or other materials | ||
23 | * provided with the distribution. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
32 | * SOFTWARE. | ||
33 | */ | ||
34 | |||
35 | #include <linux/skbuff.h> | ||
36 | #include <linux/netdevice.h> | ||
37 | #include <linux/if.h> | ||
38 | #include <linux/if_vlan.h> | ||
39 | #include <linux/jhash.h> | ||
40 | #include <net/neighbour.h> | ||
41 | #include "cxgb4.h" | ||
42 | #include "l2t.h" | ||
43 | #include "t4_msg.h" | ||
44 | #include "t4fw_api.h" | ||
45 | |||
46 | #define VLAN_NONE 0xfff | ||
47 | |||
48 | /* identifies sync vs async L2T_WRITE_REQs */ | ||
49 | #define F_SYNC_WR (1 << 12) | ||
50 | |||
51 | enum { | ||
52 | L2T_STATE_VALID, /* entry is up to date */ | ||
53 | L2T_STATE_STALE, /* entry may be used but needs revalidation */ | ||
54 | L2T_STATE_RESOLVING, /* entry needs address resolution */ | ||
55 | L2T_STATE_SYNC_WRITE, /* synchronous write of entry underway */ | ||
56 | |||
57 | /* when state is one of the below the entry is not hashed */ | ||
58 | L2T_STATE_SWITCHING, /* entry is being used by a switching filter */ | ||
59 | L2T_STATE_UNUSED /* entry not in use */ | ||
60 | }; | ||
61 | |||
62 | struct l2t_data { | ||
63 | rwlock_t lock; | ||
64 | atomic_t nfree; /* number of free entries */ | ||
65 | struct l2t_entry *rover; /* starting point for next allocation */ | ||
66 | struct l2t_entry l2tab[L2T_SIZE]; | ||
67 | }; | ||
68 | |||
69 | static inline unsigned int vlan_prio(const struct l2t_entry *e) | ||
70 | { | ||
71 | return e->vlan >> 13; | ||
72 | } | ||
73 | |||
74 | static inline void l2t_hold(struct l2t_data *d, struct l2t_entry *e) | ||
75 | { | ||
76 | if (atomic_add_return(1, &e->refcnt) == 1) /* 0 -> 1 transition */ | ||
77 | atomic_dec(&d->nfree); | ||
78 | } | ||
79 | |||
80 | /* | ||
81 | * To avoid having to check address families we do not allow v4 and v6 | ||
82 | * neighbors to be on the same hash chain. We keep v4 entries in the first | ||
83 | * half of available hash buckets and v6 in the second. | ||
84 | */ | ||
85 | enum { | ||
86 | L2T_SZ_HALF = L2T_SIZE / 2, | ||
87 | L2T_HASH_MASK = L2T_SZ_HALF - 1 | ||
88 | }; | ||
89 | |||
90 | static inline unsigned int arp_hash(const u32 *key, int ifindex) | ||
91 | { | ||
92 | return jhash_2words(*key, ifindex, 0) & L2T_HASH_MASK; | ||
93 | } | ||
94 | |||
95 | static inline unsigned int ipv6_hash(const u32 *key, int ifindex) | ||
96 | { | ||
97 | u32 xor = key[0] ^ key[1] ^ key[2] ^ key[3]; | ||
98 | |||
99 | return L2T_SZ_HALF + (jhash_2words(xor, ifindex, 0) & L2T_HASH_MASK); | ||
100 | } | ||
101 | |||
102 | static unsigned int addr_hash(const u32 *addr, int addr_len, int ifindex) | ||
103 | { | ||
104 | return addr_len == 4 ? arp_hash(addr, ifindex) : | ||
105 | ipv6_hash(addr, ifindex); | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Checks if an L2T entry is for the given IP/IPv6 address. It does not check | ||
110 | * whether the L2T entry and the address are of the same address family. | ||
111 | * Callers ensure an address is only checked against L2T entries of the same | ||
112 | * family, something made trivial by the separation of IP and IPv6 hash chains | ||
113 | * mentioned above. Returns 0 if there's a match, | ||
114 | */ | ||
115 | static int addreq(const struct l2t_entry *e, const u32 *addr) | ||
116 | { | ||
117 | if (e->v6) | ||
118 | return (e->addr[0] ^ addr[0]) | (e->addr[1] ^ addr[1]) | | ||
119 | (e->addr[2] ^ addr[2]) | (e->addr[3] ^ addr[3]); | ||
120 | return e->addr[0] ^ addr[0]; | ||
121 | } | ||
122 | |||
123 | static void neigh_replace(struct l2t_entry *e, struct neighbour *n) | ||
124 | { | ||
125 | neigh_hold(n); | ||
126 | if (e->neigh) | ||
127 | neigh_release(e->neigh); | ||
128 | e->neigh = n; | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * Write an L2T entry. Must be called with the entry locked. | ||
133 | * The write may be synchronous or asynchronous. | ||
134 | */ | ||
135 | static int write_l2e(struct adapter *adap, struct l2t_entry *e, int sync) | ||
136 | { | ||
137 | struct sk_buff *skb; | ||
138 | struct cpl_l2t_write_req *req; | ||
139 | |||
140 | skb = alloc_skb(sizeof(*req), GFP_ATOMIC); | ||
141 | if (!skb) | ||
142 | return -ENOMEM; | ||
143 | |||
144 | req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req)); | ||
145 | INIT_TP_WR(req, 0); | ||
146 | |||
147 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, | ||
148 | e->idx | (sync ? F_SYNC_WR : 0) | | ||
149 | TID_QID(adap->sge.fw_evtq.abs_id))); | ||
150 | req->params = htons(L2T_W_PORT(e->lport) | L2T_W_NOREPLY(!sync)); | ||
151 | req->l2t_idx = htons(e->idx); | ||
152 | req->vlan = htons(e->vlan); | ||
153 | if (e->neigh) | ||
154 | memcpy(e->dmac, e->neigh->ha, sizeof(e->dmac)); | ||
155 | memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac)); | ||
156 | |||
157 | set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0); | ||
158 | t4_ofld_send(adap, skb); | ||
159 | |||
160 | if (sync && e->state != L2T_STATE_SWITCHING) | ||
161 | e->state = L2T_STATE_SYNC_WRITE; | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Send packets waiting in an L2T entry's ARP queue. Must be called with the | ||
167 | * entry locked. | ||
168 | */ | ||
169 | static void send_pending(struct adapter *adap, struct l2t_entry *e) | ||
170 | { | ||
171 | while (e->arpq_head) { | ||
172 | struct sk_buff *skb = e->arpq_head; | ||
173 | |||
174 | e->arpq_head = skb->next; | ||
175 | skb->next = NULL; | ||
176 | t4_ofld_send(adap, skb); | ||
177 | } | ||
178 | e->arpq_tail = NULL; | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * Process a CPL_L2T_WRITE_RPL. Wake up the ARP queue if it completes a | ||
183 | * synchronous L2T_WRITE. Note that the TID in the reply is really the L2T | ||
184 | * index it refers to. | ||
185 | */ | ||
186 | void do_l2t_write_rpl(struct adapter *adap, const struct cpl_l2t_write_rpl *rpl) | ||
187 | { | ||
188 | unsigned int tid = GET_TID(rpl); | ||
189 | unsigned int idx = tid & (L2T_SIZE - 1); | ||
190 | |||
191 | if (unlikely(rpl->status != CPL_ERR_NONE)) { | ||
192 | dev_err(adap->pdev_dev, | ||
193 | "Unexpected L2T_WRITE_RPL status %u for entry %u\n", | ||
194 | rpl->status, idx); | ||
195 | return; | ||
196 | } | ||
197 | |||
198 | if (tid & F_SYNC_WR) { | ||
199 | struct l2t_entry *e = &adap->l2t->l2tab[idx]; | ||
200 | |||
201 | spin_lock(&e->lock); | ||
202 | if (e->state != L2T_STATE_SWITCHING) { | ||
203 | send_pending(adap, e); | ||
204 | e->state = (e->neigh->nud_state & NUD_STALE) ? | ||
205 | L2T_STATE_STALE : L2T_STATE_VALID; | ||
206 | } | ||
207 | spin_unlock(&e->lock); | ||
208 | } | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * Add a packet to an L2T entry's queue of packets awaiting resolution. | ||
213 | * Must be called with the entry's lock held. | ||
214 | */ | ||
215 | static inline void arpq_enqueue(struct l2t_entry *e, struct sk_buff *skb) | ||
216 | { | ||
217 | skb->next = NULL; | ||
218 | if (e->arpq_head) | ||
219 | e->arpq_tail->next = skb; | ||
220 | else | ||
221 | e->arpq_head = skb; | ||
222 | e->arpq_tail = skb; | ||
223 | } | ||
224 | |||
225 | int cxgb4_l2t_send(struct net_device *dev, struct sk_buff *skb, | ||
226 | struct l2t_entry *e) | ||
227 | { | ||
228 | struct adapter *adap = netdev2adap(dev); | ||
229 | |||
230 | again: | ||
231 | switch (e->state) { | ||
232 | case L2T_STATE_STALE: /* entry is stale, kick off revalidation */ | ||
233 | neigh_event_send(e->neigh, NULL); | ||
234 | spin_lock_bh(&e->lock); | ||
235 | if (e->state == L2T_STATE_STALE) | ||
236 | e->state = L2T_STATE_VALID; | ||
237 | spin_unlock_bh(&e->lock); | ||
238 | case L2T_STATE_VALID: /* fast-path, send the packet on */ | ||
239 | return t4_ofld_send(adap, skb); | ||
240 | case L2T_STATE_RESOLVING: | ||
241 | case L2T_STATE_SYNC_WRITE: | ||
242 | spin_lock_bh(&e->lock); | ||
243 | if (e->state != L2T_STATE_SYNC_WRITE && | ||
244 | e->state != L2T_STATE_RESOLVING) { | ||
245 | spin_unlock_bh(&e->lock); | ||
246 | goto again; | ||
247 | } | ||
248 | arpq_enqueue(e, skb); | ||
249 | spin_unlock_bh(&e->lock); | ||
250 | |||
251 | if (e->state == L2T_STATE_RESOLVING && | ||
252 | !neigh_event_send(e->neigh, NULL)) { | ||
253 | spin_lock_bh(&e->lock); | ||
254 | if (e->state == L2T_STATE_RESOLVING && e->arpq_head) | ||
255 | write_l2e(adap, e, 1); | ||
256 | spin_unlock_bh(&e->lock); | ||
257 | } | ||
258 | } | ||
259 | return 0; | ||
260 | } | ||
261 | EXPORT_SYMBOL(cxgb4_l2t_send); | ||
262 | |||
263 | /* | ||
264 | * Allocate a free L2T entry. Must be called with l2t_data.lock held. | ||
265 | */ | ||
266 | static struct l2t_entry *alloc_l2e(struct l2t_data *d) | ||
267 | { | ||
268 | struct l2t_entry *end, *e, **p; | ||
269 | |||
270 | if (!atomic_read(&d->nfree)) | ||
271 | return NULL; | ||
272 | |||
273 | /* there's definitely a free entry */ | ||
274 | for (e = d->rover, end = &d->l2tab[L2T_SIZE]; e != end; ++e) | ||
275 | if (atomic_read(&e->refcnt) == 0) | ||
276 | goto found; | ||
277 | |||
278 | for (e = d->l2tab; atomic_read(&e->refcnt); ++e) | ||
279 | ; | ||
280 | found: | ||
281 | d->rover = e + 1; | ||
282 | atomic_dec(&d->nfree); | ||
283 | |||
284 | /* | ||
285 | * The entry we found may be an inactive entry that is | ||
286 | * presently in the hash table. We need to remove it. | ||
287 | */ | ||
288 | if (e->state < L2T_STATE_SWITCHING) | ||
289 | for (p = &d->l2tab[e->hash].first; *p; p = &(*p)->next) | ||
290 | if (*p == e) { | ||
291 | *p = e->next; | ||
292 | e->next = NULL; | ||
293 | break; | ||
294 | } | ||
295 | |||
296 | e->state = L2T_STATE_UNUSED; | ||
297 | return e; | ||
298 | } | ||
299 | |||
300 | /* | ||
301 | * Called when an L2T entry has no more users. | ||
302 | */ | ||
303 | static void t4_l2e_free(struct l2t_entry *e) | ||
304 | { | ||
305 | struct l2t_data *d; | ||
306 | |||
307 | spin_lock_bh(&e->lock); | ||
308 | if (atomic_read(&e->refcnt) == 0) { /* hasn't been recycled */ | ||
309 | if (e->neigh) { | ||
310 | neigh_release(e->neigh); | ||
311 | e->neigh = NULL; | ||
312 | } | ||
313 | } | ||
314 | spin_unlock_bh(&e->lock); | ||
315 | |||
316 | d = container_of(e, struct l2t_data, l2tab[e->idx]); | ||
317 | atomic_inc(&d->nfree); | ||
318 | } | ||
319 | |||
320 | void cxgb4_l2t_release(struct l2t_entry *e) | ||
321 | { | ||
322 | if (atomic_dec_and_test(&e->refcnt)) | ||
323 | t4_l2e_free(e); | ||
324 | } | ||
325 | EXPORT_SYMBOL(cxgb4_l2t_release); | ||
326 | |||
327 | /* | ||
328 | * Update an L2T entry that was previously used for the same next hop as neigh. | ||
329 | * Must be called with softirqs disabled. | ||
330 | */ | ||
331 | static void reuse_entry(struct l2t_entry *e, struct neighbour *neigh) | ||
332 | { | ||
333 | unsigned int nud_state; | ||
334 | |||
335 | spin_lock(&e->lock); /* avoid race with t4_l2t_free */ | ||
336 | if (neigh != e->neigh) | ||
337 | neigh_replace(e, neigh); | ||
338 | nud_state = neigh->nud_state; | ||
339 | if (memcmp(e->dmac, neigh->ha, sizeof(e->dmac)) || | ||
340 | !(nud_state & NUD_VALID)) | ||
341 | e->state = L2T_STATE_RESOLVING; | ||
342 | else if (nud_state & NUD_CONNECTED) | ||
343 | e->state = L2T_STATE_VALID; | ||
344 | else | ||
345 | e->state = L2T_STATE_STALE; | ||
346 | spin_unlock(&e->lock); | ||
347 | } | ||
348 | |||
349 | struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh, | ||
350 | const struct net_device *physdev, | ||
351 | unsigned int priority) | ||
352 | { | ||
353 | u8 lport; | ||
354 | u16 vlan; | ||
355 | struct l2t_entry *e; | ||
356 | int addr_len = neigh->tbl->key_len; | ||
357 | u32 *addr = (u32 *)neigh->primary_key; | ||
358 | int ifidx = neigh->dev->ifindex; | ||
359 | int hash = addr_hash(addr, addr_len, ifidx); | ||
360 | |||
361 | if (neigh->dev->flags & IFF_LOOPBACK) | ||
362 | lport = netdev2pinfo(physdev)->tx_chan + 4; | ||
363 | else | ||
364 | lport = netdev2pinfo(physdev)->lport; | ||
365 | |||
366 | if (neigh->dev->priv_flags & IFF_802_1Q_VLAN) | ||
367 | vlan = vlan_dev_vlan_id(neigh->dev); | ||
368 | else | ||
369 | vlan = VLAN_NONE; | ||
370 | |||
371 | write_lock_bh(&d->lock); | ||
372 | for (e = d->l2tab[hash].first; e; e = e->next) | ||
373 | if (!addreq(e, addr) && e->ifindex == ifidx && | ||
374 | e->vlan == vlan && e->lport == lport) { | ||
375 | l2t_hold(d, e); | ||
376 | if (atomic_read(&e->refcnt) == 1) | ||
377 | reuse_entry(e, neigh); | ||
378 | goto done; | ||
379 | } | ||
380 | |||
381 | /* Need to allocate a new entry */ | ||
382 | e = alloc_l2e(d); | ||
383 | if (e) { | ||
384 | spin_lock(&e->lock); /* avoid race with t4_l2t_free */ | ||
385 | e->state = L2T_STATE_RESOLVING; | ||
386 | memcpy(e->addr, addr, addr_len); | ||
387 | e->ifindex = ifidx; | ||
388 | e->hash = hash; | ||
389 | e->lport = lport; | ||
390 | e->v6 = addr_len == 16; | ||
391 | atomic_set(&e->refcnt, 1); | ||
392 | neigh_replace(e, neigh); | ||
393 | e->vlan = vlan; | ||
394 | e->next = d->l2tab[hash].first; | ||
395 | d->l2tab[hash].first = e; | ||
396 | spin_unlock(&e->lock); | ||
397 | } | ||
398 | done: | ||
399 | write_unlock_bh(&d->lock); | ||
400 | return e; | ||
401 | } | ||
402 | EXPORT_SYMBOL(cxgb4_l2t_get); | ||
403 | |||
404 | /* | ||
405 | * Called when address resolution fails for an L2T entry to handle packets | ||
406 | * on the arpq head. If a packet specifies a failure handler it is invoked, | ||
407 | * otherwise the packet is sent to the device. | ||
408 | */ | ||
409 | static void handle_failed_resolution(struct adapter *adap, struct sk_buff *arpq) | ||
410 | { | ||
411 | while (arpq) { | ||
412 | struct sk_buff *skb = arpq; | ||
413 | const struct l2t_skb_cb *cb = L2T_SKB_CB(skb); | ||
414 | |||
415 | arpq = skb->next; | ||
416 | skb->next = NULL; | ||
417 | if (cb->arp_err_handler) | ||
418 | cb->arp_err_handler(cb->handle, skb); | ||
419 | else | ||
420 | t4_ofld_send(adap, skb); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | /* | ||
425 | * Called when the host's neighbor layer makes a change to some entry that is | ||
426 | * loaded into the HW L2 table. | ||
427 | */ | ||
428 | void t4_l2t_update(struct adapter *adap, struct neighbour *neigh) | ||
429 | { | ||
430 | struct l2t_entry *e; | ||
431 | struct sk_buff *arpq = NULL; | ||
432 | struct l2t_data *d = adap->l2t; | ||
433 | int addr_len = neigh->tbl->key_len; | ||
434 | u32 *addr = (u32 *) neigh->primary_key; | ||
435 | int ifidx = neigh->dev->ifindex; | ||
436 | int hash = addr_hash(addr, addr_len, ifidx); | ||
437 | |||
438 | read_lock_bh(&d->lock); | ||
439 | for (e = d->l2tab[hash].first; e; e = e->next) | ||
440 | if (!addreq(e, addr) && e->ifindex == ifidx) { | ||
441 | spin_lock(&e->lock); | ||
442 | if (atomic_read(&e->refcnt)) | ||
443 | goto found; | ||
444 | spin_unlock(&e->lock); | ||
445 | break; | ||
446 | } | ||
447 | read_unlock_bh(&d->lock); | ||
448 | return; | ||
449 | |||
450 | found: | ||
451 | read_unlock(&d->lock); | ||
452 | |||
453 | if (neigh != e->neigh) | ||
454 | neigh_replace(e, neigh); | ||
455 | |||
456 | if (e->state == L2T_STATE_RESOLVING) { | ||
457 | if (neigh->nud_state & NUD_FAILED) { | ||
458 | arpq = e->arpq_head; | ||
459 | e->arpq_head = e->arpq_tail = NULL; | ||
460 | } else if ((neigh->nud_state & (NUD_CONNECTED | NUD_STALE)) && | ||
461 | e->arpq_head) { | ||
462 | write_l2e(adap, e, 1); | ||
463 | } | ||
464 | } else { | ||
465 | e->state = neigh->nud_state & NUD_CONNECTED ? | ||
466 | L2T_STATE_VALID : L2T_STATE_STALE; | ||
467 | if (memcmp(e->dmac, neigh->ha, sizeof(e->dmac))) | ||
468 | write_l2e(adap, e, 0); | ||
469 | } | ||
470 | |||
471 | spin_unlock_bh(&e->lock); | ||
472 | |||
473 | if (arpq) | ||
474 | handle_failed_resolution(adap, arpq); | ||
475 | } | ||
476 | |||
477 | /* | ||
478 | * Allocate an L2T entry for use by a switching rule. Such entries need to be | ||
479 | * explicitly freed and while busy they are not on any hash chain, so normal | ||
480 | * address resolution updates do not see them. | ||
481 | */ | ||
482 | struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d) | ||
483 | { | ||
484 | struct l2t_entry *e; | ||
485 | |||
486 | write_lock_bh(&d->lock); | ||
487 | e = alloc_l2e(d); | ||
488 | if (e) { | ||
489 | spin_lock(&e->lock); /* avoid race with t4_l2t_free */ | ||
490 | e->state = L2T_STATE_SWITCHING; | ||
491 | atomic_set(&e->refcnt, 1); | ||
492 | spin_unlock(&e->lock); | ||
493 | } | ||
494 | write_unlock_bh(&d->lock); | ||
495 | return e; | ||
496 | } | ||
497 | |||
498 | /* | ||
499 | * Sets/updates the contents of a switching L2T entry that has been allocated | ||
500 | * with an earlier call to @t4_l2t_alloc_switching. | ||
501 | */ | ||
502 | int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan, | ||
503 | u8 port, u8 *eth_addr) | ||
504 | { | ||
505 | e->vlan = vlan; | ||
506 | e->lport = port; | ||
507 | memcpy(e->dmac, eth_addr, ETH_ALEN); | ||
508 | return write_l2e(adap, e, 0); | ||
509 | } | ||
510 | |||
511 | struct l2t_data *t4_init_l2t(void) | ||
512 | { | ||
513 | int i; | ||
514 | struct l2t_data *d; | ||
515 | |||
516 | d = t4_alloc_mem(sizeof(*d)); | ||
517 | if (!d) | ||
518 | return NULL; | ||
519 | |||
520 | d->rover = d->l2tab; | ||
521 | atomic_set(&d->nfree, L2T_SIZE); | ||
522 | rwlock_init(&d->lock); | ||
523 | |||
524 | for (i = 0; i < L2T_SIZE; ++i) { | ||
525 | d->l2tab[i].idx = i; | ||
526 | d->l2tab[i].state = L2T_STATE_UNUSED; | ||
527 | spin_lock_init(&d->l2tab[i].lock); | ||
528 | atomic_set(&d->l2tab[i].refcnt, 0); | ||
529 | } | ||
530 | return d; | ||
531 | } | ||
532 | |||
533 | #include <linux/module.h> | ||
534 | #include <linux/debugfs.h> | ||
535 | #include <linux/seq_file.h> | ||
536 | |||
537 | static inline void *l2t_get_idx(struct seq_file *seq, loff_t pos) | ||
538 | { | ||
539 | struct l2t_entry *l2tab = seq->private; | ||
540 | |||
541 | return pos >= L2T_SIZE ? NULL : &l2tab[pos]; | ||
542 | } | ||
543 | |||
544 | static void *l2t_seq_start(struct seq_file *seq, loff_t *pos) | ||
545 | { | ||
546 | return *pos ? l2t_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; | ||
547 | } | ||
548 | |||
549 | static void *l2t_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
550 | { | ||
551 | v = l2t_get_idx(seq, *pos); | ||
552 | if (v) | ||
553 | ++*pos; | ||
554 | return v; | ||
555 | } | ||
556 | |||
557 | static void l2t_seq_stop(struct seq_file *seq, void *v) | ||
558 | { | ||
559 | } | ||
560 | |||
561 | static char l2e_state(const struct l2t_entry *e) | ||
562 | { | ||
563 | switch (e->state) { | ||
564 | case L2T_STATE_VALID: return 'V'; | ||
565 | case L2T_STATE_STALE: return 'S'; | ||
566 | case L2T_STATE_SYNC_WRITE: return 'W'; | ||
567 | case L2T_STATE_RESOLVING: return e->arpq_head ? 'A' : 'R'; | ||
568 | case L2T_STATE_SWITCHING: return 'X'; | ||
569 | default: | ||
570 | return 'U'; | ||
571 | } | ||
572 | } | ||
573 | |||
574 | static int l2t_seq_show(struct seq_file *seq, void *v) | ||
575 | { | ||
576 | if (v == SEQ_START_TOKEN) | ||
577 | seq_puts(seq, " Idx IP address " | ||
578 | "Ethernet address VLAN/P LP State Users Port\n"); | ||
579 | else { | ||
580 | char ip[60]; | ||
581 | struct l2t_entry *e = v; | ||
582 | |||
583 | spin_lock_bh(&e->lock); | ||
584 | if (e->state == L2T_STATE_SWITCHING) | ||
585 | ip[0] = '\0'; | ||
586 | else | ||
587 | sprintf(ip, e->v6 ? "%pI6c" : "%pI4", e->addr); | ||
588 | seq_printf(seq, "%4u %-25s %17pM %4d %u %2u %c %5u %s\n", | ||
589 | e->idx, ip, e->dmac, | ||
590 | e->vlan & VLAN_VID_MASK, vlan_prio(e), e->lport, | ||
591 | l2e_state(e), atomic_read(&e->refcnt), | ||
592 | e->neigh ? e->neigh->dev->name : ""); | ||
593 | spin_unlock_bh(&e->lock); | ||
594 | } | ||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | static const struct seq_operations l2t_seq_ops = { | ||
599 | .start = l2t_seq_start, | ||
600 | .next = l2t_seq_next, | ||
601 | .stop = l2t_seq_stop, | ||
602 | .show = l2t_seq_show | ||
603 | }; | ||
604 | |||
605 | static int l2t_seq_open(struct inode *inode, struct file *file) | ||
606 | { | ||
607 | int rc = seq_open(file, &l2t_seq_ops); | ||
608 | |||
609 | if (!rc) { | ||
610 | struct adapter *adap = inode->i_private; | ||
611 | struct seq_file *seq = file->private_data; | ||
612 | |||
613 | seq->private = adap->l2t->l2tab; | ||
614 | } | ||
615 | return rc; | ||
616 | } | ||
617 | |||
618 | const struct file_operations t4_l2t_fops = { | ||
619 | .owner = THIS_MODULE, | ||
620 | .open = l2t_seq_open, | ||
621 | .read = seq_read, | ||
622 | .llseek = seq_lseek, | ||
623 | .release = seq_release, | ||
624 | }; | ||
diff --git a/drivers/net/cxgb4/l2t.h b/drivers/net/cxgb4/l2t.h new file mode 100644 index 000000000000..643f27ed3cf4 --- /dev/null +++ b/drivers/net/cxgb4/l2t.h | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | * This file is part of the Chelsio T4 Ethernet driver for Linux. | ||
3 | * | ||
4 | * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved. | ||
5 | * | ||
6 | * This software is available to you under a choice of one of two | ||
7 | * licenses. You may choose to be licensed under the terms of the GNU | ||
8 | * General Public License (GPL) Version 2, available from the file | ||
9 | * COPYING in the main directory of this source tree, or the | ||
10 | * OpenIB.org BSD license below: | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or | ||
13 | * without modification, are permitted provided that the following | ||
14 | * conditions are met: | ||
15 | * | ||
16 | * - Redistributions of source code must retain the above | ||
17 | * copyright notice, this list of conditions and the following | ||
18 | * disclaimer. | ||
19 | * | ||
20 | * - Redistributions in binary form must reproduce the above | ||
21 | * copyright notice, this list of conditions and the following | ||
22 | * disclaimer in the documentation and/or other materials | ||
23 | * provided with the distribution. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
32 | * SOFTWARE. | ||
33 | */ | ||
34 | |||
35 | #ifndef __CXGB4_L2T_H | ||
36 | #define __CXGB4_L2T_H | ||
37 | |||
38 | #include <linux/spinlock.h> | ||
39 | #include <linux/if_ether.h> | ||
40 | #include <asm/atomic.h> | ||
41 | |||
42 | struct adapter; | ||
43 | struct l2t_data; | ||
44 | struct neighbour; | ||
45 | struct net_device; | ||
46 | struct file_operations; | ||
47 | struct cpl_l2t_write_rpl; | ||
48 | |||
49 | /* | ||
50 | * Each L2T entry plays multiple roles. First of all, it keeps state for the | ||
51 | * corresponding entry of the HW L2 table and maintains a queue of offload | ||
52 | * packets awaiting address resolution. Second, it is a node of a hash table | ||
53 | * chain, where the nodes of the chain are linked together through their next | ||
54 | * pointer. Finally, each node is a bucket of a hash table, pointing to the | ||
55 | * first element in its chain through its first pointer. | ||
56 | */ | ||
57 | struct l2t_entry { | ||
58 | u16 state; /* entry state */ | ||
59 | u16 idx; /* entry index */ | ||
60 | u32 addr[4]; /* next hop IP or IPv6 address */ | ||
61 | int ifindex; /* neighbor's net_device's ifindex */ | ||
62 | struct neighbour *neigh; /* associated neighbour */ | ||
63 | struct l2t_entry *first; /* start of hash chain */ | ||
64 | struct l2t_entry *next; /* next l2t_entry on chain */ | ||
65 | struct sk_buff *arpq_head; /* queue of packets awaiting resolution */ | ||
66 | struct sk_buff *arpq_tail; | ||
67 | spinlock_t lock; | ||
68 | atomic_t refcnt; /* entry reference count */ | ||
69 | u16 hash; /* hash bucket the entry is on */ | ||
70 | u16 vlan; /* VLAN TCI (id: bits 0-11, prio: 13-15 */ | ||
71 | u8 v6; /* whether entry is for IPv6 */ | ||
72 | u8 lport; /* associated offload logical interface */ | ||
73 | u8 dmac[ETH_ALEN]; /* neighbour's MAC address */ | ||
74 | }; | ||
75 | |||
76 | typedef void (*arp_err_handler_t)(void *handle, struct sk_buff *skb); | ||
77 | |||
78 | /* | ||
79 | * Callback stored in an skb to handle address resolution failure. | ||
80 | */ | ||
81 | struct l2t_skb_cb { | ||
82 | void *handle; | ||
83 | arp_err_handler_t arp_err_handler; | ||
84 | }; | ||
85 | |||
86 | #define L2T_SKB_CB(skb) ((struct l2t_skb_cb *)(skb)->cb) | ||
87 | |||
88 | static inline void t4_set_arp_err_handler(struct sk_buff *skb, void *handle, | ||
89 | arp_err_handler_t handler) | ||
90 | { | ||
91 | L2T_SKB_CB(skb)->handle = handle; | ||
92 | L2T_SKB_CB(skb)->arp_err_handler = handler; | ||
93 | } | ||
94 | |||
95 | void cxgb4_l2t_release(struct l2t_entry *e); | ||
96 | int cxgb4_l2t_send(struct net_device *dev, struct sk_buff *skb, | ||
97 | struct l2t_entry *e); | ||
98 | struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh, | ||
99 | const struct net_device *physdev, | ||
100 | unsigned int priority); | ||
101 | |||
102 | void t4_l2t_update(struct adapter *adap, struct neighbour *neigh); | ||
103 | struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d); | ||
104 | int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan, | ||
105 | u8 port, u8 *eth_addr); | ||
106 | struct l2t_data *t4_init_l2t(void); | ||
107 | void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl); | ||
108 | |||
109 | extern const struct file_operations t4_l2t_fops; | ||
110 | #endif /* __CXGB4_L2T_H */ | ||
diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c new file mode 100644 index 000000000000..14adc58e71c3 --- /dev/null +++ b/drivers/net/cxgb4/sge.c | |||
@@ -0,0 +1,2431 @@ | |||
1 | /* | ||
2 | * This file is part of the Chelsio T4 Ethernet driver for Linux. | ||
3 | * | ||
4 | * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved. | ||
5 | * | ||
6 | * This software is available to you under a choice of one of two | ||
7 | * licenses. You may choose to be licensed under the terms of the GNU | ||
8 | * General Public License (GPL) Version 2, available from the file | ||
9 | * COPYING in the main directory of this source tree, or the | ||
10 | * OpenIB.org BSD license below: | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or | ||
13 | * without modification, are permitted provided that the following | ||
14 | * conditions are met: | ||
15 | * | ||
16 | * - Redistributions of source code must retain the above | ||
17 | * copyright notice, this list of conditions and the following | ||
18 | * disclaimer. | ||
19 | * | ||
20 | * - Redistributions in binary form must reproduce the above | ||
21 | * copyright notice, this list of conditions and the following | ||
22 | * disclaimer in the documentation and/or other materials | ||
23 | * provided with the distribution. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
32 | * SOFTWARE. | ||
33 | */ | ||
34 | |||
35 | #include <linux/skbuff.h> | ||
36 | #include <linux/netdevice.h> | ||
37 | #include <linux/etherdevice.h> | ||
38 | #include <linux/if_vlan.h> | ||
39 | #include <linux/ip.h> | ||
40 | #include <linux/dma-mapping.h> | ||
41 | #include <linux/jiffies.h> | ||
42 | #include <net/ipv6.h> | ||
43 | #include <net/tcp.h> | ||
44 | #include "cxgb4.h" | ||
45 | #include "t4_regs.h" | ||
46 | #include "t4_msg.h" | ||
47 | #include "t4fw_api.h" | ||
48 | |||
49 | /* | ||
50 | * Rx buffer size. We use largish buffers if possible but settle for single | ||
51 | * pages under memory shortage. | ||
52 | */ | ||
53 | #if PAGE_SHIFT >= 16 | ||
54 | # define FL_PG_ORDER 0 | ||
55 | #else | ||
56 | # define FL_PG_ORDER (16 - PAGE_SHIFT) | ||
57 | #endif | ||
58 | |||
59 | /* RX_PULL_LEN should be <= RX_COPY_THRES */ | ||
60 | #define RX_COPY_THRES 256 | ||
61 | #define RX_PULL_LEN 128 | ||
62 | |||
63 | /* | ||
64 | * Main body length for sk_buffs used for Rx Ethernet packets with fragments. | ||
65 | * Should be >= RX_PULL_LEN but possibly bigger to give pskb_may_pull some room. | ||
66 | */ | ||
67 | #define RX_PKT_SKB_LEN 512 | ||
68 | |||
69 | /* Ethernet header padding prepended to RX_PKTs */ | ||
70 | #define RX_PKT_PAD 2 | ||
71 | |||
72 | /* | ||
73 | * Max number of Tx descriptors we clean up at a time. Should be modest as | ||
74 | * freeing skbs isn't cheap and it happens while holding locks. We just need | ||
75 | * to free packets faster than they arrive, we eventually catch up and keep | ||
76 | * the amortized cost reasonable. Must be >= 2 * TXQ_STOP_THRES. | ||
77 | */ | ||
78 | #define MAX_TX_RECLAIM 16 | ||
79 | |||
80 | /* | ||
81 | * Max number of Rx buffers we replenish at a time. Again keep this modest, | ||
82 | * allocating buffers isn't cheap either. | ||
83 | */ | ||
84 | #define MAX_RX_REFILL 16U | ||
85 | |||
86 | /* | ||
87 | * Period of the Rx queue check timer. This timer is infrequent as it has | ||
88 | * something to do only when the system experiences severe memory shortage. | ||
89 | */ | ||
90 | #define RX_QCHECK_PERIOD (HZ / 2) | ||
91 | |||
92 | /* | ||
93 | * Period of the Tx queue check timer. | ||
94 | */ | ||
95 | #define TX_QCHECK_PERIOD (HZ / 2) | ||
96 | |||
97 | /* | ||
98 | * Max number of Tx descriptors to be reclaimed by the Tx timer. | ||
99 | */ | ||
100 | #define MAX_TIMER_TX_RECLAIM 100 | ||
101 | |||
102 | /* | ||
103 | * Timer index used when backing off due to memory shortage. | ||
104 | */ | ||
105 | #define NOMEM_TMR_IDX (SGE_NTIMERS - 1) | ||
106 | |||
107 | /* | ||
108 | * An FL with <= FL_STARVE_THRES buffers is starving and a periodic timer will | ||
109 | * attempt to refill it. | ||
110 | */ | ||
111 | #define FL_STARVE_THRES 4 | ||
112 | |||
113 | /* | ||
114 | * Suspend an Ethernet Tx queue with fewer available descriptors than this. | ||
115 | * This is the same as calc_tx_descs() for a TSO packet with | ||
116 | * nr_frags == MAX_SKB_FRAGS. | ||
117 | */ | ||
118 | #define ETHTXQ_STOP_THRES \ | ||
119 | (1 + DIV_ROUND_UP((3 * MAX_SKB_FRAGS) / 2 + (MAX_SKB_FRAGS & 1), 8)) | ||
120 | |||
121 | /* | ||
122 | * Suspension threshold for non-Ethernet Tx queues. We require enough room | ||
123 | * for a full sized WR. | ||
124 | */ | ||
125 | #define TXQ_STOP_THRES (SGE_MAX_WR_LEN / sizeof(struct tx_desc)) | ||
126 | |||
127 | /* | ||
128 | * Max Tx descriptor space we allow for an Ethernet packet to be inlined | ||
129 | * into a WR. | ||
130 | */ | ||
131 | #define MAX_IMM_TX_PKT_LEN 128 | ||
132 | |||
133 | /* | ||
134 | * Max size of a WR sent through a control Tx queue. | ||
135 | */ | ||
136 | #define MAX_CTRL_WR_LEN SGE_MAX_WR_LEN | ||
137 | |||
138 | enum { | ||
139 | /* packet alignment in FL buffers */ | ||
140 | FL_ALIGN = L1_CACHE_BYTES < 32 ? 32 : L1_CACHE_BYTES, | ||
141 | /* egress status entry size */ | ||
142 | STAT_LEN = L1_CACHE_BYTES > 64 ? 128 : 64 | ||
143 | }; | ||
144 | |||
145 | struct tx_sw_desc { /* SW state per Tx descriptor */ | ||
146 | struct sk_buff *skb; | ||
147 | struct ulptx_sgl *sgl; | ||
148 | }; | ||
149 | |||
150 | struct rx_sw_desc { /* SW state per Rx descriptor */ | ||
151 | struct page *page; | ||
152 | dma_addr_t dma_addr; | ||
153 | }; | ||
154 | |||
155 | /* | ||
156 | * The low bits of rx_sw_desc.dma_addr have special meaning. | ||
157 | */ | ||
158 | enum { | ||
159 | RX_LARGE_BUF = 1 << 0, /* buffer is larger than PAGE_SIZE */ | ||
160 | RX_UNMAPPED_BUF = 1 << 1, /* buffer is not mapped */ | ||
161 | }; | ||
162 | |||
163 | static inline dma_addr_t get_buf_addr(const struct rx_sw_desc *d) | ||
164 | { | ||
165 | return d->dma_addr & ~(dma_addr_t)(RX_LARGE_BUF | RX_UNMAPPED_BUF); | ||
166 | } | ||
167 | |||
168 | static inline bool is_buf_mapped(const struct rx_sw_desc *d) | ||
169 | { | ||
170 | return !(d->dma_addr & RX_UNMAPPED_BUF); | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * txq_avail - return the number of available slots in a Tx queue | ||
175 | * @q: the Tx queue | ||
176 | * | ||
177 | * Returns the number of descriptors in a Tx queue available to write new | ||
178 | * packets. | ||
179 | */ | ||
180 | static inline unsigned int txq_avail(const struct sge_txq *q) | ||
181 | { | ||
182 | return q->size - 1 - q->in_use; | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * fl_cap - return the capacity of a free-buffer list | ||
187 | * @fl: the FL | ||
188 | * | ||
189 | * Returns the capacity of a free-buffer list. The capacity is less than | ||
190 | * the size because one descriptor needs to be left unpopulated, otherwise | ||
191 | * HW will think the FL is empty. | ||
192 | */ | ||
193 | static inline unsigned int fl_cap(const struct sge_fl *fl) | ||
194 | { | ||
195 | return fl->size - 8; /* 1 descriptor = 8 buffers */ | ||
196 | } | ||
197 | |||
198 | static inline bool fl_starving(const struct sge_fl *fl) | ||
199 | { | ||
200 | return fl->avail - fl->pend_cred <= FL_STARVE_THRES; | ||
201 | } | ||
202 | |||
203 | static int map_skb(struct device *dev, const struct sk_buff *skb, | ||
204 | dma_addr_t *addr) | ||
205 | { | ||
206 | const skb_frag_t *fp, *end; | ||
207 | const struct skb_shared_info *si; | ||
208 | |||
209 | *addr = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); | ||
210 | if (dma_mapping_error(dev, *addr)) | ||
211 | goto out_err; | ||
212 | |||
213 | si = skb_shinfo(skb); | ||
214 | end = &si->frags[si->nr_frags]; | ||
215 | |||
216 | for (fp = si->frags; fp < end; fp++) { | ||
217 | *++addr = dma_map_page(dev, fp->page, fp->page_offset, fp->size, | ||
218 | DMA_TO_DEVICE); | ||
219 | if (dma_mapping_error(dev, *addr)) | ||
220 | goto unwind; | ||
221 | } | ||
222 | return 0; | ||
223 | |||
224 | unwind: | ||
225 | while (fp-- > si->frags) | ||
226 | dma_unmap_page(dev, *--addr, fp->size, DMA_TO_DEVICE); | ||
227 | |||
228 | dma_unmap_single(dev, addr[-1], skb_headlen(skb), DMA_TO_DEVICE); | ||
229 | out_err: | ||
230 | return -ENOMEM; | ||
231 | } | ||
232 | |||
233 | #ifdef CONFIG_NEED_DMA_MAP_STATE | ||
234 | static void unmap_skb(struct device *dev, const struct sk_buff *skb, | ||
235 | const dma_addr_t *addr) | ||
236 | { | ||
237 | const skb_frag_t *fp, *end; | ||
238 | const struct skb_shared_info *si; | ||
239 | |||
240 | dma_unmap_single(dev, *addr++, skb_headlen(skb), DMA_TO_DEVICE); | ||
241 | |||
242 | si = skb_shinfo(skb); | ||
243 | end = &si->frags[si->nr_frags]; | ||
244 | for (fp = si->frags; fp < end; fp++) | ||
245 | dma_unmap_page(dev, *addr++, fp->size, DMA_TO_DEVICE); | ||
246 | } | ||
247 | |||
248 | /** | ||
249 | * deferred_unmap_destructor - unmap a packet when it is freed | ||
250 | * @skb: the packet | ||
251 | * | ||
252 | * This is the packet destructor used for Tx packets that need to remain | ||
253 | * mapped until they are freed rather than until their Tx descriptors are | ||
254 | * freed. | ||
255 | */ | ||
256 | static void deferred_unmap_destructor(struct sk_buff *skb) | ||
257 | { | ||
258 | unmap_skb(skb->dev->dev.parent, skb, (dma_addr_t *)skb->head); | ||
259 | } | ||
260 | #endif | ||
261 | |||
262 | static void unmap_sgl(struct device *dev, const struct sk_buff *skb, | ||
263 | const struct ulptx_sgl *sgl, const struct sge_txq *q) | ||
264 | { | ||
265 | const struct ulptx_sge_pair *p; | ||
266 | unsigned int nfrags = skb_shinfo(skb)->nr_frags; | ||
267 | |||
268 | if (likely(skb_headlen(skb))) | ||
269 | dma_unmap_single(dev, be64_to_cpu(sgl->addr0), ntohl(sgl->len0), | ||
270 | DMA_TO_DEVICE); | ||
271 | else { | ||
272 | dma_unmap_page(dev, be64_to_cpu(sgl->addr0), ntohl(sgl->len0), | ||
273 | DMA_TO_DEVICE); | ||
274 | nfrags--; | ||
275 | } | ||
276 | |||
277 | /* | ||
278 | * the complexity below is because of the possibility of a wrap-around | ||
279 | * in the middle of an SGL | ||
280 | */ | ||
281 | for (p = sgl->sge; nfrags >= 2; nfrags -= 2) { | ||
282 | if (likely((u8 *)(p + 1) <= (u8 *)q->stat)) { | ||
283 | unmap: dma_unmap_page(dev, be64_to_cpu(p->addr[0]), | ||
284 | ntohl(p->len[0]), DMA_TO_DEVICE); | ||
285 | dma_unmap_page(dev, be64_to_cpu(p->addr[1]), | ||
286 | ntohl(p->len[1]), DMA_TO_DEVICE); | ||
287 | p++; | ||
288 | } else if ((u8 *)p == (u8 *)q->stat) { | ||
289 | p = (const struct ulptx_sge_pair *)q->desc; | ||
290 | goto unmap; | ||
291 | } else if ((u8 *)p + 8 == (u8 *)q->stat) { | ||
292 | const __be64 *addr = (const __be64 *)q->desc; | ||
293 | |||
294 | dma_unmap_page(dev, be64_to_cpu(addr[0]), | ||
295 | ntohl(p->len[0]), DMA_TO_DEVICE); | ||
296 | dma_unmap_page(dev, be64_to_cpu(addr[1]), | ||
297 | ntohl(p->len[1]), DMA_TO_DEVICE); | ||
298 | p = (const struct ulptx_sge_pair *)&addr[2]; | ||
299 | } else { | ||
300 | const __be64 *addr = (const __be64 *)q->desc; | ||
301 | |||
302 | dma_unmap_page(dev, be64_to_cpu(p->addr[0]), | ||
303 | ntohl(p->len[0]), DMA_TO_DEVICE); | ||
304 | dma_unmap_page(dev, be64_to_cpu(addr[0]), | ||
305 | ntohl(p->len[1]), DMA_TO_DEVICE); | ||
306 | p = (const struct ulptx_sge_pair *)&addr[1]; | ||
307 | } | ||
308 | } | ||
309 | if (nfrags) { | ||
310 | __be64 addr; | ||
311 | |||
312 | if ((u8 *)p == (u8 *)q->stat) | ||
313 | p = (const struct ulptx_sge_pair *)q->desc; | ||
314 | addr = (u8 *)p + 16 <= (u8 *)q->stat ? p->addr[0] : | ||
315 | *(const __be64 *)q->desc; | ||
316 | dma_unmap_page(dev, be64_to_cpu(addr), ntohl(p->len[0]), | ||
317 | DMA_TO_DEVICE); | ||
318 | } | ||
319 | } | ||
320 | |||
321 | /** | ||
322 | * free_tx_desc - reclaims Tx descriptors and their buffers | ||
323 | * @adapter: the adapter | ||
324 | * @q: the Tx queue to reclaim descriptors from | ||
325 | * @n: the number of descriptors to reclaim | ||
326 | * @unmap: whether the buffers should be unmapped for DMA | ||
327 | * | ||
328 | * Reclaims Tx descriptors from an SGE Tx queue and frees the associated | ||
329 | * Tx buffers. Called with the Tx queue lock held. | ||
330 | */ | ||
331 | static void free_tx_desc(struct adapter *adap, struct sge_txq *q, | ||
332 | unsigned int n, bool unmap) | ||
333 | { | ||
334 | struct tx_sw_desc *d; | ||
335 | unsigned int cidx = q->cidx; | ||
336 | struct device *dev = adap->pdev_dev; | ||
337 | |||
338 | d = &q->sdesc[cidx]; | ||
339 | while (n--) { | ||
340 | if (d->skb) { /* an SGL is present */ | ||
341 | if (unmap) | ||
342 | unmap_sgl(dev, d->skb, d->sgl, q); | ||
343 | kfree_skb(d->skb); | ||
344 | d->skb = NULL; | ||
345 | } | ||
346 | ++d; | ||
347 | if (++cidx == q->size) { | ||
348 | cidx = 0; | ||
349 | d = q->sdesc; | ||
350 | } | ||
351 | } | ||
352 | q->cidx = cidx; | ||
353 | } | ||
354 | |||
355 | /* | ||
356 | * Return the number of reclaimable descriptors in a Tx queue. | ||
357 | */ | ||
358 | static inline int reclaimable(const struct sge_txq *q) | ||
359 | { | ||
360 | int hw_cidx = ntohs(q->stat->cidx); | ||
361 | hw_cidx -= q->cidx; | ||
362 | return hw_cidx < 0 ? hw_cidx + q->size : hw_cidx; | ||
363 | } | ||
364 | |||
365 | /** | ||
366 | * reclaim_completed_tx - reclaims completed Tx descriptors | ||
367 | * @adap: the adapter | ||
368 | * @q: the Tx queue to reclaim completed descriptors from | ||
369 | * @unmap: whether the buffers should be unmapped for DMA | ||
370 | * | ||
371 | * Reclaims Tx descriptors that the SGE has indicated it has processed, | ||
372 | * and frees the associated buffers if possible. Called with the Tx | ||
373 | * queue locked. | ||
374 | */ | ||
375 | static inline void reclaim_completed_tx(struct adapter *adap, struct sge_txq *q, | ||
376 | bool unmap) | ||
377 | { | ||
378 | int avail = reclaimable(q); | ||
379 | |||
380 | if (avail) { | ||
381 | /* | ||
382 | * Limit the amount of clean up work we do at a time to keep | ||
383 | * the Tx lock hold time O(1). | ||
384 | */ | ||
385 | if (avail > MAX_TX_RECLAIM) | ||
386 | avail = MAX_TX_RECLAIM; | ||
387 | |||
388 | free_tx_desc(adap, q, avail, unmap); | ||
389 | q->in_use -= avail; | ||
390 | } | ||
391 | } | ||
392 | |||
393 | static inline int get_buf_size(const struct rx_sw_desc *d) | ||
394 | { | ||
395 | #if FL_PG_ORDER > 0 | ||
396 | return (d->dma_addr & RX_LARGE_BUF) ? (PAGE_SIZE << FL_PG_ORDER) : | ||
397 | PAGE_SIZE; | ||
398 | #else | ||
399 | return PAGE_SIZE; | ||
400 | #endif | ||
401 | } | ||
402 | |||
403 | /** | ||
404 | * free_rx_bufs - free the Rx buffers on an SGE free list | ||
405 | * @adap: the adapter | ||
406 | * @q: the SGE free list to free buffers from | ||
407 | * @n: how many buffers to free | ||
408 | * | ||
409 | * Release the next @n buffers on an SGE free-buffer Rx queue. The | ||
410 | * buffers must be made inaccessible to HW before calling this function. | ||
411 | */ | ||
412 | static void free_rx_bufs(struct adapter *adap, struct sge_fl *q, int n) | ||
413 | { | ||
414 | while (n--) { | ||
415 | struct rx_sw_desc *d = &q->sdesc[q->cidx]; | ||
416 | |||
417 | if (is_buf_mapped(d)) | ||
418 | dma_unmap_page(adap->pdev_dev, get_buf_addr(d), | ||
419 | get_buf_size(d), PCI_DMA_FROMDEVICE); | ||
420 | put_page(d->page); | ||
421 | d->page = NULL; | ||
422 | if (++q->cidx == q->size) | ||
423 | q->cidx = 0; | ||
424 | q->avail--; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | /** | ||
429 | * unmap_rx_buf - unmap the current Rx buffer on an SGE free list | ||
430 | * @adap: the adapter | ||
431 | * @q: the SGE free list | ||
432 | * | ||
433 | * Unmap the current buffer on an SGE free-buffer Rx queue. The | ||
434 | * buffer must be made inaccessible to HW before calling this function. | ||
435 | * | ||
436 | * This is similar to @free_rx_bufs above but does not free the buffer. | ||
437 | * Do note that the FL still loses any further access to the buffer. | ||
438 | */ | ||
439 | static void unmap_rx_buf(struct adapter *adap, struct sge_fl *q) | ||
440 | { | ||
441 | struct rx_sw_desc *d = &q->sdesc[q->cidx]; | ||
442 | |||
443 | if (is_buf_mapped(d)) | ||
444 | dma_unmap_page(adap->pdev_dev, get_buf_addr(d), | ||
445 | get_buf_size(d), PCI_DMA_FROMDEVICE); | ||
446 | d->page = NULL; | ||
447 | if (++q->cidx == q->size) | ||
448 | q->cidx = 0; | ||
449 | q->avail--; | ||
450 | } | ||
451 | |||
452 | static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q) | ||
453 | { | ||
454 | if (q->pend_cred >= 8) { | ||
455 | wmb(); | ||
456 | t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), DBPRIO | | ||
457 | QID(q->cntxt_id) | PIDX(q->pend_cred / 8)); | ||
458 | q->pend_cred &= 7; | ||
459 | } | ||
460 | } | ||
461 | |||
462 | static inline void set_rx_sw_desc(struct rx_sw_desc *sd, struct page *pg, | ||
463 | dma_addr_t mapping) | ||
464 | { | ||
465 | sd->page = pg; | ||
466 | sd->dma_addr = mapping; /* includes size low bits */ | ||
467 | } | ||
468 | |||
469 | /** | ||
470 | * refill_fl - refill an SGE Rx buffer ring | ||
471 | * @adap: the adapter | ||
472 | * @q: the ring to refill | ||
473 | * @n: the number of new buffers to allocate | ||
474 | * @gfp: the gfp flags for the allocations | ||
475 | * | ||
476 | * (Re)populate an SGE free-buffer queue with up to @n new packet buffers, | ||
477 | * allocated with the supplied gfp flags. The caller must assure that | ||
478 | * @n does not exceed the queue's capacity. If afterwards the queue is | ||
479 | * found critically low mark it as starving in the bitmap of starving FLs. | ||
480 | * | ||
481 | * Returns the number of buffers allocated. | ||
482 | */ | ||
483 | static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n, | ||
484 | gfp_t gfp) | ||
485 | { | ||
486 | struct page *pg; | ||
487 | dma_addr_t mapping; | ||
488 | unsigned int cred = q->avail; | ||
489 | __be64 *d = &q->desc[q->pidx]; | ||
490 | struct rx_sw_desc *sd = &q->sdesc[q->pidx]; | ||
491 | |||
492 | gfp |= __GFP_NOWARN; /* failures are expected */ | ||
493 | |||
494 | #if FL_PG_ORDER > 0 | ||
495 | /* | ||
496 | * Prefer large buffers | ||
497 | */ | ||
498 | while (n) { | ||
499 | pg = alloc_pages(gfp | __GFP_COMP, FL_PG_ORDER); | ||
500 | if (unlikely(!pg)) { | ||
501 | q->large_alloc_failed++; | ||
502 | break; /* fall back to single pages */ | ||
503 | } | ||
504 | |||
505 | mapping = dma_map_page(adap->pdev_dev, pg, 0, | ||
506 | PAGE_SIZE << FL_PG_ORDER, | ||
507 | PCI_DMA_FROMDEVICE); | ||
508 | if (unlikely(dma_mapping_error(adap->pdev_dev, mapping))) { | ||
509 | __free_pages(pg, FL_PG_ORDER); | ||
510 | goto out; /* do not try small pages for this error */ | ||
511 | } | ||
512 | mapping |= RX_LARGE_BUF; | ||
513 | *d++ = cpu_to_be64(mapping); | ||
514 | |||
515 | set_rx_sw_desc(sd, pg, mapping); | ||
516 | sd++; | ||
517 | |||
518 | q->avail++; | ||
519 | if (++q->pidx == q->size) { | ||
520 | q->pidx = 0; | ||
521 | sd = q->sdesc; | ||
522 | d = q->desc; | ||
523 | } | ||
524 | n--; | ||
525 | } | ||
526 | #endif | ||
527 | |||
528 | while (n--) { | ||
529 | pg = __netdev_alloc_page(adap->port[0], gfp); | ||
530 | if (unlikely(!pg)) { | ||
531 | q->alloc_failed++; | ||
532 | break; | ||
533 | } | ||
534 | |||
535 | mapping = dma_map_page(adap->pdev_dev, pg, 0, PAGE_SIZE, | ||
536 | PCI_DMA_FROMDEVICE); | ||
537 | if (unlikely(dma_mapping_error(adap->pdev_dev, mapping))) { | ||
538 | netdev_free_page(adap->port[0], pg); | ||
539 | goto out; | ||
540 | } | ||
541 | *d++ = cpu_to_be64(mapping); | ||
542 | |||
543 | set_rx_sw_desc(sd, pg, mapping); | ||
544 | sd++; | ||
545 | |||
546 | q->avail++; | ||
547 | if (++q->pidx == q->size) { | ||
548 | q->pidx = 0; | ||
549 | sd = q->sdesc; | ||
550 | d = q->desc; | ||
551 | } | ||
552 | } | ||
553 | |||
554 | out: cred = q->avail - cred; | ||
555 | q->pend_cred += cred; | ||
556 | ring_fl_db(adap, q); | ||
557 | |||
558 | if (unlikely(fl_starving(q))) { | ||
559 | smp_wmb(); | ||
560 | set_bit(q->cntxt_id, adap->sge.starving_fl); | ||
561 | } | ||
562 | |||
563 | return cred; | ||
564 | } | ||
565 | |||
566 | static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl) | ||
567 | { | ||
568 | refill_fl(adap, fl, min(MAX_RX_REFILL, fl_cap(fl) - fl->avail), | ||
569 | GFP_ATOMIC); | ||
570 | } | ||
571 | |||
572 | /** | ||
573 | * alloc_ring - allocate resources for an SGE descriptor ring | ||
574 | * @dev: the PCI device's core device | ||
575 | * @nelem: the number of descriptors | ||
576 | * @elem_size: the size of each descriptor | ||
577 | * @sw_size: the size of the SW state associated with each ring element | ||
578 | * @phys: the physical address of the allocated ring | ||
579 | * @metadata: address of the array holding the SW state for the ring | ||
580 | * @stat_size: extra space in HW ring for status information | ||
581 | * | ||
582 | * Allocates resources for an SGE descriptor ring, such as Tx queues, | ||
583 | * free buffer lists, or response queues. Each SGE ring requires | ||
584 | * space for its HW descriptors plus, optionally, space for the SW state | ||
585 | * associated with each HW entry (the metadata). The function returns | ||
586 | * three values: the virtual address for the HW ring (the return value | ||
587 | * of the function), the bus address of the HW ring, and the address | ||
588 | * of the SW ring. | ||
589 | */ | ||
590 | static void *alloc_ring(struct device *dev, size_t nelem, size_t elem_size, | ||
591 | size_t sw_size, dma_addr_t *phys, void *metadata, | ||
592 | size_t stat_size) | ||
593 | { | ||
594 | size_t len = nelem * elem_size + stat_size; | ||
595 | void *s = NULL; | ||
596 | void *p = dma_alloc_coherent(dev, len, phys, GFP_KERNEL); | ||
597 | |||
598 | if (!p) | ||
599 | return NULL; | ||
600 | if (sw_size) { | ||
601 | s = kcalloc(nelem, sw_size, GFP_KERNEL); | ||
602 | |||
603 | if (!s) { | ||
604 | dma_free_coherent(dev, len, p, *phys); | ||
605 | return NULL; | ||
606 | } | ||
607 | } | ||
608 | if (metadata) | ||
609 | *(void **)metadata = s; | ||
610 | memset(p, 0, len); | ||
611 | return p; | ||
612 | } | ||
613 | |||
614 | /** | ||
615 | * sgl_len - calculates the size of an SGL of the given capacity | ||
616 | * @n: the number of SGL entries | ||
617 | * | ||
618 | * Calculates the number of flits needed for a scatter/gather list that | ||
619 | * can hold the given number of entries. | ||
620 | */ | ||
621 | static inline unsigned int sgl_len(unsigned int n) | ||
622 | { | ||
623 | n--; | ||
624 | return (3 * n) / 2 + (n & 1) + 2; | ||
625 | } | ||
626 | |||
627 | /** | ||
628 | * flits_to_desc - returns the num of Tx descriptors for the given flits | ||
629 | * @n: the number of flits | ||
630 | * | ||
631 | * Returns the number of Tx descriptors needed for the supplied number | ||
632 | * of flits. | ||
633 | */ | ||
634 | static inline unsigned int flits_to_desc(unsigned int n) | ||
635 | { | ||
636 | BUG_ON(n > SGE_MAX_WR_LEN / 8); | ||
637 | return DIV_ROUND_UP(n, 8); | ||
638 | } | ||
639 | |||
640 | /** | ||
641 | * is_eth_imm - can an Ethernet packet be sent as immediate data? | ||
642 | * @skb: the packet | ||
643 | * | ||
644 | * Returns whether an Ethernet packet is small enough to fit as | ||
645 | * immediate data. | ||
646 | */ | ||
647 | static inline int is_eth_imm(const struct sk_buff *skb) | ||
648 | { | ||
649 | return skb->len <= MAX_IMM_TX_PKT_LEN - sizeof(struct cpl_tx_pkt); | ||
650 | } | ||
651 | |||
652 | /** | ||
653 | * calc_tx_flits - calculate the number of flits for a packet Tx WR | ||
654 | * @skb: the packet | ||
655 | * | ||
656 | * Returns the number of flits needed for a Tx WR for the given Ethernet | ||
657 | * packet, including the needed WR and CPL headers. | ||
658 | */ | ||
659 | static inline unsigned int calc_tx_flits(const struct sk_buff *skb) | ||
660 | { | ||
661 | unsigned int flits; | ||
662 | |||
663 | if (is_eth_imm(skb)) | ||
664 | return DIV_ROUND_UP(skb->len + sizeof(struct cpl_tx_pkt), 8); | ||
665 | |||
666 | flits = sgl_len(skb_shinfo(skb)->nr_frags + 1) + 4; | ||
667 | if (skb_shinfo(skb)->gso_size) | ||
668 | flits += 2; | ||
669 | return flits; | ||
670 | } | ||
671 | |||
672 | /** | ||
673 | * calc_tx_descs - calculate the number of Tx descriptors for a packet | ||
674 | * @skb: the packet | ||
675 | * | ||
676 | * Returns the number of Tx descriptors needed for the given Ethernet | ||
677 | * packet, including the needed WR and CPL headers. | ||
678 | */ | ||
679 | static inline unsigned int calc_tx_descs(const struct sk_buff *skb) | ||
680 | { | ||
681 | return flits_to_desc(calc_tx_flits(skb)); | ||
682 | } | ||
683 | |||
684 | /** | ||
685 | * write_sgl - populate a scatter/gather list for a packet | ||
686 | * @skb: the packet | ||
687 | * @q: the Tx queue we are writing into | ||
688 | * @sgl: starting location for writing the SGL | ||
689 | * @end: points right after the end of the SGL | ||
690 | * @start: start offset into skb main-body data to include in the SGL | ||
691 | * @addr: the list of bus addresses for the SGL elements | ||
692 | * | ||
693 | * Generates a gather list for the buffers that make up a packet. | ||
694 | * The caller must provide adequate space for the SGL that will be written. | ||
695 | * The SGL includes all of the packet's page fragments and the data in its | ||
696 | * main body except for the first @start bytes. @sgl must be 16-byte | ||
697 | * aligned and within a Tx descriptor with available space. @end points | ||
698 | * right after the end of the SGL but does not account for any potential | ||
699 | * wrap around, i.e., @end > @sgl. | ||
700 | */ | ||
701 | static void write_sgl(const struct sk_buff *skb, struct sge_txq *q, | ||
702 | struct ulptx_sgl *sgl, u64 *end, unsigned int start, | ||
703 | const dma_addr_t *addr) | ||
704 | { | ||
705 | unsigned int i, len; | ||
706 | struct ulptx_sge_pair *to; | ||
707 | const struct skb_shared_info *si = skb_shinfo(skb); | ||
708 | unsigned int nfrags = si->nr_frags; | ||
709 | struct ulptx_sge_pair buf[MAX_SKB_FRAGS / 2 + 1]; | ||
710 | |||
711 | len = skb_headlen(skb) - start; | ||
712 | if (likely(len)) { | ||
713 | sgl->len0 = htonl(len); | ||
714 | sgl->addr0 = cpu_to_be64(addr[0] + start); | ||
715 | nfrags++; | ||
716 | } else { | ||
717 | sgl->len0 = htonl(si->frags[0].size); | ||
718 | sgl->addr0 = cpu_to_be64(addr[1]); | ||
719 | } | ||
720 | |||
721 | sgl->cmd_nsge = htonl(ULPTX_CMD(ULP_TX_SC_DSGL) | ULPTX_NSGE(nfrags)); | ||
722 | if (likely(--nfrags == 0)) | ||
723 | return; | ||
724 | /* | ||
725 | * Most of the complexity below deals with the possibility we hit the | ||
726 | * end of the queue in the middle of writing the SGL. For this case | ||
727 | * only we create the SGL in a temporary buffer and then copy it. | ||
728 | */ | ||
729 | to = (u8 *)end > (u8 *)q->stat ? buf : sgl->sge; | ||
730 | |||
731 | for (i = (nfrags != si->nr_frags); nfrags >= 2; nfrags -= 2, to++) { | ||
732 | to->len[0] = cpu_to_be32(si->frags[i].size); | ||
733 | to->len[1] = cpu_to_be32(si->frags[++i].size); | ||
734 | to->addr[0] = cpu_to_be64(addr[i]); | ||
735 | to->addr[1] = cpu_to_be64(addr[++i]); | ||
736 | } | ||
737 | if (nfrags) { | ||
738 | to->len[0] = cpu_to_be32(si->frags[i].size); | ||
739 | to->len[1] = cpu_to_be32(0); | ||
740 | to->addr[0] = cpu_to_be64(addr[i + 1]); | ||
741 | } | ||
742 | if (unlikely((u8 *)end > (u8 *)q->stat)) { | ||
743 | unsigned int part0 = (u8 *)q->stat - (u8 *)sgl->sge, part1; | ||
744 | |||
745 | if (likely(part0)) | ||
746 | memcpy(sgl->sge, buf, part0); | ||
747 | part1 = (u8 *)end - (u8 *)q->stat; | ||
748 | memcpy(q->desc, (u8 *)buf + part0, part1); | ||
749 | end = (void *)q->desc + part1; | ||
750 | } | ||
751 | if ((uintptr_t)end & 8) /* 0-pad to multiple of 16 */ | ||
752 | *(u64 *)end = 0; | ||
753 | } | ||
754 | |||
755 | /** | ||
756 | * ring_tx_db - check and potentially ring a Tx queue's doorbell | ||
757 | * @adap: the adapter | ||
758 | * @q: the Tx queue | ||
759 | * @n: number of new descriptors to give to HW | ||
760 | * | ||
761 | * Ring the doorbel for a Tx queue. | ||
762 | */ | ||
763 | static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n) | ||
764 | { | ||
765 | wmb(); /* write descriptors before telling HW */ | ||
766 | t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), | ||
767 | QID(q->cntxt_id) | PIDX(n)); | ||
768 | } | ||
769 | |||
770 | /** | ||
771 | * inline_tx_skb - inline a packet's data into Tx descriptors | ||
772 | * @skb: the packet | ||
773 | * @q: the Tx queue where the packet will be inlined | ||
774 | * @pos: starting position in the Tx queue where to inline the packet | ||
775 | * | ||
776 | * Inline a packet's contents directly into Tx descriptors, starting at | ||
777 | * the given position within the Tx DMA ring. | ||
778 | * Most of the complexity of this operation is dealing with wrap arounds | ||
779 | * in the middle of the packet we want to inline. | ||
780 | */ | ||
781 | static void inline_tx_skb(const struct sk_buff *skb, const struct sge_txq *q, | ||
782 | void *pos) | ||
783 | { | ||
784 | u64 *p; | ||
785 | int left = (void *)q->stat - pos; | ||
786 | |||
787 | if (likely(skb->len <= left)) { | ||
788 | if (likely(!skb->data_len)) | ||
789 | skb_copy_from_linear_data(skb, pos, skb->len); | ||
790 | else | ||
791 | skb_copy_bits(skb, 0, pos, skb->len); | ||
792 | pos += skb->len; | ||
793 | } else { | ||
794 | skb_copy_bits(skb, 0, pos, left); | ||
795 | skb_copy_bits(skb, left, q->desc, skb->len - left); | ||
796 | pos = (void *)q->desc + (skb->len - left); | ||
797 | } | ||
798 | |||
799 | /* 0-pad to multiple of 16 */ | ||
800 | p = PTR_ALIGN(pos, 8); | ||
801 | if ((uintptr_t)p & 8) | ||
802 | *p = 0; | ||
803 | } | ||
804 | |||
805 | /* | ||
806 | * Figure out what HW csum a packet wants and return the appropriate control | ||
807 | * bits. | ||
808 | */ | ||
809 | static u64 hwcsum(const struct sk_buff *skb) | ||
810 | { | ||
811 | int csum_type; | ||
812 | const struct iphdr *iph = ip_hdr(skb); | ||
813 | |||
814 | if (iph->version == 4) { | ||
815 | if (iph->protocol == IPPROTO_TCP) | ||
816 | csum_type = TX_CSUM_TCPIP; | ||
817 | else if (iph->protocol == IPPROTO_UDP) | ||
818 | csum_type = TX_CSUM_UDPIP; | ||
819 | else { | ||
820 | nocsum: /* | ||
821 | * unknown protocol, disable HW csum | ||
822 | * and hope a bad packet is detected | ||
823 | */ | ||
824 | return TXPKT_L4CSUM_DIS; | ||
825 | } | ||
826 | } else { | ||
827 | /* | ||
828 | * this doesn't work with extension headers | ||
829 | */ | ||
830 | const struct ipv6hdr *ip6h = (const struct ipv6hdr *)iph; | ||
831 | |||
832 | if (ip6h->nexthdr == IPPROTO_TCP) | ||
833 | csum_type = TX_CSUM_TCPIP6; | ||
834 | else if (ip6h->nexthdr == IPPROTO_UDP) | ||
835 | csum_type = TX_CSUM_UDPIP6; | ||
836 | else | ||
837 | goto nocsum; | ||
838 | } | ||
839 | |||
840 | if (likely(csum_type >= TX_CSUM_TCPIP)) | ||
841 | return TXPKT_CSUM_TYPE(csum_type) | | ||
842 | TXPKT_IPHDR_LEN(skb_network_header_len(skb)) | | ||
843 | TXPKT_ETHHDR_LEN(skb_network_offset(skb) - ETH_HLEN); | ||
844 | else { | ||
845 | int start = skb_transport_offset(skb); | ||
846 | |||
847 | return TXPKT_CSUM_TYPE(csum_type) | TXPKT_CSUM_START(start) | | ||
848 | TXPKT_CSUM_LOC(start + skb->csum_offset); | ||
849 | } | ||
850 | } | ||
851 | |||
852 | static void eth_txq_stop(struct sge_eth_txq *q) | ||
853 | { | ||
854 | netif_tx_stop_queue(q->txq); | ||
855 | q->q.stops++; | ||
856 | } | ||
857 | |||
858 | static inline void txq_advance(struct sge_txq *q, unsigned int n) | ||
859 | { | ||
860 | q->in_use += n; | ||
861 | q->pidx += n; | ||
862 | if (q->pidx >= q->size) | ||
863 | q->pidx -= q->size; | ||
864 | } | ||
865 | |||
866 | /** | ||
867 | * t4_eth_xmit - add a packet to an Ethernet Tx queue | ||
868 | * @skb: the packet | ||
869 | * @dev: the egress net device | ||
870 | * | ||
871 | * Add a packet to an SGE Ethernet Tx queue. Runs with softirqs disabled. | ||
872 | */ | ||
873 | netdev_tx_t t4_eth_xmit(struct sk_buff *skb, struct net_device *dev) | ||
874 | { | ||
875 | u32 wr_mid; | ||
876 | u64 cntrl, *end; | ||
877 | int qidx, credits; | ||
878 | unsigned int flits, ndesc; | ||
879 | struct adapter *adap; | ||
880 | struct sge_eth_txq *q; | ||
881 | const struct port_info *pi; | ||
882 | struct fw_eth_tx_pkt_wr *wr; | ||
883 | struct cpl_tx_pkt_core *cpl; | ||
884 | const struct skb_shared_info *ssi; | ||
885 | dma_addr_t addr[MAX_SKB_FRAGS + 1]; | ||
886 | |||
887 | /* | ||
888 | * The chip min packet length is 10 octets but play safe and reject | ||
889 | * anything shorter than an Ethernet header. | ||
890 | */ | ||
891 | if (unlikely(skb->len < ETH_HLEN)) { | ||
892 | out_free: dev_kfree_skb(skb); | ||
893 | return NETDEV_TX_OK; | ||
894 | } | ||
895 | |||
896 | pi = netdev_priv(dev); | ||
897 | adap = pi->adapter; | ||
898 | qidx = skb_get_queue_mapping(skb); | ||
899 | q = &adap->sge.ethtxq[qidx + pi->first_qset]; | ||
900 | |||
901 | reclaim_completed_tx(adap, &q->q, true); | ||
902 | |||
903 | flits = calc_tx_flits(skb); | ||
904 | ndesc = flits_to_desc(flits); | ||
905 | credits = txq_avail(&q->q) - ndesc; | ||
906 | |||
907 | if (unlikely(credits < 0)) { | ||
908 | eth_txq_stop(q); | ||
909 | dev_err(adap->pdev_dev, | ||
910 | "%s: Tx ring %u full while queue awake!\n", | ||
911 | dev->name, qidx); | ||
912 | return NETDEV_TX_BUSY; | ||
913 | } | ||
914 | |||
915 | if (!is_eth_imm(skb) && | ||
916 | unlikely(map_skb(adap->pdev_dev, skb, addr) < 0)) { | ||
917 | q->mapping_err++; | ||
918 | goto out_free; | ||
919 | } | ||
920 | |||
921 | wr_mid = FW_WR_LEN16(DIV_ROUND_UP(flits, 2)); | ||
922 | if (unlikely(credits < ETHTXQ_STOP_THRES)) { | ||
923 | eth_txq_stop(q); | ||
924 | wr_mid |= FW_WR_EQUEQ | FW_WR_EQUIQ; | ||
925 | } | ||
926 | |||
927 | wr = (void *)&q->q.desc[q->q.pidx]; | ||
928 | wr->equiq_to_len16 = htonl(wr_mid); | ||
929 | wr->r3 = cpu_to_be64(0); | ||
930 | end = (u64 *)wr + flits; | ||
931 | |||
932 | ssi = skb_shinfo(skb); | ||
933 | if (ssi->gso_size) { | ||
934 | struct cpl_tx_pkt_lso *lso = (void *)wr; | ||
935 | bool v6 = (ssi->gso_type & SKB_GSO_TCPV6) != 0; | ||
936 | int l3hdr_len = skb_network_header_len(skb); | ||
937 | int eth_xtra_len = skb_network_offset(skb) - ETH_HLEN; | ||
938 | |||
939 | wr->op_immdlen = htonl(FW_WR_OP(FW_ETH_TX_PKT_WR) | | ||
940 | FW_WR_IMMDLEN(sizeof(*lso))); | ||
941 | lso->lso_ctrl = htonl(LSO_OPCODE(CPL_TX_PKT_LSO) | | ||
942 | LSO_FIRST_SLICE | LSO_LAST_SLICE | | ||
943 | LSO_IPV6(v6) | | ||
944 | LSO_ETHHDR_LEN(eth_xtra_len / 4) | | ||
945 | LSO_IPHDR_LEN(l3hdr_len / 4) | | ||
946 | LSO_TCPHDR_LEN(tcp_hdr(skb)->doff)); | ||
947 | lso->ipid_ofst = htons(0); | ||
948 | lso->mss = htons(ssi->gso_size); | ||
949 | lso->seqno_offset = htonl(0); | ||
950 | lso->len = htonl(skb->len); | ||
951 | cpl = (void *)(lso + 1); | ||
952 | cntrl = TXPKT_CSUM_TYPE(v6 ? TX_CSUM_TCPIP6 : TX_CSUM_TCPIP) | | ||
953 | TXPKT_IPHDR_LEN(l3hdr_len) | | ||
954 | TXPKT_ETHHDR_LEN(eth_xtra_len); | ||
955 | q->tso++; | ||
956 | q->tx_cso += ssi->gso_segs; | ||
957 | } else { | ||
958 | int len; | ||
959 | |||
960 | len = is_eth_imm(skb) ? skb->len + sizeof(*cpl) : sizeof(*cpl); | ||
961 | wr->op_immdlen = htonl(FW_WR_OP(FW_ETH_TX_PKT_WR) | | ||
962 | FW_WR_IMMDLEN(len)); | ||
963 | cpl = (void *)(wr + 1); | ||
964 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
965 | cntrl = hwcsum(skb) | TXPKT_IPCSUM_DIS; | ||
966 | q->tx_cso++; | ||
967 | } else | ||
968 | cntrl = TXPKT_L4CSUM_DIS | TXPKT_IPCSUM_DIS; | ||
969 | } | ||
970 | |||
971 | if (vlan_tx_tag_present(skb)) { | ||
972 | q->vlan_ins++; | ||
973 | cntrl |= TXPKT_VLAN_VLD | TXPKT_VLAN(vlan_tx_tag_get(skb)); | ||
974 | } | ||
975 | |||
976 | cpl->ctrl0 = htonl(TXPKT_OPCODE(CPL_TX_PKT_XT) | | ||
977 | TXPKT_INTF(pi->tx_chan) | TXPKT_PF(0)); | ||
978 | cpl->pack = htons(0); | ||
979 | cpl->len = htons(skb->len); | ||
980 | cpl->ctrl1 = cpu_to_be64(cntrl); | ||
981 | |||
982 | if (is_eth_imm(skb)) { | ||
983 | inline_tx_skb(skb, &q->q, cpl + 1); | ||
984 | dev_kfree_skb(skb); | ||
985 | } else { | ||
986 | int last_desc; | ||
987 | |||
988 | write_sgl(skb, &q->q, (struct ulptx_sgl *)(cpl + 1), end, 0, | ||
989 | addr); | ||
990 | skb_orphan(skb); | ||
991 | |||
992 | last_desc = q->q.pidx + ndesc - 1; | ||
993 | if (last_desc >= q->q.size) | ||
994 | last_desc -= q->q.size; | ||
995 | q->q.sdesc[last_desc].skb = skb; | ||
996 | q->q.sdesc[last_desc].sgl = (struct ulptx_sgl *)(cpl + 1); | ||
997 | } | ||
998 | |||
999 | txq_advance(&q->q, ndesc); | ||
1000 | |||
1001 | ring_tx_db(adap, &q->q, ndesc); | ||
1002 | return NETDEV_TX_OK; | ||
1003 | } | ||
1004 | |||
1005 | /** | ||
1006 | * reclaim_completed_tx_imm - reclaim completed control-queue Tx descs | ||
1007 | * @q: the SGE control Tx queue | ||
1008 | * | ||
1009 | * This is a variant of reclaim_completed_tx() that is used for Tx queues | ||
1010 | * that send only immediate data (presently just the control queues) and | ||
1011 | * thus do not have any sk_buffs to release. | ||
1012 | */ | ||
1013 | static inline void reclaim_completed_tx_imm(struct sge_txq *q) | ||
1014 | { | ||
1015 | int hw_cidx = ntohs(q->stat->cidx); | ||
1016 | int reclaim = hw_cidx - q->cidx; | ||
1017 | |||
1018 | if (reclaim < 0) | ||
1019 | reclaim += q->size; | ||
1020 | |||
1021 | q->in_use -= reclaim; | ||
1022 | q->cidx = hw_cidx; | ||
1023 | } | ||
1024 | |||
1025 | /** | ||
1026 | * is_imm - check whether a packet can be sent as immediate data | ||
1027 | * @skb: the packet | ||
1028 | * | ||
1029 | * Returns true if a packet can be sent as a WR with immediate data. | ||
1030 | */ | ||
1031 | static inline int is_imm(const struct sk_buff *skb) | ||
1032 | { | ||
1033 | return skb->len <= MAX_CTRL_WR_LEN; | ||
1034 | } | ||
1035 | |||
1036 | /** | ||
1037 | * ctrlq_check_stop - check if a control queue is full and should stop | ||
1038 | * @q: the queue | ||
1039 | * @wr: most recent WR written to the queue | ||
1040 | * | ||
1041 | * Check if a control queue has become full and should be stopped. | ||
1042 | * We clean up control queue descriptors very lazily, only when we are out. | ||
1043 | * If the queue is still full after reclaiming any completed descriptors | ||
1044 | * we suspend it and have the last WR wake it up. | ||
1045 | */ | ||
1046 | static void ctrlq_check_stop(struct sge_ctrl_txq *q, struct fw_wr_hdr *wr) | ||
1047 | { | ||
1048 | reclaim_completed_tx_imm(&q->q); | ||
1049 | if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES)) { | ||
1050 | wr->lo |= htonl(FW_WR_EQUEQ | FW_WR_EQUIQ); | ||
1051 | q->q.stops++; | ||
1052 | q->full = 1; | ||
1053 | } | ||
1054 | } | ||
1055 | |||
1056 | /** | ||
1057 | * ctrl_xmit - send a packet through an SGE control Tx queue | ||
1058 | * @q: the control queue | ||
1059 | * @skb: the packet | ||
1060 | * | ||
1061 | * Send a packet through an SGE control Tx queue. Packets sent through | ||
1062 | * a control queue must fit entirely as immediate data. | ||
1063 | */ | ||
1064 | static int ctrl_xmit(struct sge_ctrl_txq *q, struct sk_buff *skb) | ||
1065 | { | ||
1066 | unsigned int ndesc; | ||
1067 | struct fw_wr_hdr *wr; | ||
1068 | |||
1069 | if (unlikely(!is_imm(skb))) { | ||
1070 | WARN_ON(1); | ||
1071 | dev_kfree_skb(skb); | ||
1072 | return NET_XMIT_DROP; | ||
1073 | } | ||
1074 | |||
1075 | ndesc = DIV_ROUND_UP(skb->len, sizeof(struct tx_desc)); | ||
1076 | spin_lock(&q->sendq.lock); | ||
1077 | |||
1078 | if (unlikely(q->full)) { | ||
1079 | skb->priority = ndesc; /* save for restart */ | ||
1080 | __skb_queue_tail(&q->sendq, skb); | ||
1081 | spin_unlock(&q->sendq.lock); | ||
1082 | return NET_XMIT_CN; | ||
1083 | } | ||
1084 | |||
1085 | wr = (struct fw_wr_hdr *)&q->q.desc[q->q.pidx]; | ||
1086 | inline_tx_skb(skb, &q->q, wr); | ||
1087 | |||
1088 | txq_advance(&q->q, ndesc); | ||
1089 | if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES)) | ||
1090 | ctrlq_check_stop(q, wr); | ||
1091 | |||
1092 | ring_tx_db(q->adap, &q->q, ndesc); | ||
1093 | spin_unlock(&q->sendq.lock); | ||
1094 | |||
1095 | kfree_skb(skb); | ||
1096 | return NET_XMIT_SUCCESS; | ||
1097 | } | ||
1098 | |||
1099 | /** | ||
1100 | * restart_ctrlq - restart a suspended control queue | ||
1101 | * @data: the control queue to restart | ||
1102 | * | ||
1103 | * Resumes transmission on a suspended Tx control queue. | ||
1104 | */ | ||
1105 | static void restart_ctrlq(unsigned long data) | ||
1106 | { | ||
1107 | struct sk_buff *skb; | ||
1108 | unsigned int written = 0; | ||
1109 | struct sge_ctrl_txq *q = (struct sge_ctrl_txq *)data; | ||
1110 | |||
1111 | spin_lock(&q->sendq.lock); | ||
1112 | reclaim_completed_tx_imm(&q->q); | ||
1113 | BUG_ON(txq_avail(&q->q) < TXQ_STOP_THRES); /* q should be empty */ | ||
1114 | |||
1115 | while ((skb = __skb_dequeue(&q->sendq)) != NULL) { | ||
1116 | struct fw_wr_hdr *wr; | ||
1117 | unsigned int ndesc = skb->priority; /* previously saved */ | ||
1118 | |||
1119 | /* | ||
1120 | * Write descriptors and free skbs outside the lock to limit | ||
1121 | * wait times. q->full is still set so new skbs will be queued. | ||
1122 | */ | ||
1123 | spin_unlock(&q->sendq.lock); | ||
1124 | |||
1125 | wr = (struct fw_wr_hdr *)&q->q.desc[q->q.pidx]; | ||
1126 | inline_tx_skb(skb, &q->q, wr); | ||
1127 | kfree_skb(skb); | ||
1128 | |||
1129 | written += ndesc; | ||
1130 | txq_advance(&q->q, ndesc); | ||
1131 | if (unlikely(txq_avail(&q->q) < TXQ_STOP_THRES)) { | ||
1132 | unsigned long old = q->q.stops; | ||
1133 | |||
1134 | ctrlq_check_stop(q, wr); | ||
1135 | if (q->q.stops != old) { /* suspended anew */ | ||
1136 | spin_lock(&q->sendq.lock); | ||
1137 | goto ringdb; | ||
1138 | } | ||
1139 | } | ||
1140 | if (written > 16) { | ||
1141 | ring_tx_db(q->adap, &q->q, written); | ||
1142 | written = 0; | ||
1143 | } | ||
1144 | spin_lock(&q->sendq.lock); | ||
1145 | } | ||
1146 | q->full = 0; | ||
1147 | ringdb: if (written) | ||
1148 | ring_tx_db(q->adap, &q->q, written); | ||
1149 | spin_unlock(&q->sendq.lock); | ||
1150 | } | ||
1151 | |||
1152 | /** | ||
1153 | * t4_mgmt_tx - send a management message | ||
1154 | * @adap: the adapter | ||
1155 | * @skb: the packet containing the management message | ||
1156 | * | ||
1157 | * Send a management message through control queue 0. | ||
1158 | */ | ||
1159 | int t4_mgmt_tx(struct adapter *adap, struct sk_buff *skb) | ||
1160 | { | ||
1161 | int ret; | ||
1162 | |||
1163 | local_bh_disable(); | ||
1164 | ret = ctrl_xmit(&adap->sge.ctrlq[0], skb); | ||
1165 | local_bh_enable(); | ||
1166 | return ret; | ||
1167 | } | ||
1168 | |||
1169 | /** | ||
1170 | * is_ofld_imm - check whether a packet can be sent as immediate data | ||
1171 | * @skb: the packet | ||
1172 | * | ||
1173 | * Returns true if a packet can be sent as an offload WR with immediate | ||
1174 | * data. We currently use the same limit as for Ethernet packets. | ||
1175 | */ | ||
1176 | static inline int is_ofld_imm(const struct sk_buff *skb) | ||
1177 | { | ||
1178 | return skb->len <= MAX_IMM_TX_PKT_LEN; | ||
1179 | } | ||
1180 | |||
1181 | /** | ||
1182 | * calc_tx_flits_ofld - calculate # of flits for an offload packet | ||
1183 | * @skb: the packet | ||
1184 | * | ||
1185 | * Returns the number of flits needed for the given offload packet. | ||
1186 | * These packets are already fully constructed and no additional headers | ||
1187 | * will be added. | ||
1188 | */ | ||
1189 | static inline unsigned int calc_tx_flits_ofld(const struct sk_buff *skb) | ||
1190 | { | ||
1191 | unsigned int flits, cnt; | ||
1192 | |||
1193 | if (is_ofld_imm(skb)) | ||
1194 | return DIV_ROUND_UP(skb->len, 8); | ||
1195 | |||
1196 | flits = skb_transport_offset(skb) / 8U; /* headers */ | ||
1197 | cnt = skb_shinfo(skb)->nr_frags; | ||
1198 | if (skb->tail != skb->transport_header) | ||
1199 | cnt++; | ||
1200 | return flits + sgl_len(cnt); | ||
1201 | } | ||
1202 | |||
1203 | /** | ||
1204 | * txq_stop_maperr - stop a Tx queue due to I/O MMU exhaustion | ||
1205 | * @adap: the adapter | ||
1206 | * @q: the queue to stop | ||
1207 | * | ||
1208 | * Mark a Tx queue stopped due to I/O MMU exhaustion and resulting | ||
1209 | * inability to map packets. A periodic timer attempts to restart | ||
1210 | * queues so marked. | ||
1211 | */ | ||
1212 | static void txq_stop_maperr(struct sge_ofld_txq *q) | ||
1213 | { | ||
1214 | q->mapping_err++; | ||
1215 | q->q.stops++; | ||
1216 | set_bit(q->q.cntxt_id, q->adap->sge.txq_maperr); | ||
1217 | } | ||
1218 | |||
1219 | /** | ||
1220 | * ofldtxq_stop - stop an offload Tx queue that has become full | ||
1221 | * @q: the queue to stop | ||
1222 | * @skb: the packet causing the queue to become full | ||
1223 | * | ||
1224 | * Stops an offload Tx queue that has become full and modifies the packet | ||
1225 | * being written to request a wakeup. | ||
1226 | */ | ||
1227 | static void ofldtxq_stop(struct sge_ofld_txq *q, struct sk_buff *skb) | ||
1228 | { | ||
1229 | struct fw_wr_hdr *wr = (struct fw_wr_hdr *)skb->data; | ||
1230 | |||
1231 | wr->lo |= htonl(FW_WR_EQUEQ | FW_WR_EQUIQ); | ||
1232 | q->q.stops++; | ||
1233 | q->full = 1; | ||
1234 | } | ||
1235 | |||
1236 | /** | ||
1237 | * service_ofldq - restart a suspended offload queue | ||
1238 | * @q: the offload queue | ||
1239 | * | ||
1240 | * Services an offload Tx queue by moving packets from its packet queue | ||
1241 | * to the HW Tx ring. The function starts and ends with the queue locked. | ||
1242 | */ | ||
1243 | static void service_ofldq(struct sge_ofld_txq *q) | ||
1244 | { | ||
1245 | u64 *pos; | ||
1246 | int credits; | ||
1247 | struct sk_buff *skb; | ||
1248 | unsigned int written = 0; | ||
1249 | unsigned int flits, ndesc; | ||
1250 | |||
1251 | while ((skb = skb_peek(&q->sendq)) != NULL && !q->full) { | ||
1252 | /* | ||
1253 | * We drop the lock but leave skb on sendq, thus retaining | ||
1254 | * exclusive access to the state of the queue. | ||
1255 | */ | ||
1256 | spin_unlock(&q->sendq.lock); | ||
1257 | |||
1258 | reclaim_completed_tx(q->adap, &q->q, false); | ||
1259 | |||
1260 | flits = skb->priority; /* previously saved */ | ||
1261 | ndesc = flits_to_desc(flits); | ||
1262 | credits = txq_avail(&q->q) - ndesc; | ||
1263 | BUG_ON(credits < 0); | ||
1264 | if (unlikely(credits < TXQ_STOP_THRES)) | ||
1265 | ofldtxq_stop(q, skb); | ||
1266 | |||
1267 | pos = (u64 *)&q->q.desc[q->q.pidx]; | ||
1268 | if (is_ofld_imm(skb)) | ||
1269 | inline_tx_skb(skb, &q->q, pos); | ||
1270 | else if (map_skb(q->adap->pdev_dev, skb, | ||
1271 | (dma_addr_t *)skb->head)) { | ||
1272 | txq_stop_maperr(q); | ||
1273 | spin_lock(&q->sendq.lock); | ||
1274 | break; | ||
1275 | } else { | ||
1276 | int last_desc, hdr_len = skb_transport_offset(skb); | ||
1277 | |||
1278 | memcpy(pos, skb->data, hdr_len); | ||
1279 | write_sgl(skb, &q->q, (void *)pos + hdr_len, | ||
1280 | pos + flits, hdr_len, | ||
1281 | (dma_addr_t *)skb->head); | ||
1282 | #ifdef CONFIG_NEED_DMA_MAP_STATE | ||
1283 | skb->dev = q->adap->port[0]; | ||
1284 | skb->destructor = deferred_unmap_destructor; | ||
1285 | #endif | ||
1286 | last_desc = q->q.pidx + ndesc - 1; | ||
1287 | if (last_desc >= q->q.size) | ||
1288 | last_desc -= q->q.size; | ||
1289 | q->q.sdesc[last_desc].skb = skb; | ||
1290 | } | ||
1291 | |||
1292 | txq_advance(&q->q, ndesc); | ||
1293 | written += ndesc; | ||
1294 | if (unlikely(written > 32)) { | ||
1295 | ring_tx_db(q->adap, &q->q, written); | ||
1296 | written = 0; | ||
1297 | } | ||
1298 | |||
1299 | spin_lock(&q->sendq.lock); | ||
1300 | __skb_unlink(skb, &q->sendq); | ||
1301 | if (is_ofld_imm(skb)) | ||
1302 | kfree_skb(skb); | ||
1303 | } | ||
1304 | if (likely(written)) | ||
1305 | ring_tx_db(q->adap, &q->q, written); | ||
1306 | } | ||
1307 | |||
1308 | /** | ||
1309 | * ofld_xmit - send a packet through an offload queue | ||
1310 | * @q: the Tx offload queue | ||
1311 | * @skb: the packet | ||
1312 | * | ||
1313 | * Send an offload packet through an SGE offload queue. | ||
1314 | */ | ||
1315 | static int ofld_xmit(struct sge_ofld_txq *q, struct sk_buff *skb) | ||
1316 | { | ||
1317 | skb->priority = calc_tx_flits_ofld(skb); /* save for restart */ | ||
1318 | spin_lock(&q->sendq.lock); | ||
1319 | __skb_queue_tail(&q->sendq, skb); | ||
1320 | if (q->sendq.qlen == 1) | ||
1321 | service_ofldq(q); | ||
1322 | spin_unlock(&q->sendq.lock); | ||
1323 | return NET_XMIT_SUCCESS; | ||
1324 | } | ||
1325 | |||
1326 | /** | ||
1327 | * restart_ofldq - restart a suspended offload queue | ||
1328 | * @data: the offload queue to restart | ||
1329 | * | ||
1330 | * Resumes transmission on a suspended Tx offload queue. | ||
1331 | */ | ||
1332 | static void restart_ofldq(unsigned long data) | ||
1333 | { | ||
1334 | struct sge_ofld_txq *q = (struct sge_ofld_txq *)data; | ||
1335 | |||
1336 | spin_lock(&q->sendq.lock); | ||
1337 | q->full = 0; /* the queue actually is completely empty now */ | ||
1338 | service_ofldq(q); | ||
1339 | spin_unlock(&q->sendq.lock); | ||
1340 | } | ||
1341 | |||
1342 | /** | ||
1343 | * skb_txq - return the Tx queue an offload packet should use | ||
1344 | * @skb: the packet | ||
1345 | * | ||
1346 | * Returns the Tx queue an offload packet should use as indicated by bits | ||
1347 | * 1-15 in the packet's queue_mapping. | ||
1348 | */ | ||
1349 | static inline unsigned int skb_txq(const struct sk_buff *skb) | ||
1350 | { | ||
1351 | return skb->queue_mapping >> 1; | ||
1352 | } | ||
1353 | |||
1354 | /** | ||
1355 | * is_ctrl_pkt - return whether an offload packet is a control packet | ||
1356 | * @skb: the packet | ||
1357 | * | ||
1358 | * Returns whether an offload packet should use an OFLD or a CTRL | ||
1359 | * Tx queue as indicated by bit 0 in the packet's queue_mapping. | ||
1360 | */ | ||
1361 | static inline unsigned int is_ctrl_pkt(const struct sk_buff *skb) | ||
1362 | { | ||
1363 | return skb->queue_mapping & 1; | ||
1364 | } | ||
1365 | |||
1366 | static inline int ofld_send(struct adapter *adap, struct sk_buff *skb) | ||
1367 | { | ||
1368 | unsigned int idx = skb_txq(skb); | ||
1369 | |||
1370 | if (unlikely(is_ctrl_pkt(skb))) | ||
1371 | return ctrl_xmit(&adap->sge.ctrlq[idx], skb); | ||
1372 | return ofld_xmit(&adap->sge.ofldtxq[idx], skb); | ||
1373 | } | ||
1374 | |||
1375 | /** | ||
1376 | * t4_ofld_send - send an offload packet | ||
1377 | * @adap: the adapter | ||
1378 | * @skb: the packet | ||
1379 | * | ||
1380 | * Sends an offload packet. We use the packet queue_mapping to select the | ||
1381 | * appropriate Tx queue as follows: bit 0 indicates whether the packet | ||
1382 | * should be sent as regular or control, bits 1-15 select the queue. | ||
1383 | */ | ||
1384 | int t4_ofld_send(struct adapter *adap, struct sk_buff *skb) | ||
1385 | { | ||
1386 | int ret; | ||
1387 | |||
1388 | local_bh_disable(); | ||
1389 | ret = ofld_send(adap, skb); | ||
1390 | local_bh_enable(); | ||
1391 | return ret; | ||
1392 | } | ||
1393 | |||
1394 | /** | ||
1395 | * cxgb4_ofld_send - send an offload packet | ||
1396 | * @dev: the net device | ||
1397 | * @skb: the packet | ||
1398 | * | ||
1399 | * Sends an offload packet. This is an exported version of @t4_ofld_send, | ||
1400 | * intended for ULDs. | ||
1401 | */ | ||
1402 | int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb) | ||
1403 | { | ||
1404 | return t4_ofld_send(netdev2adap(dev), skb); | ||
1405 | } | ||
1406 | EXPORT_SYMBOL(cxgb4_ofld_send); | ||
1407 | |||
1408 | static inline void copy_frags(struct skb_shared_info *ssi, | ||
1409 | const struct pkt_gl *gl, unsigned int offset) | ||
1410 | { | ||
1411 | unsigned int n; | ||
1412 | |||
1413 | /* usually there's just one frag */ | ||
1414 | ssi->frags[0].page = gl->frags[0].page; | ||
1415 | ssi->frags[0].page_offset = gl->frags[0].page_offset + offset; | ||
1416 | ssi->frags[0].size = gl->frags[0].size - offset; | ||
1417 | ssi->nr_frags = gl->nfrags; | ||
1418 | n = gl->nfrags - 1; | ||
1419 | if (n) | ||
1420 | memcpy(&ssi->frags[1], &gl->frags[1], n * sizeof(skb_frag_t)); | ||
1421 | |||
1422 | /* get a reference to the last page, we don't own it */ | ||
1423 | get_page(gl->frags[n].page); | ||
1424 | } | ||
1425 | |||
1426 | /** | ||
1427 | * cxgb4_pktgl_to_skb - build an sk_buff from a packet gather list | ||
1428 | * @gl: the gather list | ||
1429 | * @skb_len: size of sk_buff main body if it carries fragments | ||
1430 | * @pull_len: amount of data to move to the sk_buff's main body | ||
1431 | * | ||
1432 | * Builds an sk_buff from the given packet gather list. Returns the | ||
1433 | * sk_buff or %NULL if sk_buff allocation failed. | ||
1434 | */ | ||
1435 | struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl, | ||
1436 | unsigned int skb_len, unsigned int pull_len) | ||
1437 | { | ||
1438 | struct sk_buff *skb; | ||
1439 | |||
1440 | /* | ||
1441 | * Below we rely on RX_COPY_THRES being less than the smallest Rx buffer | ||
1442 | * size, which is expected since buffers are at least PAGE_SIZEd. | ||
1443 | * In this case packets up to RX_COPY_THRES have only one fragment. | ||
1444 | */ | ||
1445 | if (gl->tot_len <= RX_COPY_THRES) { | ||
1446 | skb = dev_alloc_skb(gl->tot_len); | ||
1447 | if (unlikely(!skb)) | ||
1448 | goto out; | ||
1449 | __skb_put(skb, gl->tot_len); | ||
1450 | skb_copy_to_linear_data(skb, gl->va, gl->tot_len); | ||
1451 | } else { | ||
1452 | skb = dev_alloc_skb(skb_len); | ||
1453 | if (unlikely(!skb)) | ||
1454 | goto out; | ||
1455 | __skb_put(skb, pull_len); | ||
1456 | skb_copy_to_linear_data(skb, gl->va, pull_len); | ||
1457 | |||
1458 | copy_frags(skb_shinfo(skb), gl, pull_len); | ||
1459 | skb->len = gl->tot_len; | ||
1460 | skb->data_len = skb->len - pull_len; | ||
1461 | skb->truesize += skb->data_len; | ||
1462 | } | ||
1463 | out: return skb; | ||
1464 | } | ||
1465 | EXPORT_SYMBOL(cxgb4_pktgl_to_skb); | ||
1466 | |||
1467 | /** | ||
1468 | * t4_pktgl_free - free a packet gather list | ||
1469 | * @gl: the gather list | ||
1470 | * | ||
1471 | * Releases the pages of a packet gather list. We do not own the last | ||
1472 | * page on the list and do not free it. | ||
1473 | */ | ||
1474 | void t4_pktgl_free(const struct pkt_gl *gl) | ||
1475 | { | ||
1476 | int n; | ||
1477 | const skb_frag_t *p; | ||
1478 | |||
1479 | for (p = gl->frags, n = gl->nfrags - 1; n--; p++) | ||
1480 | put_page(p->page); | ||
1481 | } | ||
1482 | |||
1483 | /* | ||
1484 | * Process an MPS trace packet. Give it an unused protocol number so it won't | ||
1485 | * be delivered to anyone and send it to the stack for capture. | ||
1486 | */ | ||
1487 | static noinline int handle_trace_pkt(struct adapter *adap, | ||
1488 | const struct pkt_gl *gl) | ||
1489 | { | ||
1490 | struct sk_buff *skb; | ||
1491 | struct cpl_trace_pkt *p; | ||
1492 | |||
1493 | skb = cxgb4_pktgl_to_skb(gl, RX_PULL_LEN, RX_PULL_LEN); | ||
1494 | if (unlikely(!skb)) { | ||
1495 | t4_pktgl_free(gl); | ||
1496 | return 0; | ||
1497 | } | ||
1498 | |||
1499 | p = (struct cpl_trace_pkt *)skb->data; | ||
1500 | __skb_pull(skb, sizeof(*p)); | ||
1501 | skb_reset_mac_header(skb); | ||
1502 | skb->protocol = htons(0xffff); | ||
1503 | skb->dev = adap->port[0]; | ||
1504 | netif_receive_skb(skb); | ||
1505 | return 0; | ||
1506 | } | ||
1507 | |||
1508 | static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl, | ||
1509 | const struct cpl_rx_pkt *pkt) | ||
1510 | { | ||
1511 | int ret; | ||
1512 | struct sk_buff *skb; | ||
1513 | |||
1514 | skb = napi_get_frags(&rxq->rspq.napi); | ||
1515 | if (unlikely(!skb)) { | ||
1516 | t4_pktgl_free(gl); | ||
1517 | rxq->stats.rx_drops++; | ||
1518 | return; | ||
1519 | } | ||
1520 | |||
1521 | copy_frags(skb_shinfo(skb), gl, RX_PKT_PAD); | ||
1522 | skb->len = gl->tot_len - RX_PKT_PAD; | ||
1523 | skb->data_len = skb->len; | ||
1524 | skb->truesize += skb->data_len; | ||
1525 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1526 | skb_record_rx_queue(skb, rxq->rspq.idx); | ||
1527 | |||
1528 | if (unlikely(pkt->vlan_ex)) { | ||
1529 | struct port_info *pi = netdev_priv(rxq->rspq.netdev); | ||
1530 | struct vlan_group *grp = pi->vlan_grp; | ||
1531 | |||
1532 | rxq->stats.vlan_ex++; | ||
1533 | if (likely(grp)) { | ||
1534 | ret = vlan_gro_frags(&rxq->rspq.napi, grp, | ||
1535 | ntohs(pkt->vlan)); | ||
1536 | goto stats; | ||
1537 | } | ||
1538 | } | ||
1539 | ret = napi_gro_frags(&rxq->rspq.napi); | ||
1540 | stats: if (ret == GRO_HELD) | ||
1541 | rxq->stats.lro_pkts++; | ||
1542 | else if (ret == GRO_MERGED || ret == GRO_MERGED_FREE) | ||
1543 | rxq->stats.lro_merged++; | ||
1544 | rxq->stats.pkts++; | ||
1545 | rxq->stats.rx_cso++; | ||
1546 | } | ||
1547 | |||
1548 | /** | ||
1549 | * t4_ethrx_handler - process an ingress ethernet packet | ||
1550 | * @q: the response queue that received the packet | ||
1551 | * @rsp: the response queue descriptor holding the RX_PKT message | ||
1552 | * @si: the gather list of packet fragments | ||
1553 | * | ||
1554 | * Process an ingress ethernet packet and deliver it to the stack. | ||
1555 | */ | ||
1556 | int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, | ||
1557 | const struct pkt_gl *si) | ||
1558 | { | ||
1559 | bool csum_ok; | ||
1560 | struct sk_buff *skb; | ||
1561 | struct port_info *pi; | ||
1562 | const struct cpl_rx_pkt *pkt; | ||
1563 | struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq); | ||
1564 | |||
1565 | if (unlikely(*(u8 *)rsp == CPL_TRACE_PKT)) | ||
1566 | return handle_trace_pkt(q->adap, si); | ||
1567 | |||
1568 | pkt = (void *)&rsp[1]; | ||
1569 | csum_ok = pkt->csum_calc && !pkt->err_vec; | ||
1570 | if ((pkt->l2info & htonl(RXF_TCP)) && | ||
1571 | (q->netdev->features & NETIF_F_GRO) && csum_ok && !pkt->ip_frag) { | ||
1572 | do_gro(rxq, si, pkt); | ||
1573 | return 0; | ||
1574 | } | ||
1575 | |||
1576 | skb = cxgb4_pktgl_to_skb(si, RX_PKT_SKB_LEN, RX_PULL_LEN); | ||
1577 | if (unlikely(!skb)) { | ||
1578 | t4_pktgl_free(si); | ||
1579 | rxq->stats.rx_drops++; | ||
1580 | return 0; | ||
1581 | } | ||
1582 | |||
1583 | __skb_pull(skb, RX_PKT_PAD); /* remove ethernet header padding */ | ||
1584 | skb->protocol = eth_type_trans(skb, q->netdev); | ||
1585 | skb_record_rx_queue(skb, q->idx); | ||
1586 | pi = netdev_priv(skb->dev); | ||
1587 | rxq->stats.pkts++; | ||
1588 | |||
1589 | if (csum_ok && (pi->rx_offload & RX_CSO) && | ||
1590 | (pkt->l2info & htonl(RXF_UDP | RXF_TCP))) { | ||
1591 | if (!pkt->ip_frag) | ||
1592 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1593 | else { | ||
1594 | __sum16 c = (__force __sum16)pkt->csum; | ||
1595 | skb->csum = csum_unfold(c); | ||
1596 | skb->ip_summed = CHECKSUM_COMPLETE; | ||
1597 | } | ||
1598 | rxq->stats.rx_cso++; | ||
1599 | } else | ||
1600 | skb->ip_summed = CHECKSUM_NONE; | ||
1601 | |||
1602 | if (unlikely(pkt->vlan_ex)) { | ||
1603 | struct vlan_group *grp = pi->vlan_grp; | ||
1604 | |||
1605 | rxq->stats.vlan_ex++; | ||
1606 | if (likely(grp)) | ||
1607 | vlan_hwaccel_receive_skb(skb, grp, ntohs(pkt->vlan)); | ||
1608 | else | ||
1609 | dev_kfree_skb_any(skb); | ||
1610 | } else | ||
1611 | netif_receive_skb(skb); | ||
1612 | |||
1613 | return 0; | ||
1614 | } | ||
1615 | |||
1616 | /** | ||
1617 | * restore_rx_bufs - put back a packet's Rx buffers | ||
1618 | * @si: the packet gather list | ||
1619 | * @q: the SGE free list | ||
1620 | * @frags: number of FL buffers to restore | ||
1621 | * | ||
1622 | * Puts back on an FL the Rx buffers associated with @si. The buffers | ||
1623 | * have already been unmapped and are left unmapped, we mark them so to | ||
1624 | * prevent further unmapping attempts. | ||
1625 | * | ||
1626 | * This function undoes a series of @unmap_rx_buf calls when we find out | ||
1627 | * that the current packet can't be processed right away afterall and we | ||
1628 | * need to come back to it later. This is a very rare event and there's | ||
1629 | * no effort to make this particularly efficient. | ||
1630 | */ | ||
1631 | static void restore_rx_bufs(const struct pkt_gl *si, struct sge_fl *q, | ||
1632 | int frags) | ||
1633 | { | ||
1634 | struct rx_sw_desc *d; | ||
1635 | |||
1636 | while (frags--) { | ||
1637 | if (q->cidx == 0) | ||
1638 | q->cidx = q->size - 1; | ||
1639 | else | ||
1640 | q->cidx--; | ||
1641 | d = &q->sdesc[q->cidx]; | ||
1642 | d->page = si->frags[frags].page; | ||
1643 | d->dma_addr |= RX_UNMAPPED_BUF; | ||
1644 | q->avail++; | ||
1645 | } | ||
1646 | } | ||
1647 | |||
1648 | /** | ||
1649 | * is_new_response - check if a response is newly written | ||
1650 | * @r: the response descriptor | ||
1651 | * @q: the response queue | ||
1652 | * | ||
1653 | * Returns true if a response descriptor contains a yet unprocessed | ||
1654 | * response. | ||
1655 | */ | ||
1656 | static inline bool is_new_response(const struct rsp_ctrl *r, | ||
1657 | const struct sge_rspq *q) | ||
1658 | { | ||
1659 | return RSPD_GEN(r->type_gen) == q->gen; | ||
1660 | } | ||
1661 | |||
1662 | /** | ||
1663 | * rspq_next - advance to the next entry in a response queue | ||
1664 | * @q: the queue | ||
1665 | * | ||
1666 | * Updates the state of a response queue to advance it to the next entry. | ||
1667 | */ | ||
1668 | static inline void rspq_next(struct sge_rspq *q) | ||
1669 | { | ||
1670 | q->cur_desc = (void *)q->cur_desc + q->iqe_len; | ||
1671 | if (unlikely(++q->cidx == q->size)) { | ||
1672 | q->cidx = 0; | ||
1673 | q->gen ^= 1; | ||
1674 | q->cur_desc = q->desc; | ||
1675 | } | ||
1676 | } | ||
1677 | |||
1678 | /** | ||
1679 | * process_responses - process responses from an SGE response queue | ||
1680 | * @q: the ingress queue to process | ||
1681 | * @budget: how many responses can be processed in this round | ||
1682 | * | ||
1683 | * Process responses from an SGE response queue up to the supplied budget. | ||
1684 | * Responses include received packets as well as control messages from FW | ||
1685 | * or HW. | ||
1686 | * | ||
1687 | * Additionally choose the interrupt holdoff time for the next interrupt | ||
1688 | * on this queue. If the system is under memory shortage use a fairly | ||
1689 | * long delay to help recovery. | ||
1690 | */ | ||
1691 | static int process_responses(struct sge_rspq *q, int budget) | ||
1692 | { | ||
1693 | int ret, rsp_type; | ||
1694 | int budget_left = budget; | ||
1695 | const struct rsp_ctrl *rc; | ||
1696 | struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq); | ||
1697 | |||
1698 | while (likely(budget_left)) { | ||
1699 | rc = (void *)q->cur_desc + (q->iqe_len - sizeof(*rc)); | ||
1700 | if (!is_new_response(rc, q)) | ||
1701 | break; | ||
1702 | |||
1703 | rmb(); | ||
1704 | rsp_type = RSPD_TYPE(rc->type_gen); | ||
1705 | if (likely(rsp_type == RSP_TYPE_FLBUF)) { | ||
1706 | skb_frag_t *fp; | ||
1707 | struct pkt_gl si; | ||
1708 | const struct rx_sw_desc *rsd; | ||
1709 | u32 len = ntohl(rc->pldbuflen_qid), bufsz, frags; | ||
1710 | |||
1711 | if (len & RSPD_NEWBUF) { | ||
1712 | if (likely(q->offset > 0)) { | ||
1713 | free_rx_bufs(q->adap, &rxq->fl, 1); | ||
1714 | q->offset = 0; | ||
1715 | } | ||
1716 | len &= RSPD_LEN; | ||
1717 | } | ||
1718 | si.tot_len = len; | ||
1719 | |||
1720 | /* gather packet fragments */ | ||
1721 | for (frags = 0, fp = si.frags; ; frags++, fp++) { | ||
1722 | rsd = &rxq->fl.sdesc[rxq->fl.cidx]; | ||
1723 | bufsz = get_buf_size(rsd); | ||
1724 | fp->page = rsd->page; | ||
1725 | fp->page_offset = q->offset; | ||
1726 | fp->size = min(bufsz, len); | ||
1727 | len -= fp->size; | ||
1728 | if (!len) | ||
1729 | break; | ||
1730 | unmap_rx_buf(q->adap, &rxq->fl); | ||
1731 | } | ||
1732 | |||
1733 | /* | ||
1734 | * Last buffer remains mapped so explicitly make it | ||
1735 | * coherent for CPU access. | ||
1736 | */ | ||
1737 | dma_sync_single_for_cpu(q->adap->pdev_dev, | ||
1738 | get_buf_addr(rsd), | ||
1739 | fp->size, DMA_FROM_DEVICE); | ||
1740 | |||
1741 | si.va = page_address(si.frags[0].page) + | ||
1742 | si.frags[0].page_offset; | ||
1743 | prefetch(si.va); | ||
1744 | |||
1745 | si.nfrags = frags + 1; | ||
1746 | ret = q->handler(q, q->cur_desc, &si); | ||
1747 | if (likely(ret == 0)) | ||
1748 | q->offset += ALIGN(fp->size, FL_ALIGN); | ||
1749 | else | ||
1750 | restore_rx_bufs(&si, &rxq->fl, frags); | ||
1751 | } else if (likely(rsp_type == RSP_TYPE_CPL)) { | ||
1752 | ret = q->handler(q, q->cur_desc, NULL); | ||
1753 | } else { | ||
1754 | ret = q->handler(q, (const __be64 *)rc, CXGB4_MSG_AN); | ||
1755 | } | ||
1756 | |||
1757 | if (unlikely(ret)) { | ||
1758 | /* couldn't process descriptor, back off for recovery */ | ||
1759 | q->next_intr_params = QINTR_TIMER_IDX(NOMEM_TMR_IDX); | ||
1760 | break; | ||
1761 | } | ||
1762 | |||
1763 | rspq_next(q); | ||
1764 | budget_left--; | ||
1765 | } | ||
1766 | |||
1767 | if (q->offset >= 0 && rxq->fl.size - rxq->fl.avail >= 16) | ||
1768 | __refill_fl(q->adap, &rxq->fl); | ||
1769 | return budget - budget_left; | ||
1770 | } | ||
1771 | |||
1772 | /** | ||
1773 | * napi_rx_handler - the NAPI handler for Rx processing | ||
1774 | * @napi: the napi instance | ||
1775 | * @budget: how many packets we can process in this round | ||
1776 | * | ||
1777 | * Handler for new data events when using NAPI. This does not need any | ||
1778 | * locking or protection from interrupts as data interrupts are off at | ||
1779 | * this point and other adapter interrupts do not interfere (the latter | ||
1780 | * in not a concern at all with MSI-X as non-data interrupts then have | ||
1781 | * a separate handler). | ||
1782 | */ | ||
1783 | static int napi_rx_handler(struct napi_struct *napi, int budget) | ||
1784 | { | ||
1785 | unsigned int params; | ||
1786 | struct sge_rspq *q = container_of(napi, struct sge_rspq, napi); | ||
1787 | int work_done = process_responses(q, budget); | ||
1788 | |||
1789 | if (likely(work_done < budget)) { | ||
1790 | napi_complete(napi); | ||
1791 | params = q->next_intr_params; | ||
1792 | q->next_intr_params = q->intr_params; | ||
1793 | } else | ||
1794 | params = QINTR_TIMER_IDX(7); | ||
1795 | |||
1796 | t4_write_reg(q->adap, MYPF_REG(SGE_PF_GTS), CIDXINC(work_done) | | ||
1797 | INGRESSQID((u32)q->cntxt_id) | SEINTARM(params)); | ||
1798 | return work_done; | ||
1799 | } | ||
1800 | |||
1801 | /* | ||
1802 | * The MSI-X interrupt handler for an SGE response queue. | ||
1803 | */ | ||
1804 | irqreturn_t t4_sge_intr_msix(int irq, void *cookie) | ||
1805 | { | ||
1806 | struct sge_rspq *q = cookie; | ||
1807 | |||
1808 | napi_schedule(&q->napi); | ||
1809 | return IRQ_HANDLED; | ||
1810 | } | ||
1811 | |||
1812 | /* | ||
1813 | * Process the indirect interrupt entries in the interrupt queue and kick off | ||
1814 | * NAPI for each queue that has generated an entry. | ||
1815 | */ | ||
1816 | static unsigned int process_intrq(struct adapter *adap) | ||
1817 | { | ||
1818 | unsigned int credits; | ||
1819 | const struct rsp_ctrl *rc; | ||
1820 | struct sge_rspq *q = &adap->sge.intrq; | ||
1821 | |||
1822 | spin_lock(&adap->sge.intrq_lock); | ||
1823 | for (credits = 0; ; credits++) { | ||
1824 | rc = (void *)q->cur_desc + (q->iqe_len - sizeof(*rc)); | ||
1825 | if (!is_new_response(rc, q)) | ||
1826 | break; | ||
1827 | |||
1828 | rmb(); | ||
1829 | if (RSPD_TYPE(rc->type_gen) == RSP_TYPE_INTR) { | ||
1830 | unsigned int qid = ntohl(rc->pldbuflen_qid); | ||
1831 | |||
1832 | napi_schedule(&adap->sge.ingr_map[qid]->napi); | ||
1833 | } | ||
1834 | |||
1835 | rspq_next(q); | ||
1836 | } | ||
1837 | |||
1838 | t4_write_reg(adap, MYPF_REG(SGE_PF_GTS), CIDXINC(credits) | | ||
1839 | INGRESSQID(q->cntxt_id) | SEINTARM(q->intr_params)); | ||
1840 | spin_unlock(&adap->sge.intrq_lock); | ||
1841 | return credits; | ||
1842 | } | ||
1843 | |||
1844 | /* | ||
1845 | * The MSI interrupt handler, which handles data events from SGE response queues | ||
1846 | * as well as error and other async events as they all use the same MSI vector. | ||
1847 | */ | ||
1848 | static irqreturn_t t4_intr_msi(int irq, void *cookie) | ||
1849 | { | ||
1850 | struct adapter *adap = cookie; | ||
1851 | |||
1852 | t4_slow_intr_handler(adap); | ||
1853 | process_intrq(adap); | ||
1854 | return IRQ_HANDLED; | ||
1855 | } | ||
1856 | |||
1857 | /* | ||
1858 | * Interrupt handler for legacy INTx interrupts. | ||
1859 | * Handles data events from SGE response queues as well as error and other | ||
1860 | * async events as they all use the same interrupt line. | ||
1861 | */ | ||
1862 | static irqreturn_t t4_intr_intx(int irq, void *cookie) | ||
1863 | { | ||
1864 | struct adapter *adap = cookie; | ||
1865 | |||
1866 | t4_write_reg(adap, MYPF_REG(PCIE_PF_CLI), 0); | ||
1867 | if (t4_slow_intr_handler(adap) | process_intrq(adap)) | ||
1868 | return IRQ_HANDLED; | ||
1869 | return IRQ_NONE; /* probably shared interrupt */ | ||
1870 | } | ||
1871 | |||
1872 | /** | ||
1873 | * t4_intr_handler - select the top-level interrupt handler | ||
1874 | * @adap: the adapter | ||
1875 | * | ||
1876 | * Selects the top-level interrupt handler based on the type of interrupts | ||
1877 | * (MSI-X, MSI, or INTx). | ||
1878 | */ | ||
1879 | irq_handler_t t4_intr_handler(struct adapter *adap) | ||
1880 | { | ||
1881 | if (adap->flags & USING_MSIX) | ||
1882 | return t4_sge_intr_msix; | ||
1883 | if (adap->flags & USING_MSI) | ||
1884 | return t4_intr_msi; | ||
1885 | return t4_intr_intx; | ||
1886 | } | ||
1887 | |||
1888 | static void sge_rx_timer_cb(unsigned long data) | ||
1889 | { | ||
1890 | unsigned long m; | ||
1891 | unsigned int i, cnt[2]; | ||
1892 | struct adapter *adap = (struct adapter *)data; | ||
1893 | struct sge *s = &adap->sge; | ||
1894 | |||
1895 | for (i = 0; i < ARRAY_SIZE(s->starving_fl); i++) | ||
1896 | for (m = s->starving_fl[i]; m; m &= m - 1) { | ||
1897 | struct sge_eth_rxq *rxq; | ||
1898 | unsigned int id = __ffs(m) + i * BITS_PER_LONG; | ||
1899 | struct sge_fl *fl = s->egr_map[id]; | ||
1900 | |||
1901 | clear_bit(id, s->starving_fl); | ||
1902 | smp_mb__after_clear_bit(); | ||
1903 | |||
1904 | if (fl_starving(fl)) { | ||
1905 | rxq = container_of(fl, struct sge_eth_rxq, fl); | ||
1906 | if (napi_reschedule(&rxq->rspq.napi)) | ||
1907 | fl->starving++; | ||
1908 | else | ||
1909 | set_bit(id, s->starving_fl); | ||
1910 | } | ||
1911 | } | ||
1912 | |||
1913 | t4_write_reg(adap, SGE_DEBUG_INDEX, 13); | ||
1914 | cnt[0] = t4_read_reg(adap, SGE_DEBUG_DATA_HIGH); | ||
1915 | cnt[1] = t4_read_reg(adap, SGE_DEBUG_DATA_LOW); | ||
1916 | |||
1917 | for (i = 0; i < 2; i++) | ||
1918 | if (cnt[i] >= s->starve_thres) { | ||
1919 | if (s->idma_state[i] || cnt[i] == 0xffffffff) | ||
1920 | continue; | ||
1921 | s->idma_state[i] = 1; | ||
1922 | t4_write_reg(adap, SGE_DEBUG_INDEX, 11); | ||
1923 | m = t4_read_reg(adap, SGE_DEBUG_DATA_LOW) >> (i * 16); | ||
1924 | dev_warn(adap->pdev_dev, | ||
1925 | "SGE idma%u starvation detected for " | ||
1926 | "queue %lu\n", i, m & 0xffff); | ||
1927 | } else if (s->idma_state[i]) | ||
1928 | s->idma_state[i] = 0; | ||
1929 | |||
1930 | mod_timer(&s->rx_timer, jiffies + RX_QCHECK_PERIOD); | ||
1931 | } | ||
1932 | |||
1933 | static void sge_tx_timer_cb(unsigned long data) | ||
1934 | { | ||
1935 | unsigned long m; | ||
1936 | unsigned int i, budget; | ||
1937 | struct adapter *adap = (struct adapter *)data; | ||
1938 | struct sge *s = &adap->sge; | ||
1939 | |||
1940 | for (i = 0; i < ARRAY_SIZE(s->txq_maperr); i++) | ||
1941 | for (m = s->txq_maperr[i]; m; m &= m - 1) { | ||
1942 | unsigned long id = __ffs(m) + i * BITS_PER_LONG; | ||
1943 | struct sge_ofld_txq *txq = s->egr_map[id]; | ||
1944 | |||
1945 | clear_bit(id, s->txq_maperr); | ||
1946 | tasklet_schedule(&txq->qresume_tsk); | ||
1947 | } | ||
1948 | |||
1949 | budget = MAX_TIMER_TX_RECLAIM; | ||
1950 | i = s->ethtxq_rover; | ||
1951 | do { | ||
1952 | struct sge_eth_txq *q = &s->ethtxq[i]; | ||
1953 | |||
1954 | if (q->q.in_use && | ||
1955 | time_after_eq(jiffies, q->txq->trans_start + HZ / 100) && | ||
1956 | __netif_tx_trylock(q->txq)) { | ||
1957 | int avail = reclaimable(&q->q); | ||
1958 | |||
1959 | if (avail) { | ||
1960 | if (avail > budget) | ||
1961 | avail = budget; | ||
1962 | |||
1963 | free_tx_desc(adap, &q->q, avail, true); | ||
1964 | q->q.in_use -= avail; | ||
1965 | budget -= avail; | ||
1966 | } | ||
1967 | __netif_tx_unlock(q->txq); | ||
1968 | } | ||
1969 | |||
1970 | if (++i >= s->ethqsets) | ||
1971 | i = 0; | ||
1972 | } while (budget && i != s->ethtxq_rover); | ||
1973 | s->ethtxq_rover = i; | ||
1974 | mod_timer(&s->tx_timer, jiffies + (budget ? TX_QCHECK_PERIOD : 2)); | ||
1975 | } | ||
1976 | |||
1977 | int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, | ||
1978 | struct net_device *dev, int intr_idx, | ||
1979 | struct sge_fl *fl, rspq_handler_t hnd) | ||
1980 | { | ||
1981 | int ret, flsz = 0; | ||
1982 | struct fw_iq_cmd c; | ||
1983 | struct port_info *pi = netdev_priv(dev); | ||
1984 | |||
1985 | /* Size needs to be multiple of 16, including status entry. */ | ||
1986 | iq->size = roundup(iq->size, 16); | ||
1987 | |||
1988 | iq->desc = alloc_ring(adap->pdev_dev, iq->size, iq->iqe_len, 0, | ||
1989 | &iq->phys_addr, NULL, 0); | ||
1990 | if (!iq->desc) | ||
1991 | return -ENOMEM; | ||
1992 | |||
1993 | memset(&c, 0, sizeof(c)); | ||
1994 | c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST | | ||
1995 | FW_CMD_WRITE | FW_CMD_EXEC | | ||
1996 | FW_IQ_CMD_PFN(0) | FW_IQ_CMD_VFN(0)); | ||
1997 | c.alloc_to_len16 = htonl(FW_IQ_CMD_ALLOC | FW_IQ_CMD_IQSTART(1) | | ||
1998 | FW_LEN16(c)); | ||
1999 | c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(FW_IQ_TYPE_FL_INT_CAP) | | ||
2000 | FW_IQ_CMD_IQASYNCH(fwevtq) | FW_IQ_CMD_VIID(pi->viid) | | ||
2001 | FW_IQ_CMD_IQANDST(intr_idx < 0) | FW_IQ_CMD_IQANUD(1) | | ||
2002 | FW_IQ_CMD_IQANDSTINDEX(intr_idx >= 0 ? intr_idx : | ||
2003 | -intr_idx - 1)); | ||
2004 | c.iqdroprss_to_iqesize = htons(FW_IQ_CMD_IQPCIECH(pi->tx_chan) | | ||
2005 | FW_IQ_CMD_IQGTSMODE | | ||
2006 | FW_IQ_CMD_IQINTCNTTHRESH(iq->pktcnt_idx) | | ||
2007 | FW_IQ_CMD_IQESIZE(ilog2(iq->iqe_len) - 4)); | ||
2008 | c.iqsize = htons(iq->size); | ||
2009 | c.iqaddr = cpu_to_be64(iq->phys_addr); | ||
2010 | |||
2011 | if (fl) { | ||
2012 | fl->size = roundup(fl->size, 8); | ||
2013 | fl->desc = alloc_ring(adap->pdev_dev, fl->size, sizeof(__be64), | ||
2014 | sizeof(struct rx_sw_desc), &fl->addr, | ||
2015 | &fl->sdesc, STAT_LEN); | ||
2016 | if (!fl->desc) | ||
2017 | goto fl_nomem; | ||
2018 | |||
2019 | flsz = fl->size / 8 + STAT_LEN / sizeof(struct tx_desc); | ||
2020 | c.iqns_to_fl0congen = htonl(FW_IQ_CMD_FL0PACKEN | | ||
2021 | FW_IQ_CMD_FL0PADEN); | ||
2022 | c.fl0dcaen_to_fl0cidxfthresh = htons(FW_IQ_CMD_FL0FBMIN(2) | | ||
2023 | FW_IQ_CMD_FL0FBMAX(3)); | ||
2024 | c.fl0size = htons(flsz); | ||
2025 | c.fl0addr = cpu_to_be64(fl->addr); | ||
2026 | } | ||
2027 | |||
2028 | ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c); | ||
2029 | if (ret) | ||
2030 | goto err; | ||
2031 | |||
2032 | netif_napi_add(dev, &iq->napi, napi_rx_handler, 64); | ||
2033 | iq->cur_desc = iq->desc; | ||
2034 | iq->cidx = 0; | ||
2035 | iq->gen = 1; | ||
2036 | iq->next_intr_params = iq->intr_params; | ||
2037 | iq->cntxt_id = ntohs(c.iqid); | ||
2038 | iq->abs_id = ntohs(c.physiqid); | ||
2039 | iq->size--; /* subtract status entry */ | ||
2040 | iq->adap = adap; | ||
2041 | iq->netdev = dev; | ||
2042 | iq->handler = hnd; | ||
2043 | |||
2044 | /* set offset to -1 to distinguish ingress queues without FL */ | ||
2045 | iq->offset = fl ? 0 : -1; | ||
2046 | |||
2047 | adap->sge.ingr_map[iq->cntxt_id] = iq; | ||
2048 | |||
2049 | if (fl) { | ||
2050 | fl->cntxt_id = htons(c.fl0id); | ||
2051 | fl->avail = fl->pend_cred = 0; | ||
2052 | fl->pidx = fl->cidx = 0; | ||
2053 | fl->alloc_failed = fl->large_alloc_failed = fl->starving = 0; | ||
2054 | adap->sge.egr_map[fl->cntxt_id] = fl; | ||
2055 | refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL); | ||
2056 | } | ||
2057 | return 0; | ||
2058 | |||
2059 | fl_nomem: | ||
2060 | ret = -ENOMEM; | ||
2061 | err: | ||
2062 | if (iq->desc) { | ||
2063 | dma_free_coherent(adap->pdev_dev, iq->size * iq->iqe_len, | ||
2064 | iq->desc, iq->phys_addr); | ||
2065 | iq->desc = NULL; | ||
2066 | } | ||
2067 | if (fl && fl->desc) { | ||
2068 | kfree(fl->sdesc); | ||
2069 | fl->sdesc = NULL; | ||
2070 | dma_free_coherent(adap->pdev_dev, flsz * sizeof(struct tx_desc), | ||
2071 | fl->desc, fl->addr); | ||
2072 | fl->desc = NULL; | ||
2073 | } | ||
2074 | return ret; | ||
2075 | } | ||
2076 | |||
2077 | static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id) | ||
2078 | { | ||
2079 | q->in_use = 0; | ||
2080 | q->cidx = q->pidx = 0; | ||
2081 | q->stops = q->restarts = 0; | ||
2082 | q->stat = (void *)&q->desc[q->size]; | ||
2083 | q->cntxt_id = id; | ||
2084 | adap->sge.egr_map[id] = q; | ||
2085 | } | ||
2086 | |||
2087 | int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, | ||
2088 | struct net_device *dev, struct netdev_queue *netdevq, | ||
2089 | unsigned int iqid) | ||
2090 | { | ||
2091 | int ret, nentries; | ||
2092 | struct fw_eq_eth_cmd c; | ||
2093 | struct port_info *pi = netdev_priv(dev); | ||
2094 | |||
2095 | /* Add status entries */ | ||
2096 | nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc); | ||
2097 | |||
2098 | txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size, | ||
2099 | sizeof(struct tx_desc), sizeof(struct tx_sw_desc), | ||
2100 | &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN); | ||
2101 | if (!txq->q.desc) | ||
2102 | return -ENOMEM; | ||
2103 | |||
2104 | memset(&c, 0, sizeof(c)); | ||
2105 | c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_ETH_CMD) | FW_CMD_REQUEST | | ||
2106 | FW_CMD_WRITE | FW_CMD_EXEC | | ||
2107 | FW_EQ_ETH_CMD_PFN(0) | FW_EQ_ETH_CMD_VFN(0)); | ||
2108 | c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_ALLOC | | ||
2109 | FW_EQ_ETH_CMD_EQSTART | FW_LEN16(c)); | ||
2110 | c.viid_pkd = htonl(FW_EQ_ETH_CMD_VIID(pi->viid)); | ||
2111 | c.fetchszm_to_iqid = htonl(FW_EQ_ETH_CMD_HOSTFCMODE(2) | | ||
2112 | FW_EQ_ETH_CMD_PCIECHN(pi->tx_chan) | | ||
2113 | FW_EQ_ETH_CMD_IQID(iqid)); | ||
2114 | c.dcaen_to_eqsize = htonl(FW_EQ_ETH_CMD_FBMIN(2) | | ||
2115 | FW_EQ_ETH_CMD_FBMAX(3) | | ||
2116 | FW_EQ_ETH_CMD_CIDXFTHRESH(5) | | ||
2117 | FW_EQ_ETH_CMD_EQSIZE(nentries)); | ||
2118 | c.eqaddr = cpu_to_be64(txq->q.phys_addr); | ||
2119 | |||
2120 | ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c); | ||
2121 | if (ret) { | ||
2122 | kfree(txq->q.sdesc); | ||
2123 | txq->q.sdesc = NULL; | ||
2124 | dma_free_coherent(adap->pdev_dev, | ||
2125 | nentries * sizeof(struct tx_desc), | ||
2126 | txq->q.desc, txq->q.phys_addr); | ||
2127 | txq->q.desc = NULL; | ||
2128 | return ret; | ||
2129 | } | ||
2130 | |||
2131 | init_txq(adap, &txq->q, FW_EQ_ETH_CMD_EQID_GET(ntohl(c.eqid_pkd))); | ||
2132 | txq->txq = netdevq; | ||
2133 | txq->tso = txq->tx_cso = txq->vlan_ins = 0; | ||
2134 | txq->mapping_err = 0; | ||
2135 | return 0; | ||
2136 | } | ||
2137 | |||
2138 | int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq, | ||
2139 | struct net_device *dev, unsigned int iqid, | ||
2140 | unsigned int cmplqid) | ||
2141 | { | ||
2142 | int ret, nentries; | ||
2143 | struct fw_eq_ctrl_cmd c; | ||
2144 | struct port_info *pi = netdev_priv(dev); | ||
2145 | |||
2146 | /* Add status entries */ | ||
2147 | nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc); | ||
2148 | |||
2149 | txq->q.desc = alloc_ring(adap->pdev_dev, nentries, | ||
2150 | sizeof(struct tx_desc), 0, &txq->q.phys_addr, | ||
2151 | NULL, 0); | ||
2152 | if (!txq->q.desc) | ||
2153 | return -ENOMEM; | ||
2154 | |||
2155 | c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST | | ||
2156 | FW_CMD_WRITE | FW_CMD_EXEC | | ||
2157 | FW_EQ_CTRL_CMD_PFN(0) | FW_EQ_CTRL_CMD_VFN(0)); | ||
2158 | c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_ALLOC | | ||
2159 | FW_EQ_CTRL_CMD_EQSTART | FW_LEN16(c)); | ||
2160 | c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_CMPLIQID(cmplqid)); | ||
2161 | c.physeqid_pkd = htonl(0); | ||
2162 | c.fetchszm_to_iqid = htonl(FW_EQ_CTRL_CMD_HOSTFCMODE(2) | | ||
2163 | FW_EQ_CTRL_CMD_PCIECHN(pi->tx_chan) | | ||
2164 | FW_EQ_CTRL_CMD_IQID(iqid)); | ||
2165 | c.dcaen_to_eqsize = htonl(FW_EQ_CTRL_CMD_FBMIN(2) | | ||
2166 | FW_EQ_CTRL_CMD_FBMAX(3) | | ||
2167 | FW_EQ_CTRL_CMD_CIDXFTHRESH(5) | | ||
2168 | FW_EQ_CTRL_CMD_EQSIZE(nentries)); | ||
2169 | c.eqaddr = cpu_to_be64(txq->q.phys_addr); | ||
2170 | |||
2171 | ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c); | ||
2172 | if (ret) { | ||
2173 | dma_free_coherent(adap->pdev_dev, | ||
2174 | nentries * sizeof(struct tx_desc), | ||
2175 | txq->q.desc, txq->q.phys_addr); | ||
2176 | txq->q.desc = NULL; | ||
2177 | return ret; | ||
2178 | } | ||
2179 | |||
2180 | init_txq(adap, &txq->q, FW_EQ_CTRL_CMD_EQID_GET(ntohl(c.cmpliqid_eqid))); | ||
2181 | txq->adap = adap; | ||
2182 | skb_queue_head_init(&txq->sendq); | ||
2183 | tasklet_init(&txq->qresume_tsk, restart_ctrlq, (unsigned long)txq); | ||
2184 | txq->full = 0; | ||
2185 | return 0; | ||
2186 | } | ||
2187 | |||
2188 | int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_ofld_txq *txq, | ||
2189 | struct net_device *dev, unsigned int iqid) | ||
2190 | { | ||
2191 | int ret, nentries; | ||
2192 | struct fw_eq_ofld_cmd c; | ||
2193 | struct port_info *pi = netdev_priv(dev); | ||
2194 | |||
2195 | /* Add status entries */ | ||
2196 | nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc); | ||
2197 | |||
2198 | txq->q.desc = alloc_ring(adap->pdev_dev, txq->q.size, | ||
2199 | sizeof(struct tx_desc), sizeof(struct tx_sw_desc), | ||
2200 | &txq->q.phys_addr, &txq->q.sdesc, STAT_LEN); | ||
2201 | if (!txq->q.desc) | ||
2202 | return -ENOMEM; | ||
2203 | |||
2204 | memset(&c, 0, sizeof(c)); | ||
2205 | c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST | | ||
2206 | FW_CMD_WRITE | FW_CMD_EXEC | | ||
2207 | FW_EQ_OFLD_CMD_PFN(0) | FW_EQ_OFLD_CMD_VFN(0)); | ||
2208 | c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_ALLOC | | ||
2209 | FW_EQ_OFLD_CMD_EQSTART | FW_LEN16(c)); | ||
2210 | c.fetchszm_to_iqid = htonl(FW_EQ_OFLD_CMD_HOSTFCMODE(2) | | ||
2211 | FW_EQ_OFLD_CMD_PCIECHN(pi->tx_chan) | | ||
2212 | FW_EQ_OFLD_CMD_IQID(iqid)); | ||
2213 | c.dcaen_to_eqsize = htonl(FW_EQ_OFLD_CMD_FBMIN(2) | | ||
2214 | FW_EQ_OFLD_CMD_FBMAX(3) | | ||
2215 | FW_EQ_OFLD_CMD_CIDXFTHRESH(5) | | ||
2216 | FW_EQ_OFLD_CMD_EQSIZE(nentries)); | ||
2217 | c.eqaddr = cpu_to_be64(txq->q.phys_addr); | ||
2218 | |||
2219 | ret = t4_wr_mbox(adap, 0, &c, sizeof(c), &c); | ||
2220 | if (ret) { | ||
2221 | kfree(txq->q.sdesc); | ||
2222 | txq->q.sdesc = NULL; | ||
2223 | dma_free_coherent(adap->pdev_dev, | ||
2224 | nentries * sizeof(struct tx_desc), | ||
2225 | txq->q.desc, txq->q.phys_addr); | ||
2226 | txq->q.desc = NULL; | ||
2227 | return ret; | ||
2228 | } | ||
2229 | |||
2230 | init_txq(adap, &txq->q, FW_EQ_OFLD_CMD_EQID_GET(ntohl(c.eqid_pkd))); | ||
2231 | txq->adap = adap; | ||
2232 | skb_queue_head_init(&txq->sendq); | ||
2233 | tasklet_init(&txq->qresume_tsk, restart_ofldq, (unsigned long)txq); | ||
2234 | txq->full = 0; | ||
2235 | txq->mapping_err = 0; | ||
2236 | return 0; | ||
2237 | } | ||
2238 | |||
2239 | static void free_txq(struct adapter *adap, struct sge_txq *q) | ||
2240 | { | ||
2241 | dma_free_coherent(adap->pdev_dev, | ||
2242 | q->size * sizeof(struct tx_desc) + STAT_LEN, | ||
2243 | q->desc, q->phys_addr); | ||
2244 | q->cntxt_id = 0; | ||
2245 | q->sdesc = NULL; | ||
2246 | q->desc = NULL; | ||
2247 | } | ||
2248 | |||
2249 | static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, | ||
2250 | struct sge_fl *fl) | ||
2251 | { | ||
2252 | unsigned int fl_id = fl ? fl->cntxt_id : 0xffff; | ||
2253 | |||
2254 | adap->sge.ingr_map[rq->cntxt_id] = NULL; | ||
2255 | t4_iq_free(adap, 0, 0, 0, FW_IQ_TYPE_FL_INT_CAP, rq->cntxt_id, fl_id, | ||
2256 | 0xffff); | ||
2257 | dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len, | ||
2258 | rq->desc, rq->phys_addr); | ||
2259 | netif_napi_del(&rq->napi); | ||
2260 | rq->netdev = NULL; | ||
2261 | rq->cntxt_id = rq->abs_id = 0; | ||
2262 | rq->desc = NULL; | ||
2263 | |||
2264 | if (fl) { | ||
2265 | free_rx_bufs(adap, fl, fl->avail); | ||
2266 | dma_free_coherent(adap->pdev_dev, fl->size * 8 + STAT_LEN, | ||
2267 | fl->desc, fl->addr); | ||
2268 | kfree(fl->sdesc); | ||
2269 | fl->sdesc = NULL; | ||
2270 | fl->cntxt_id = 0; | ||
2271 | fl->desc = NULL; | ||
2272 | } | ||
2273 | } | ||
2274 | |||
2275 | /** | ||
2276 | * t4_free_sge_resources - free SGE resources | ||
2277 | * @adap: the adapter | ||
2278 | * | ||
2279 | * Frees resources used by the SGE queue sets. | ||
2280 | */ | ||
2281 | void t4_free_sge_resources(struct adapter *adap) | ||
2282 | { | ||
2283 | int i; | ||
2284 | struct sge_eth_rxq *eq = adap->sge.ethrxq; | ||
2285 | struct sge_eth_txq *etq = adap->sge.ethtxq; | ||
2286 | struct sge_ofld_rxq *oq = adap->sge.ofldrxq; | ||
2287 | |||
2288 | /* clean up Ethernet Tx/Rx queues */ | ||
2289 | for (i = 0; i < adap->sge.ethqsets; i++, eq++, etq++) { | ||
2290 | if (eq->rspq.desc) | ||
2291 | free_rspq_fl(adap, &eq->rspq, &eq->fl); | ||
2292 | if (etq->q.desc) { | ||
2293 | t4_eth_eq_free(adap, 0, 0, 0, etq->q.cntxt_id); | ||
2294 | free_tx_desc(adap, &etq->q, etq->q.in_use, true); | ||
2295 | kfree(etq->q.sdesc); | ||
2296 | free_txq(adap, &etq->q); | ||
2297 | } | ||
2298 | } | ||
2299 | |||
2300 | /* clean up RDMA and iSCSI Rx queues */ | ||
2301 | for (i = 0; i < adap->sge.ofldqsets; i++, oq++) { | ||
2302 | if (oq->rspq.desc) | ||
2303 | free_rspq_fl(adap, &oq->rspq, &oq->fl); | ||
2304 | } | ||
2305 | for (i = 0, oq = adap->sge.rdmarxq; i < adap->sge.rdmaqs; i++, oq++) { | ||
2306 | if (oq->rspq.desc) | ||
2307 | free_rspq_fl(adap, &oq->rspq, &oq->fl); | ||
2308 | } | ||
2309 | |||
2310 | /* clean up offload Tx queues */ | ||
2311 | for (i = 0; i < ARRAY_SIZE(adap->sge.ofldtxq); i++) { | ||
2312 | struct sge_ofld_txq *q = &adap->sge.ofldtxq[i]; | ||
2313 | |||
2314 | if (q->q.desc) { | ||
2315 | tasklet_kill(&q->qresume_tsk); | ||
2316 | t4_ofld_eq_free(adap, 0, 0, 0, q->q.cntxt_id); | ||
2317 | free_tx_desc(adap, &q->q, q->q.in_use, false); | ||
2318 | kfree(q->q.sdesc); | ||
2319 | __skb_queue_purge(&q->sendq); | ||
2320 | free_txq(adap, &q->q); | ||
2321 | } | ||
2322 | } | ||
2323 | |||
2324 | /* clean up control Tx queues */ | ||
2325 | for (i = 0; i < ARRAY_SIZE(adap->sge.ctrlq); i++) { | ||
2326 | struct sge_ctrl_txq *cq = &adap->sge.ctrlq[i]; | ||
2327 | |||
2328 | if (cq->q.desc) { | ||
2329 | tasklet_kill(&cq->qresume_tsk); | ||
2330 | t4_ctrl_eq_free(adap, 0, 0, 0, cq->q.cntxt_id); | ||
2331 | __skb_queue_purge(&cq->sendq); | ||
2332 | free_txq(adap, &cq->q); | ||
2333 | } | ||
2334 | } | ||
2335 | |||
2336 | if (adap->sge.fw_evtq.desc) | ||
2337 | free_rspq_fl(adap, &adap->sge.fw_evtq, NULL); | ||
2338 | |||
2339 | if (adap->sge.intrq.desc) | ||
2340 | free_rspq_fl(adap, &adap->sge.intrq, NULL); | ||
2341 | |||
2342 | /* clear the reverse egress queue map */ | ||
2343 | memset(adap->sge.egr_map, 0, sizeof(adap->sge.egr_map)); | ||
2344 | } | ||
2345 | |||
2346 | void t4_sge_start(struct adapter *adap) | ||
2347 | { | ||
2348 | adap->sge.ethtxq_rover = 0; | ||
2349 | mod_timer(&adap->sge.rx_timer, jiffies + RX_QCHECK_PERIOD); | ||
2350 | mod_timer(&adap->sge.tx_timer, jiffies + TX_QCHECK_PERIOD); | ||
2351 | } | ||
2352 | |||
2353 | /** | ||
2354 | * t4_sge_stop - disable SGE operation | ||
2355 | * @adap: the adapter | ||
2356 | * | ||
2357 | * Stop tasklets and timers associated with the DMA engine. Note that | ||
2358 | * this is effective only if measures have been taken to disable any HW | ||
2359 | * events that may restart them. | ||
2360 | */ | ||
2361 | void t4_sge_stop(struct adapter *adap) | ||
2362 | { | ||
2363 | int i; | ||
2364 | struct sge *s = &adap->sge; | ||
2365 | |||
2366 | if (in_interrupt()) /* actions below require waiting */ | ||
2367 | return; | ||
2368 | |||
2369 | if (s->rx_timer.function) | ||
2370 | del_timer_sync(&s->rx_timer); | ||
2371 | if (s->tx_timer.function) | ||
2372 | del_timer_sync(&s->tx_timer); | ||
2373 | |||
2374 | for (i = 0; i < ARRAY_SIZE(s->ofldtxq); i++) { | ||
2375 | struct sge_ofld_txq *q = &s->ofldtxq[i]; | ||
2376 | |||
2377 | if (q->q.desc) | ||
2378 | tasklet_kill(&q->qresume_tsk); | ||
2379 | } | ||
2380 | for (i = 0; i < ARRAY_SIZE(s->ctrlq); i++) { | ||
2381 | struct sge_ctrl_txq *cq = &s->ctrlq[i]; | ||
2382 | |||
2383 | if (cq->q.desc) | ||
2384 | tasklet_kill(&cq->qresume_tsk); | ||
2385 | } | ||
2386 | } | ||
2387 | |||
2388 | /** | ||
2389 | * t4_sge_init - initialize SGE | ||
2390 | * @adap: the adapter | ||
2391 | * | ||
2392 | * Performs SGE initialization needed every time after a chip reset. | ||
2393 | * We do not initialize any of the queues here, instead the driver | ||
2394 | * top-level must request them individually. | ||
2395 | */ | ||
2396 | void t4_sge_init(struct adapter *adap) | ||
2397 | { | ||
2398 | struct sge *s = &adap->sge; | ||
2399 | unsigned int fl_align_log = ilog2(FL_ALIGN); | ||
2400 | |||
2401 | t4_set_reg_field(adap, SGE_CONTROL, PKTSHIFT_MASK | | ||
2402 | INGPADBOUNDARY_MASK | EGRSTATUSPAGESIZE, | ||
2403 | INGPADBOUNDARY(fl_align_log - 5) | PKTSHIFT(2) | | ||
2404 | RXPKTCPLMODE | | ||
2405 | (STAT_LEN == 128 ? EGRSTATUSPAGESIZE : 0)); | ||
2406 | t4_set_reg_field(adap, SGE_HOST_PAGE_SIZE, HOSTPAGESIZEPF0_MASK, | ||
2407 | HOSTPAGESIZEPF0(PAGE_SHIFT - 10)); | ||
2408 | t4_write_reg(adap, SGE_FL_BUFFER_SIZE0, PAGE_SIZE); | ||
2409 | #if FL_PG_ORDER > 0 | ||
2410 | t4_write_reg(adap, SGE_FL_BUFFER_SIZE1, PAGE_SIZE << FL_PG_ORDER); | ||
2411 | #endif | ||
2412 | t4_write_reg(adap, SGE_INGRESS_RX_THRESHOLD, | ||
2413 | THRESHOLD_0(s->counter_val[0]) | | ||
2414 | THRESHOLD_1(s->counter_val[1]) | | ||
2415 | THRESHOLD_2(s->counter_val[2]) | | ||
2416 | THRESHOLD_3(s->counter_val[3])); | ||
2417 | t4_write_reg(adap, SGE_TIMER_VALUE_0_AND_1, | ||
2418 | TIMERVALUE0(us_to_core_ticks(adap, s->timer_val[0])) | | ||
2419 | TIMERVALUE1(us_to_core_ticks(adap, s->timer_val[1]))); | ||
2420 | t4_write_reg(adap, SGE_TIMER_VALUE_2_AND_3, | ||
2421 | TIMERVALUE0(us_to_core_ticks(adap, s->timer_val[2])) | | ||
2422 | TIMERVALUE1(us_to_core_ticks(adap, s->timer_val[3]))); | ||
2423 | t4_write_reg(adap, SGE_TIMER_VALUE_4_AND_5, | ||
2424 | TIMERVALUE0(us_to_core_ticks(adap, s->timer_val[4])) | | ||
2425 | TIMERVALUE1(us_to_core_ticks(adap, s->timer_val[5]))); | ||
2426 | setup_timer(&s->rx_timer, sge_rx_timer_cb, (unsigned long)adap); | ||
2427 | setup_timer(&s->tx_timer, sge_tx_timer_cb, (unsigned long)adap); | ||
2428 | s->starve_thres = core_ticks_per_usec(adap) * 1000000; /* 1 s */ | ||
2429 | s->idma_state[0] = s->idma_state[1] = 0; | ||
2430 | spin_lock_init(&s->intrq_lock); | ||
2431 | } | ||
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c new file mode 100644 index 000000000000..a814a3afe123 --- /dev/null +++ b/drivers/net/cxgb4/t4_hw.c | |||
@@ -0,0 +1,3131 @@ | |||
1 | /* | ||
2 | * This file is part of the Chelsio T4 Ethernet driver for Linux. | ||
3 | * | ||
4 | * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved. | ||
5 | * | ||
6 | * This software is available to you under a choice of one of two | ||
7 | * licenses. You may choose to be licensed under the terms of the GNU | ||
8 | * General Public License (GPL) Version 2, available from the file | ||
9 | * COPYING in the main directory of this source tree, or the | ||
10 | * OpenIB.org BSD license below: | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or | ||
13 | * without modification, are permitted provided that the following | ||
14 | * conditions are met: | ||
15 | * | ||
16 | * - Redistributions of source code must retain the above | ||
17 | * copyright notice, this list of conditions and the following | ||
18 | * disclaimer. | ||
19 | * | ||
20 | * - Redistributions in binary form must reproduce the above | ||
21 | * copyright notice, this list of conditions and the following | ||
22 | * disclaimer in the documentation and/or other materials | ||
23 | * provided with the distribution. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
32 | * SOFTWARE. | ||
33 | */ | ||
34 | |||
35 | #include <linux/init.h> | ||
36 | #include <linux/delay.h> | ||
37 | #include "cxgb4.h" | ||
38 | #include "t4_regs.h" | ||
39 | #include "t4fw_api.h" | ||
40 | |||
41 | /** | ||
42 | * t4_wait_op_done_val - wait until an operation is completed | ||
43 | * @adapter: the adapter performing the operation | ||
44 | * @reg: the register to check for completion | ||
45 | * @mask: a single-bit field within @reg that indicates completion | ||
46 | * @polarity: the value of the field when the operation is completed | ||
47 | * @attempts: number of check iterations | ||
48 | * @delay: delay in usecs between iterations | ||
49 | * @valp: where to store the value of the register at completion time | ||
50 | * | ||
51 | * Wait until an operation is completed by checking a bit in a register | ||
52 | * up to @attempts times. If @valp is not NULL the value of the register | ||
53 | * at the time it indicated completion is stored there. Returns 0 if the | ||
54 | * operation completes and -EAGAIN otherwise. | ||
55 | */ | ||
56 | int t4_wait_op_done_val(struct adapter *adapter, int reg, u32 mask, | ||
57 | int polarity, int attempts, int delay, u32 *valp) | ||
58 | { | ||
59 | while (1) { | ||
60 | u32 val = t4_read_reg(adapter, reg); | ||
61 | |||
62 | if (!!(val & mask) == polarity) { | ||
63 | if (valp) | ||
64 | *valp = val; | ||
65 | return 0; | ||
66 | } | ||
67 | if (--attempts == 0) | ||
68 | return -EAGAIN; | ||
69 | if (delay) | ||
70 | udelay(delay); | ||
71 | } | ||
72 | } | ||
73 | |||
74 | static inline int t4_wait_op_done(struct adapter *adapter, int reg, u32 mask, | ||
75 | int polarity, int attempts, int delay) | ||
76 | { | ||
77 | return t4_wait_op_done_val(adapter, reg, mask, polarity, attempts, | ||
78 | delay, NULL); | ||
79 | } | ||
80 | |||
81 | /** | ||
82 | * t4_set_reg_field - set a register field to a value | ||
83 | * @adapter: the adapter to program | ||
84 | * @addr: the register address | ||
85 | * @mask: specifies the portion of the register to modify | ||
86 | * @val: the new value for the register field | ||
87 | * | ||
88 | * Sets a register field specified by the supplied mask to the | ||
89 | * given value. | ||
90 | */ | ||
91 | void t4_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask, | ||
92 | u32 val) | ||
93 | { | ||
94 | u32 v = t4_read_reg(adapter, addr) & ~mask; | ||
95 | |||
96 | t4_write_reg(adapter, addr, v | val); | ||
97 | (void) t4_read_reg(adapter, addr); /* flush */ | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * t4_read_indirect - read indirectly addressed registers | ||
102 | * @adap: the adapter | ||
103 | * @addr_reg: register holding the indirect address | ||
104 | * @data_reg: register holding the value of the indirect register | ||
105 | * @vals: where the read register values are stored | ||
106 | * @nregs: how many indirect registers to read | ||
107 | * @start_idx: index of first indirect register to read | ||
108 | * | ||
109 | * Reads registers that are accessed indirectly through an address/data | ||
110 | * register pair. | ||
111 | */ | ||
112 | void t4_read_indirect(struct adapter *adap, unsigned int addr_reg, | ||
113 | unsigned int data_reg, u32 *vals, unsigned int nregs, | ||
114 | unsigned int start_idx) | ||
115 | { | ||
116 | while (nregs--) { | ||
117 | t4_write_reg(adap, addr_reg, start_idx); | ||
118 | *vals++ = t4_read_reg(adap, data_reg); | ||
119 | start_idx++; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * t4_write_indirect - write indirectly addressed registers | ||
125 | * @adap: the adapter | ||
126 | * @addr_reg: register holding the indirect addresses | ||
127 | * @data_reg: register holding the value for the indirect registers | ||
128 | * @vals: values to write | ||
129 | * @nregs: how many indirect registers to write | ||
130 | * @start_idx: address of first indirect register to write | ||
131 | * | ||
132 | * Writes a sequential block of registers that are accessed indirectly | ||
133 | * through an address/data register pair. | ||
134 | */ | ||
135 | void t4_write_indirect(struct adapter *adap, unsigned int addr_reg, | ||
136 | unsigned int data_reg, const u32 *vals, | ||
137 | unsigned int nregs, unsigned int start_idx) | ||
138 | { | ||
139 | while (nregs--) { | ||
140 | t4_write_reg(adap, addr_reg, start_idx++); | ||
141 | t4_write_reg(adap, data_reg, *vals++); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Get the reply to a mailbox command and store it in @rpl in big-endian order. | ||
147 | */ | ||
148 | static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit, | ||
149 | u32 mbox_addr) | ||
150 | { | ||
151 | for ( ; nflit; nflit--, mbox_addr += 8) | ||
152 | *rpl++ = cpu_to_be64(t4_read_reg64(adap, mbox_addr)); | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * Handle a FW assertion reported in a mailbox. | ||
157 | */ | ||
158 | static void fw_asrt(struct adapter *adap, u32 mbox_addr) | ||
159 | { | ||
160 | struct fw_debug_cmd asrt; | ||
161 | |||
162 | get_mbox_rpl(adap, (__be64 *)&asrt, sizeof(asrt) / 8, mbox_addr); | ||
163 | dev_alert(adap->pdev_dev, | ||
164 | "FW assertion at %.16s:%u, val0 %#x, val1 %#x\n", | ||
165 | asrt.u.assert.filename_0_7, ntohl(asrt.u.assert.line), | ||
166 | ntohl(asrt.u.assert.x), ntohl(asrt.u.assert.y)); | ||
167 | } | ||
168 | |||
169 | static void dump_mbox(struct adapter *adap, int mbox, u32 data_reg) | ||
170 | { | ||
171 | dev_err(adap->pdev_dev, | ||
172 | "mbox %d: %llx %llx %llx %llx %llx %llx %llx %llx\n", mbox, | ||
173 | (unsigned long long)t4_read_reg64(adap, data_reg), | ||
174 | (unsigned long long)t4_read_reg64(adap, data_reg + 8), | ||
175 | (unsigned long long)t4_read_reg64(adap, data_reg + 16), | ||
176 | (unsigned long long)t4_read_reg64(adap, data_reg + 24), | ||
177 | (unsigned long long)t4_read_reg64(adap, data_reg + 32), | ||
178 | (unsigned long long)t4_read_reg64(adap, data_reg + 40), | ||
179 | (unsigned long long)t4_read_reg64(adap, data_reg + 48), | ||
180 | (unsigned long long)t4_read_reg64(adap, data_reg + 56)); | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * t4_wr_mbox_meat - send a command to FW through the given mailbox | ||
185 | * @adap: the adapter | ||
186 | * @mbox: index of the mailbox to use | ||
187 | * @cmd: the command to write | ||
188 | * @size: command length in bytes | ||
189 | * @rpl: where to optionally store the reply | ||
190 | * @sleep_ok: if true we may sleep while awaiting command completion | ||
191 | * | ||
192 | * Sends the given command to FW through the selected mailbox and waits | ||
193 | * for the FW to execute the command. If @rpl is not %NULL it is used to | ||
194 | * store the FW's reply to the command. The command and its optional | ||
195 | * reply are of the same length. FW can take up to %FW_CMD_MAX_TIMEOUT ms | ||
196 | * to respond. @sleep_ok determines whether we may sleep while awaiting | ||
197 | * the response. If sleeping is allowed we use progressive backoff | ||
198 | * otherwise we spin. | ||
199 | * | ||
200 | * The return value is 0 on success or a negative errno on failure. A | ||
201 | * failure can happen either because we are not able to execute the | ||
202 | * command or FW executes it but signals an error. In the latter case | ||
203 | * the return value is the error code indicated by FW (negated). | ||
204 | */ | ||
205 | int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, | ||
206 | void *rpl, bool sleep_ok) | ||
207 | { | ||
208 | static int delay[] = { | ||
209 | 1, 1, 3, 5, 10, 10, 20, 50, 100, 200 | ||
210 | }; | ||
211 | |||
212 | u32 v; | ||
213 | u64 res; | ||
214 | int i, ms, delay_idx; | ||
215 | const __be64 *p = cmd; | ||
216 | u32 data_reg = PF_REG(mbox, CIM_PF_MAILBOX_DATA); | ||
217 | u32 ctl_reg = PF_REG(mbox, CIM_PF_MAILBOX_CTRL); | ||
218 | |||
219 | if ((size & 15) || size > MBOX_LEN) | ||
220 | return -EINVAL; | ||
221 | |||
222 | v = MBOWNER_GET(t4_read_reg(adap, ctl_reg)); | ||
223 | for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++) | ||
224 | v = MBOWNER_GET(t4_read_reg(adap, ctl_reg)); | ||
225 | |||
226 | if (v != MBOX_OWNER_DRV) | ||
227 | return v ? -EBUSY : -ETIMEDOUT; | ||
228 | |||
229 | for (i = 0; i < size; i += 8) | ||
230 | t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p++)); | ||
231 | |||
232 | t4_write_reg(adap, ctl_reg, MBMSGVALID | MBOWNER(MBOX_OWNER_FW)); | ||
233 | t4_read_reg(adap, ctl_reg); /* flush write */ | ||
234 | |||
235 | delay_idx = 0; | ||
236 | ms = delay[0]; | ||
237 | |||
238 | for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) { | ||
239 | if (sleep_ok) { | ||
240 | ms = delay[delay_idx]; /* last element may repeat */ | ||
241 | if (delay_idx < ARRAY_SIZE(delay) - 1) | ||
242 | delay_idx++; | ||
243 | msleep(ms); | ||
244 | } else | ||
245 | mdelay(ms); | ||
246 | |||
247 | v = t4_read_reg(adap, ctl_reg); | ||
248 | if (MBOWNER_GET(v) == MBOX_OWNER_DRV) { | ||
249 | if (!(v & MBMSGVALID)) { | ||
250 | t4_write_reg(adap, ctl_reg, 0); | ||
251 | continue; | ||
252 | } | ||
253 | |||
254 | res = t4_read_reg64(adap, data_reg); | ||
255 | if (FW_CMD_OP_GET(res >> 32) == FW_DEBUG_CMD) { | ||
256 | fw_asrt(adap, data_reg); | ||
257 | res = FW_CMD_RETVAL(EIO); | ||
258 | } else if (rpl) | ||
259 | get_mbox_rpl(adap, rpl, size / 8, data_reg); | ||
260 | |||
261 | if (FW_CMD_RETVAL_GET((int)res)) | ||
262 | dump_mbox(adap, mbox, data_reg); | ||
263 | t4_write_reg(adap, ctl_reg, 0); | ||
264 | return -FW_CMD_RETVAL_GET((int)res); | ||
265 | } | ||
266 | } | ||
267 | |||
268 | dump_mbox(adap, mbox, data_reg); | ||
269 | dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n", | ||
270 | *(const u8 *)cmd, mbox); | ||
271 | return -ETIMEDOUT; | ||
272 | } | ||
273 | |||
274 | /** | ||
275 | * t4_mc_read - read from MC through backdoor accesses | ||
276 | * @adap: the adapter | ||
277 | * @addr: address of first byte requested | ||
278 | * @data: 64 bytes of data containing the requested address | ||
279 | * @ecc: where to store the corresponding 64-bit ECC word | ||
280 | * | ||
281 | * Read 64 bytes of data from MC starting at a 64-byte-aligned address | ||
282 | * that covers the requested address @addr. If @parity is not %NULL it | ||
283 | * is assigned the 64-bit ECC word for the read data. | ||
284 | */ | ||
285 | int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *ecc) | ||
286 | { | ||
287 | int i; | ||
288 | |||
289 | if (t4_read_reg(adap, MC_BIST_CMD) & START_BIST) | ||
290 | return -EBUSY; | ||
291 | t4_write_reg(adap, MC_BIST_CMD_ADDR, addr & ~0x3fU); | ||
292 | t4_write_reg(adap, MC_BIST_CMD_LEN, 64); | ||
293 | t4_write_reg(adap, MC_BIST_DATA_PATTERN, 0xc); | ||
294 | t4_write_reg(adap, MC_BIST_CMD, BIST_OPCODE(1) | START_BIST | | ||
295 | BIST_CMD_GAP(1)); | ||
296 | i = t4_wait_op_done(adap, MC_BIST_CMD, START_BIST, 0, 10, 1); | ||
297 | if (i) | ||
298 | return i; | ||
299 | |||
300 | #define MC_DATA(i) MC_BIST_STATUS_REG(MC_BIST_STATUS_RDATA, i) | ||
301 | |||
302 | for (i = 15; i >= 0; i--) | ||
303 | *data++ = htonl(t4_read_reg(adap, MC_DATA(i))); | ||
304 | if (ecc) | ||
305 | *ecc = t4_read_reg64(adap, MC_DATA(16)); | ||
306 | #undef MC_DATA | ||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | /** | ||
311 | * t4_edc_read - read from EDC through backdoor accesses | ||
312 | * @adap: the adapter | ||
313 | * @idx: which EDC to access | ||
314 | * @addr: address of first byte requested | ||
315 | * @data: 64 bytes of data containing the requested address | ||
316 | * @ecc: where to store the corresponding 64-bit ECC word | ||
317 | * | ||
318 | * Read 64 bytes of data from EDC starting at a 64-byte-aligned address | ||
319 | * that covers the requested address @addr. If @parity is not %NULL it | ||
320 | * is assigned the 64-bit ECC word for the read data. | ||
321 | */ | ||
322 | int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) | ||
323 | { | ||
324 | int i; | ||
325 | |||
326 | idx *= EDC_STRIDE; | ||
327 | if (t4_read_reg(adap, EDC_BIST_CMD + idx) & START_BIST) | ||
328 | return -EBUSY; | ||
329 | t4_write_reg(adap, EDC_BIST_CMD_ADDR + idx, addr & ~0x3fU); | ||
330 | t4_write_reg(adap, EDC_BIST_CMD_LEN + idx, 64); | ||
331 | t4_write_reg(adap, EDC_BIST_DATA_PATTERN + idx, 0xc); | ||
332 | t4_write_reg(adap, EDC_BIST_CMD + idx, | ||
333 | BIST_OPCODE(1) | BIST_CMD_GAP(1) | START_BIST); | ||
334 | i = t4_wait_op_done(adap, EDC_BIST_CMD + idx, START_BIST, 0, 10, 1); | ||
335 | if (i) | ||
336 | return i; | ||
337 | |||
338 | #define EDC_DATA(i) (EDC_BIST_STATUS_REG(EDC_BIST_STATUS_RDATA, i) + idx) | ||
339 | |||
340 | for (i = 15; i >= 0; i--) | ||
341 | *data++ = htonl(t4_read_reg(adap, EDC_DATA(i))); | ||
342 | if (ecc) | ||
343 | *ecc = t4_read_reg64(adap, EDC_DATA(16)); | ||
344 | #undef EDC_DATA | ||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | #define VPD_ENTRY(name, len) \ | ||
349 | u8 name##_kword[2]; u8 name##_len; u8 name##_data[len] | ||
350 | |||
351 | /* | ||
352 | * Partial EEPROM Vital Product Data structure. Includes only the ID and | ||
353 | * VPD-R sections. | ||
354 | */ | ||
355 | struct t4_vpd { | ||
356 | u8 id_tag; | ||
357 | u8 id_len[2]; | ||
358 | u8 id_data[ID_LEN]; | ||
359 | u8 vpdr_tag; | ||
360 | u8 vpdr_len[2]; | ||
361 | VPD_ENTRY(pn, 16); /* part number */ | ||
362 | VPD_ENTRY(ec, EC_LEN); /* EC level */ | ||
363 | VPD_ENTRY(sn, SERNUM_LEN); /* serial number */ | ||
364 | VPD_ENTRY(na, 12); /* MAC address base */ | ||
365 | VPD_ENTRY(port_type, 8); /* port types */ | ||
366 | VPD_ENTRY(gpio, 14); /* GPIO usage */ | ||
367 | VPD_ENTRY(cclk, 6); /* core clock */ | ||
368 | VPD_ENTRY(port_addr, 8); /* port MDIO addresses */ | ||
369 | VPD_ENTRY(rv, 1); /* csum */ | ||
370 | u32 pad; /* for multiple-of-4 sizing and alignment */ | ||
371 | }; | ||
372 | |||
373 | #define EEPROM_STAT_ADDR 0x7bfc | ||
374 | #define VPD_BASE 0 | ||
375 | |||
376 | /** | ||
377 | * t4_seeprom_wp - enable/disable EEPROM write protection | ||
378 | * @adapter: the adapter | ||
379 | * @enable: whether to enable or disable write protection | ||
380 | * | ||
381 | * Enables or disables write protection on the serial EEPROM. | ||
382 | */ | ||
383 | int t4_seeprom_wp(struct adapter *adapter, bool enable) | ||
384 | { | ||
385 | unsigned int v = enable ? 0xc : 0; | ||
386 | int ret = pci_write_vpd(adapter->pdev, EEPROM_STAT_ADDR, 4, &v); | ||
387 | return ret < 0 ? ret : 0; | ||
388 | } | ||
389 | |||
390 | /** | ||
391 | * get_vpd_params - read VPD parameters from VPD EEPROM | ||
392 | * @adapter: adapter to read | ||
393 | * @p: where to store the parameters | ||
394 | * | ||
395 | * Reads card parameters stored in VPD EEPROM. | ||
396 | */ | ||
397 | static int get_vpd_params(struct adapter *adapter, struct vpd_params *p) | ||
398 | { | ||
399 | int ret; | ||
400 | struct t4_vpd vpd; | ||
401 | u8 *q = (u8 *)&vpd, csum; | ||
402 | |||
403 | ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(vpd), &vpd); | ||
404 | if (ret < 0) | ||
405 | return ret; | ||
406 | |||
407 | for (csum = 0; q <= vpd.rv_data; q++) | ||
408 | csum += *q; | ||
409 | |||
410 | if (csum) { | ||
411 | dev_err(adapter->pdev_dev, | ||
412 | "corrupted VPD EEPROM, actual csum %u\n", csum); | ||
413 | return -EINVAL; | ||
414 | } | ||
415 | |||
416 | p->cclk = simple_strtoul(vpd.cclk_data, NULL, 10); | ||
417 | memcpy(p->id, vpd.id_data, sizeof(vpd.id_data)); | ||
418 | strim(p->id); | ||
419 | memcpy(p->ec, vpd.ec_data, sizeof(vpd.ec_data)); | ||
420 | strim(p->ec); | ||
421 | memcpy(p->sn, vpd.sn_data, sizeof(vpd.sn_data)); | ||
422 | strim(p->sn); | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | /* serial flash and firmware constants */ | ||
427 | enum { | ||
428 | SF_ATTEMPTS = 10, /* max retries for SF operations */ | ||
429 | |||
430 | /* flash command opcodes */ | ||
431 | SF_PROG_PAGE = 2, /* program page */ | ||
432 | SF_WR_DISABLE = 4, /* disable writes */ | ||
433 | SF_RD_STATUS = 5, /* read status register */ | ||
434 | SF_WR_ENABLE = 6, /* enable writes */ | ||
435 | SF_RD_DATA_FAST = 0xb, /* read flash */ | ||
436 | SF_ERASE_SECTOR = 0xd8, /* erase sector */ | ||
437 | |||
438 | FW_START_SEC = 8, /* first flash sector for FW */ | ||
439 | FW_END_SEC = 15, /* last flash sector for FW */ | ||
440 | FW_IMG_START = FW_START_SEC * SF_SEC_SIZE, | ||
441 | FW_MAX_SIZE = (FW_END_SEC - FW_START_SEC + 1) * SF_SEC_SIZE, | ||
442 | }; | ||
443 | |||
444 | /** | ||
445 | * sf1_read - read data from the serial flash | ||
446 | * @adapter: the adapter | ||
447 | * @byte_cnt: number of bytes to read | ||
448 | * @cont: whether another operation will be chained | ||
449 | * @lock: whether to lock SF for PL access only | ||
450 | * @valp: where to store the read data | ||
451 | * | ||
452 | * Reads up to 4 bytes of data from the serial flash. The location of | ||
453 | * the read needs to be specified prior to calling this by issuing the | ||
454 | * appropriate commands to the serial flash. | ||
455 | */ | ||
456 | static int sf1_read(struct adapter *adapter, unsigned int byte_cnt, int cont, | ||
457 | int lock, u32 *valp) | ||
458 | { | ||
459 | int ret; | ||
460 | |||
461 | if (!byte_cnt || byte_cnt > 4) | ||
462 | return -EINVAL; | ||
463 | if (t4_read_reg(adapter, SF_OP) & BUSY) | ||
464 | return -EBUSY; | ||
465 | cont = cont ? SF_CONT : 0; | ||
466 | lock = lock ? SF_LOCK : 0; | ||
467 | t4_write_reg(adapter, SF_OP, lock | cont | BYTECNT(byte_cnt - 1)); | ||
468 | ret = t4_wait_op_done(adapter, SF_OP, BUSY, 0, SF_ATTEMPTS, 5); | ||
469 | if (!ret) | ||
470 | *valp = t4_read_reg(adapter, SF_DATA); | ||
471 | return ret; | ||
472 | } | ||
473 | |||
474 | /** | ||
475 | * sf1_write - write data to the serial flash | ||
476 | * @adapter: the adapter | ||
477 | * @byte_cnt: number of bytes to write | ||
478 | * @cont: whether another operation will be chained | ||
479 | * @lock: whether to lock SF for PL access only | ||
480 | * @val: value to write | ||
481 | * | ||
482 | * Writes up to 4 bytes of data to the serial flash. The location of | ||
483 | * the write needs to be specified prior to calling this by issuing the | ||
484 | * appropriate commands to the serial flash. | ||
485 | */ | ||
486 | static int sf1_write(struct adapter *adapter, unsigned int byte_cnt, int cont, | ||
487 | int lock, u32 val) | ||
488 | { | ||
489 | if (!byte_cnt || byte_cnt > 4) | ||
490 | return -EINVAL; | ||
491 | if (t4_read_reg(adapter, SF_OP) & BUSY) | ||
492 | return -EBUSY; | ||
493 | cont = cont ? SF_CONT : 0; | ||
494 | lock = lock ? SF_LOCK : 0; | ||
495 | t4_write_reg(adapter, SF_DATA, val); | ||
496 | t4_write_reg(adapter, SF_OP, lock | | ||
497 | cont | BYTECNT(byte_cnt - 1) | OP_WR); | ||
498 | return t4_wait_op_done(adapter, SF_OP, BUSY, 0, SF_ATTEMPTS, 5); | ||
499 | } | ||
500 | |||
501 | /** | ||
502 | * flash_wait_op - wait for a flash operation to complete | ||
503 | * @adapter: the adapter | ||
504 | * @attempts: max number of polls of the status register | ||
505 | * @delay: delay between polls in ms | ||
506 | * | ||
507 | * Wait for a flash operation to complete by polling the status register. | ||
508 | */ | ||
509 | static int flash_wait_op(struct adapter *adapter, int attempts, int delay) | ||
510 | { | ||
511 | int ret; | ||
512 | u32 status; | ||
513 | |||
514 | while (1) { | ||
515 | if ((ret = sf1_write(adapter, 1, 1, 1, SF_RD_STATUS)) != 0 || | ||
516 | (ret = sf1_read(adapter, 1, 0, 1, &status)) != 0) | ||
517 | return ret; | ||
518 | if (!(status & 1)) | ||
519 | return 0; | ||
520 | if (--attempts == 0) | ||
521 | return -EAGAIN; | ||
522 | if (delay) | ||
523 | msleep(delay); | ||
524 | } | ||
525 | } | ||
526 | |||
527 | /** | ||
528 | * t4_read_flash - read words from serial flash | ||
529 | * @adapter: the adapter | ||
530 | * @addr: the start address for the read | ||
531 | * @nwords: how many 32-bit words to read | ||
532 | * @data: where to store the read data | ||
533 | * @byte_oriented: whether to store data as bytes or as words | ||
534 | * | ||
535 | * Read the specified number of 32-bit words from the serial flash. | ||
536 | * If @byte_oriented is set the read data is stored as a byte array | ||
537 | * (i.e., big-endian), otherwise as 32-bit words in the platform's | ||
538 | * natural endianess. | ||
539 | */ | ||
540 | int t4_read_flash(struct adapter *adapter, unsigned int addr, | ||
541 | unsigned int nwords, u32 *data, int byte_oriented) | ||
542 | { | ||
543 | int ret; | ||
544 | |||
545 | if (addr + nwords * sizeof(u32) > SF_SIZE || (addr & 3)) | ||
546 | return -EINVAL; | ||
547 | |||
548 | addr = swab32(addr) | SF_RD_DATA_FAST; | ||
549 | |||
550 | if ((ret = sf1_write(adapter, 4, 1, 0, addr)) != 0 || | ||
551 | (ret = sf1_read(adapter, 1, 1, 0, data)) != 0) | ||
552 | return ret; | ||
553 | |||
554 | for ( ; nwords; nwords--, data++) { | ||
555 | ret = sf1_read(adapter, 4, nwords > 1, nwords == 1, data); | ||
556 | if (nwords == 1) | ||
557 | t4_write_reg(adapter, SF_OP, 0); /* unlock SF */ | ||
558 | if (ret) | ||
559 | return ret; | ||
560 | if (byte_oriented) | ||
561 | *data = htonl(*data); | ||
562 | } | ||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | /** | ||
567 | * t4_write_flash - write up to a page of data to the serial flash | ||
568 | * @adapter: the adapter | ||
569 | * @addr: the start address to write | ||
570 | * @n: length of data to write in bytes | ||
571 | * @data: the data to write | ||
572 | * | ||
573 | * Writes up to a page of data (256 bytes) to the serial flash starting | ||
574 | * at the given address. All the data must be written to the same page. | ||
575 | */ | ||
576 | static int t4_write_flash(struct adapter *adapter, unsigned int addr, | ||
577 | unsigned int n, const u8 *data) | ||
578 | { | ||
579 | int ret; | ||
580 | u32 buf[64]; | ||
581 | unsigned int i, c, left, val, offset = addr & 0xff; | ||
582 | |||
583 | if (addr >= SF_SIZE || offset + n > SF_PAGE_SIZE) | ||
584 | return -EINVAL; | ||
585 | |||
586 | val = swab32(addr) | SF_PROG_PAGE; | ||
587 | |||
588 | if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 || | ||
589 | (ret = sf1_write(adapter, 4, 1, 1, val)) != 0) | ||
590 | goto unlock; | ||
591 | |||
592 | for (left = n; left; left -= c) { | ||
593 | c = min(left, 4U); | ||
594 | for (val = 0, i = 0; i < c; ++i) | ||
595 | val = (val << 8) + *data++; | ||
596 | |||
597 | ret = sf1_write(adapter, c, c != left, 1, val); | ||
598 | if (ret) | ||
599 | goto unlock; | ||
600 | } | ||
601 | ret = flash_wait_op(adapter, 5, 1); | ||
602 | if (ret) | ||
603 | goto unlock; | ||
604 | |||
605 | t4_write_reg(adapter, SF_OP, 0); /* unlock SF */ | ||
606 | |||
607 | /* Read the page to verify the write succeeded */ | ||
608 | ret = t4_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf, 1); | ||
609 | if (ret) | ||
610 | return ret; | ||
611 | |||
612 | if (memcmp(data - n, (u8 *)buf + offset, n)) { | ||
613 | dev_err(adapter->pdev_dev, | ||
614 | "failed to correctly write the flash page at %#x\n", | ||
615 | addr); | ||
616 | return -EIO; | ||
617 | } | ||
618 | return 0; | ||
619 | |||
620 | unlock: | ||
621 | t4_write_reg(adapter, SF_OP, 0); /* unlock SF */ | ||
622 | return ret; | ||
623 | } | ||
624 | |||
625 | /** | ||
626 | * get_fw_version - read the firmware version | ||
627 | * @adapter: the adapter | ||
628 | * @vers: where to place the version | ||
629 | * | ||
630 | * Reads the FW version from flash. | ||
631 | */ | ||
632 | static int get_fw_version(struct adapter *adapter, u32 *vers) | ||
633 | { | ||
634 | return t4_read_flash(adapter, | ||
635 | FW_IMG_START + offsetof(struct fw_hdr, fw_ver), 1, | ||
636 | vers, 0); | ||
637 | } | ||
638 | |||
639 | /** | ||
640 | * get_tp_version - read the TP microcode version | ||
641 | * @adapter: the adapter | ||
642 | * @vers: where to place the version | ||
643 | * | ||
644 | * Reads the TP microcode version from flash. | ||
645 | */ | ||
646 | static int get_tp_version(struct adapter *adapter, u32 *vers) | ||
647 | { | ||
648 | return t4_read_flash(adapter, FW_IMG_START + offsetof(struct fw_hdr, | ||
649 | tp_microcode_ver), | ||
650 | 1, vers, 0); | ||
651 | } | ||
652 | |||
653 | /** | ||
654 | * t4_check_fw_version - check if the FW is compatible with this driver | ||
655 | * @adapter: the adapter | ||
656 | * | ||
657 | * Checks if an adapter's FW is compatible with the driver. Returns 0 | ||
658 | * if there's exact match, a negative error if the version could not be | ||
659 | * read or there's a major version mismatch, and a positive value if the | ||
660 | * expected major version is found but there's a minor version mismatch. | ||
661 | */ | ||
662 | int t4_check_fw_version(struct adapter *adapter) | ||
663 | { | ||
664 | u32 api_vers[2]; | ||
665 | int ret, major, minor, micro; | ||
666 | |||
667 | ret = get_fw_version(adapter, &adapter->params.fw_vers); | ||
668 | if (!ret) | ||
669 | ret = get_tp_version(adapter, &adapter->params.tp_vers); | ||
670 | if (!ret) | ||
671 | ret = t4_read_flash(adapter, | ||
672 | FW_IMG_START + offsetof(struct fw_hdr, intfver_nic), | ||
673 | 2, api_vers, 1); | ||
674 | if (ret) | ||
675 | return ret; | ||
676 | |||
677 | major = FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers); | ||
678 | minor = FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers); | ||
679 | micro = FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers); | ||
680 | memcpy(adapter->params.api_vers, api_vers, | ||
681 | sizeof(adapter->params.api_vers)); | ||
682 | |||
683 | if (major != FW_VERSION_MAJOR) { /* major mismatch - fail */ | ||
684 | dev_err(adapter->pdev_dev, | ||
685 | "card FW has major version %u, driver wants %u\n", | ||
686 | major, FW_VERSION_MAJOR); | ||
687 | return -EINVAL; | ||
688 | } | ||
689 | |||
690 | if (minor == FW_VERSION_MINOR && micro == FW_VERSION_MICRO) | ||
691 | return 0; /* perfect match */ | ||
692 | |||
693 | /* Minor/micro version mismatch. Report it but often it's OK. */ | ||
694 | return 1; | ||
695 | } | ||
696 | |||
697 | /** | ||
698 | * t4_flash_erase_sectors - erase a range of flash sectors | ||
699 | * @adapter: the adapter | ||
700 | * @start: the first sector to erase | ||
701 | * @end: the last sector to erase | ||
702 | * | ||
703 | * Erases the sectors in the given inclusive range. | ||
704 | */ | ||
705 | static int t4_flash_erase_sectors(struct adapter *adapter, int start, int end) | ||
706 | { | ||
707 | int ret = 0; | ||
708 | |||
709 | while (start <= end) { | ||
710 | if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 || | ||
711 | (ret = sf1_write(adapter, 4, 0, 1, | ||
712 | SF_ERASE_SECTOR | (start << 8))) != 0 || | ||
713 | (ret = flash_wait_op(adapter, 5, 500)) != 0) { | ||
714 | dev_err(adapter->pdev_dev, | ||
715 | "erase of flash sector %d failed, error %d\n", | ||
716 | start, ret); | ||
717 | break; | ||
718 | } | ||
719 | start++; | ||
720 | } | ||
721 | t4_write_reg(adapter, SF_OP, 0); /* unlock SF */ | ||
722 | return ret; | ||
723 | } | ||
724 | |||
725 | /** | ||
726 | * t4_load_fw - download firmware | ||
727 | * @adap: the adapter | ||
728 | * @fw_data: the firmware image to write | ||
729 | * @size: image size | ||
730 | * | ||
731 | * Write the supplied firmware image to the card's serial flash. | ||
732 | */ | ||
733 | int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size) | ||
734 | { | ||
735 | u32 csum; | ||
736 | int ret, addr; | ||
737 | unsigned int i; | ||
738 | u8 first_page[SF_PAGE_SIZE]; | ||
739 | const u32 *p = (const u32 *)fw_data; | ||
740 | const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data; | ||
741 | |||
742 | if (!size) { | ||
743 | dev_err(adap->pdev_dev, "FW image has no data\n"); | ||
744 | return -EINVAL; | ||
745 | } | ||
746 | if (size & 511) { | ||
747 | dev_err(adap->pdev_dev, | ||
748 | "FW image size not multiple of 512 bytes\n"); | ||
749 | return -EINVAL; | ||
750 | } | ||
751 | if (ntohs(hdr->len512) * 512 != size) { | ||
752 | dev_err(adap->pdev_dev, | ||
753 | "FW image size differs from size in FW header\n"); | ||
754 | return -EINVAL; | ||
755 | } | ||
756 | if (size > FW_MAX_SIZE) { | ||
757 | dev_err(adap->pdev_dev, "FW image too large, max is %u bytes\n", | ||
758 | FW_MAX_SIZE); | ||
759 | return -EFBIG; | ||
760 | } | ||
761 | |||
762 | for (csum = 0, i = 0; i < size / sizeof(csum); i++) | ||
763 | csum += ntohl(p[i]); | ||
764 | |||
765 | if (csum != 0xffffffff) { | ||
766 | dev_err(adap->pdev_dev, | ||
767 | "corrupted firmware image, checksum %#x\n", csum); | ||
768 | return -EINVAL; | ||
769 | } | ||
770 | |||
771 | i = DIV_ROUND_UP(size, SF_SEC_SIZE); /* # of sectors spanned */ | ||
772 | ret = t4_flash_erase_sectors(adap, FW_START_SEC, FW_START_SEC + i - 1); | ||
773 | if (ret) | ||
774 | goto out; | ||
775 | |||
776 | /* | ||
777 | * We write the correct version at the end so the driver can see a bad | ||
778 | * version if the FW write fails. Start by writing a copy of the | ||
779 | * first page with a bad version. | ||
780 | */ | ||
781 | memcpy(first_page, fw_data, SF_PAGE_SIZE); | ||
782 | ((struct fw_hdr *)first_page)->fw_ver = htonl(0xffffffff); | ||
783 | ret = t4_write_flash(adap, FW_IMG_START, SF_PAGE_SIZE, first_page); | ||
784 | if (ret) | ||
785 | goto out; | ||
786 | |||
787 | addr = FW_IMG_START; | ||
788 | for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) { | ||
789 | addr += SF_PAGE_SIZE; | ||
790 | fw_data += SF_PAGE_SIZE; | ||
791 | ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, fw_data); | ||
792 | if (ret) | ||
793 | goto out; | ||
794 | } | ||
795 | |||
796 | ret = t4_write_flash(adap, | ||
797 | FW_IMG_START + offsetof(struct fw_hdr, fw_ver), | ||
798 | sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver); | ||
799 | out: | ||
800 | if (ret) | ||
801 | dev_err(adap->pdev_dev, "firmware download failed, error %d\n", | ||
802 | ret); | ||
803 | return ret; | ||
804 | } | ||
805 | |||
806 | #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ | ||
807 | FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_ANEG) | ||
808 | |||
809 | /** | ||
810 | * t4_link_start - apply link configuration to MAC/PHY | ||
811 | * @phy: the PHY to setup | ||
812 | * @mac: the MAC to setup | ||
813 | * @lc: the requested link configuration | ||
814 | * | ||
815 | * Set up a port's MAC and PHY according to a desired link configuration. | ||
816 | * - If the PHY can auto-negotiate first decide what to advertise, then | ||
817 | * enable/disable auto-negotiation as desired, and reset. | ||
818 | * - If the PHY does not auto-negotiate just reset it. | ||
819 | * - If auto-negotiation is off set the MAC to the proper speed/duplex/FC, | ||
820 | * otherwise do it later based on the outcome of auto-negotiation. | ||
821 | */ | ||
822 | int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port, | ||
823 | struct link_config *lc) | ||
824 | { | ||
825 | struct fw_port_cmd c; | ||
826 | unsigned int fc = 0, mdi = FW_PORT_MDI(FW_PORT_MDI_AUTO); | ||
827 | |||
828 | lc->link_ok = 0; | ||
829 | if (lc->requested_fc & PAUSE_RX) | ||
830 | fc |= FW_PORT_CAP_FC_RX; | ||
831 | if (lc->requested_fc & PAUSE_TX) | ||
832 | fc |= FW_PORT_CAP_FC_TX; | ||
833 | |||
834 | memset(&c, 0, sizeof(c)); | ||
835 | c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | FW_CMD_REQUEST | | ||
836 | FW_CMD_EXEC | FW_PORT_CMD_PORTID(port)); | ||
837 | c.action_to_len16 = htonl(FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | | ||
838 | FW_LEN16(c)); | ||
839 | |||
840 | if (!(lc->supported & FW_PORT_CAP_ANEG)) { | ||
841 | c.u.l1cfg.rcap = htonl((lc->supported & ADVERT_MASK) | fc); | ||
842 | lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); | ||
843 | } else if (lc->autoneg == AUTONEG_DISABLE) { | ||
844 | c.u.l1cfg.rcap = htonl(lc->requested_speed | fc | mdi); | ||
845 | lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); | ||
846 | } else | ||
847 | c.u.l1cfg.rcap = htonl(lc->advertising | fc | mdi); | ||
848 | |||
849 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
850 | } | ||
851 | |||
852 | /** | ||
853 | * t4_restart_aneg - restart autonegotiation | ||
854 | * @adap: the adapter | ||
855 | * @mbox: mbox to use for the FW command | ||
856 | * @port: the port id | ||
857 | * | ||
858 | * Restarts autonegotiation for the selected port. | ||
859 | */ | ||
860 | int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port) | ||
861 | { | ||
862 | struct fw_port_cmd c; | ||
863 | |||
864 | memset(&c, 0, sizeof(c)); | ||
865 | c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | FW_CMD_REQUEST | | ||
866 | FW_CMD_EXEC | FW_PORT_CMD_PORTID(port)); | ||
867 | c.action_to_len16 = htonl(FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | | ||
868 | FW_LEN16(c)); | ||
869 | c.u.l1cfg.rcap = htonl(FW_PORT_CAP_ANEG); | ||
870 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
871 | } | ||
872 | |||
873 | /** | ||
874 | * t4_set_vlan_accel - configure HW VLAN extraction | ||
875 | * @adap: the adapter | ||
876 | * @ports: bitmap of adapter ports to operate on | ||
877 | * @on: enable (1) or disable (0) HW VLAN extraction | ||
878 | * | ||
879 | * Enables or disables HW extraction of VLAN tags for the ports specified | ||
880 | * by @ports. @ports is a bitmap with the ith bit designating the port | ||
881 | * associated with the ith adapter channel. | ||
882 | */ | ||
883 | void t4_set_vlan_accel(struct adapter *adap, unsigned int ports, int on) | ||
884 | { | ||
885 | ports <<= VLANEXTENABLE_SHIFT; | ||
886 | t4_set_reg_field(adap, TP_OUT_CONFIG, ports, on ? ports : 0); | ||
887 | } | ||
888 | |||
889 | struct intr_info { | ||
890 | unsigned int mask; /* bits to check in interrupt status */ | ||
891 | const char *msg; /* message to print or NULL */ | ||
892 | short stat_idx; /* stat counter to increment or -1 */ | ||
893 | unsigned short fatal; /* whether the condition reported is fatal */ | ||
894 | }; | ||
895 | |||
896 | /** | ||
897 | * t4_handle_intr_status - table driven interrupt handler | ||
898 | * @adapter: the adapter that generated the interrupt | ||
899 | * @reg: the interrupt status register to process | ||
900 | * @acts: table of interrupt actions | ||
901 | * | ||
902 | * A table driven interrupt handler that applies a set of masks to an | ||
903 | * interrupt status word and performs the corresponding actions if the | ||
904 | * interrupts described by the mask have occured. The actions include | ||
905 | * optionally emitting a warning or alert message. The table is terminated | ||
906 | * by an entry specifying mask 0. Returns the number of fatal interrupt | ||
907 | * conditions. | ||
908 | */ | ||
909 | static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg, | ||
910 | const struct intr_info *acts) | ||
911 | { | ||
912 | int fatal = 0; | ||
913 | unsigned int mask = 0; | ||
914 | unsigned int status = t4_read_reg(adapter, reg); | ||
915 | |||
916 | for ( ; acts->mask; ++acts) { | ||
917 | if (!(status & acts->mask)) | ||
918 | continue; | ||
919 | if (acts->fatal) { | ||
920 | fatal++; | ||
921 | dev_alert(adapter->pdev_dev, "%s (0x%x)\n", acts->msg, | ||
922 | status & acts->mask); | ||
923 | } else if (acts->msg && printk_ratelimit()) | ||
924 | dev_warn(adapter->pdev_dev, "%s (0x%x)\n", acts->msg, | ||
925 | status & acts->mask); | ||
926 | mask |= acts->mask; | ||
927 | } | ||
928 | status &= mask; | ||
929 | if (status) /* clear processed interrupts */ | ||
930 | t4_write_reg(adapter, reg, status); | ||
931 | return fatal; | ||
932 | } | ||
933 | |||
934 | /* | ||
935 | * Interrupt handler for the PCIE module. | ||
936 | */ | ||
937 | static void pcie_intr_handler(struct adapter *adapter) | ||
938 | { | ||
939 | static struct intr_info sysbus_intr_info[] = { | ||
940 | { RNPP, "RXNP array parity error", -1, 1 }, | ||
941 | { RPCP, "RXPC array parity error", -1, 1 }, | ||
942 | { RCIP, "RXCIF array parity error", -1, 1 }, | ||
943 | { RCCP, "Rx completions control array parity error", -1, 1 }, | ||
944 | { RFTP, "RXFT array parity error", -1, 1 }, | ||
945 | { 0 } | ||
946 | }; | ||
947 | static struct intr_info pcie_port_intr_info[] = { | ||
948 | { TPCP, "TXPC array parity error", -1, 1 }, | ||
949 | { TNPP, "TXNP array parity error", -1, 1 }, | ||
950 | { TFTP, "TXFT array parity error", -1, 1 }, | ||
951 | { TCAP, "TXCA array parity error", -1, 1 }, | ||
952 | { TCIP, "TXCIF array parity error", -1, 1 }, | ||
953 | { RCAP, "RXCA array parity error", -1, 1 }, | ||
954 | { OTDD, "outbound request TLP discarded", -1, 1 }, | ||
955 | { RDPE, "Rx data parity error", -1, 1 }, | ||
956 | { TDUE, "Tx uncorrectable data error", -1, 1 }, | ||
957 | { 0 } | ||
958 | }; | ||
959 | static struct intr_info pcie_intr_info[] = { | ||
960 | { MSIADDRLPERR, "MSI AddrL parity error", -1, 1 }, | ||
961 | { MSIADDRHPERR, "MSI AddrH parity error", -1, 1 }, | ||
962 | { MSIDATAPERR, "MSI data parity error", -1, 1 }, | ||
963 | { MSIXADDRLPERR, "MSI-X AddrL parity error", -1, 1 }, | ||
964 | { MSIXADDRHPERR, "MSI-X AddrH parity error", -1, 1 }, | ||
965 | { MSIXDATAPERR, "MSI-X data parity error", -1, 1 }, | ||
966 | { MSIXDIPERR, "MSI-X DI parity error", -1, 1 }, | ||
967 | { PIOCPLPERR, "PCI PIO completion FIFO parity error", -1, 1 }, | ||
968 | { PIOREQPERR, "PCI PIO request FIFO parity error", -1, 1 }, | ||
969 | { TARTAGPERR, "PCI PCI target tag FIFO parity error", -1, 1 }, | ||
970 | { CCNTPERR, "PCI CMD channel count parity error", -1, 1 }, | ||
971 | { CREQPERR, "PCI CMD channel request parity error", -1, 1 }, | ||
972 | { CRSPPERR, "PCI CMD channel response parity error", -1, 1 }, | ||
973 | { DCNTPERR, "PCI DMA channel count parity error", -1, 1 }, | ||
974 | { DREQPERR, "PCI DMA channel request parity error", -1, 1 }, | ||
975 | { DRSPPERR, "PCI DMA channel response parity error", -1, 1 }, | ||
976 | { HCNTPERR, "PCI HMA channel count parity error", -1, 1 }, | ||
977 | { HREQPERR, "PCI HMA channel request parity error", -1, 1 }, | ||
978 | { HRSPPERR, "PCI HMA channel response parity error", -1, 1 }, | ||
979 | { CFGSNPPERR, "PCI config snoop FIFO parity error", -1, 1 }, | ||
980 | { FIDPERR, "PCI FID parity error", -1, 1 }, | ||
981 | { INTXCLRPERR, "PCI INTx clear parity error", -1, 1 }, | ||
982 | { MATAGPERR, "PCI MA tag parity error", -1, 1 }, | ||
983 | { PIOTAGPERR, "PCI PIO tag parity error", -1, 1 }, | ||
984 | { RXCPLPERR, "PCI Rx completion parity error", -1, 1 }, | ||
985 | { RXWRPERR, "PCI Rx write parity error", -1, 1 }, | ||
986 | { RPLPERR, "PCI replay buffer parity error", -1, 1 }, | ||
987 | { PCIESINT, "PCI core secondary fault", -1, 1 }, | ||
988 | { PCIEPINT, "PCI core primary fault", -1, 1 }, | ||
989 | { UNXSPLCPLERR, "PCI unexpected split completion error", -1, 0 }, | ||
990 | { 0 } | ||
991 | }; | ||
992 | |||
993 | int fat; | ||
994 | |||
995 | fat = t4_handle_intr_status(adapter, | ||
996 | PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS, | ||
997 | sysbus_intr_info) + | ||
998 | t4_handle_intr_status(adapter, | ||
999 | PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, | ||
1000 | pcie_port_intr_info) + | ||
1001 | t4_handle_intr_status(adapter, PCIE_INT_CAUSE, pcie_intr_info); | ||
1002 | if (fat) | ||
1003 | t4_fatal_err(adapter); | ||
1004 | } | ||
1005 | |||
1006 | /* | ||
1007 | * TP interrupt handler. | ||
1008 | */ | ||
1009 | static void tp_intr_handler(struct adapter *adapter) | ||
1010 | { | ||
1011 | static struct intr_info tp_intr_info[] = { | ||
1012 | { 0x3fffffff, "TP parity error", -1, 1 }, | ||
1013 | { FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1 }, | ||
1014 | { 0 } | ||
1015 | }; | ||
1016 | |||
1017 | if (t4_handle_intr_status(adapter, TP_INT_CAUSE, tp_intr_info)) | ||
1018 | t4_fatal_err(adapter); | ||
1019 | } | ||
1020 | |||
1021 | /* | ||
1022 | * SGE interrupt handler. | ||
1023 | */ | ||
1024 | static void sge_intr_handler(struct adapter *adapter) | ||
1025 | { | ||
1026 | u64 v; | ||
1027 | |||
1028 | static struct intr_info sge_intr_info[] = { | ||
1029 | { ERR_CPL_EXCEED_IQE_SIZE, | ||
1030 | "SGE received CPL exceeding IQE size", -1, 1 }, | ||
1031 | { ERR_INVALID_CIDX_INC, | ||
1032 | "SGE GTS CIDX increment too large", -1, 0 }, | ||
1033 | { ERR_CPL_OPCODE_0, "SGE received 0-length CPL", -1, 0 }, | ||
1034 | { ERR_DROPPED_DB, "SGE doorbell dropped", -1, 0 }, | ||
1035 | { ERR_DATA_CPL_ON_HIGH_QID1 | ERR_DATA_CPL_ON_HIGH_QID0, | ||
1036 | "SGE IQID > 1023 received CPL for FL", -1, 0 }, | ||
1037 | { ERR_BAD_DB_PIDX3, "SGE DBP 3 pidx increment too large", -1, | ||
1038 | 0 }, | ||
1039 | { ERR_BAD_DB_PIDX2, "SGE DBP 2 pidx increment too large", -1, | ||
1040 | 0 }, | ||
1041 | { ERR_BAD_DB_PIDX1, "SGE DBP 1 pidx increment too large", -1, | ||
1042 | 0 }, | ||
1043 | { ERR_BAD_DB_PIDX0, "SGE DBP 0 pidx increment too large", -1, | ||
1044 | 0 }, | ||
1045 | { ERR_ING_CTXT_PRIO, | ||
1046 | "SGE too many priority ingress contexts", -1, 0 }, | ||
1047 | { ERR_EGR_CTXT_PRIO, | ||
1048 | "SGE too many priority egress contexts", -1, 0 }, | ||
1049 | { INGRESS_SIZE_ERR, "SGE illegal ingress QID", -1, 0 }, | ||
1050 | { EGRESS_SIZE_ERR, "SGE illegal egress QID", -1, 0 }, | ||
1051 | { 0 } | ||
1052 | }; | ||
1053 | |||
1054 | v = (u64)t4_read_reg(adapter, SGE_INT_CAUSE1) | | ||
1055 | ((u64)t4_read_reg(adapter, SGE_INT_CAUSE2) << 32); | ||
1056 | if (v) { | ||
1057 | dev_alert(adapter->pdev_dev, "SGE parity error (%#llx)\n", | ||
1058 | (unsigned long long)v); | ||
1059 | t4_write_reg(adapter, SGE_INT_CAUSE1, v); | ||
1060 | t4_write_reg(adapter, SGE_INT_CAUSE2, v >> 32); | ||
1061 | } | ||
1062 | |||
1063 | if (t4_handle_intr_status(adapter, SGE_INT_CAUSE3, sge_intr_info) || | ||
1064 | v != 0) | ||
1065 | t4_fatal_err(adapter); | ||
1066 | } | ||
1067 | |||
1068 | /* | ||
1069 | * CIM interrupt handler. | ||
1070 | */ | ||
1071 | static void cim_intr_handler(struct adapter *adapter) | ||
1072 | { | ||
1073 | static struct intr_info cim_intr_info[] = { | ||
1074 | { PREFDROPINT, "CIM control register prefetch drop", -1, 1 }, | ||
1075 | { OBQPARERR, "CIM OBQ parity error", -1, 1 }, | ||
1076 | { IBQPARERR, "CIM IBQ parity error", -1, 1 }, | ||
1077 | { MBUPPARERR, "CIM mailbox uP parity error", -1, 1 }, | ||
1078 | { MBHOSTPARERR, "CIM mailbox host parity error", -1, 1 }, | ||
1079 | { TIEQINPARERRINT, "CIM TIEQ outgoing parity error", -1, 1 }, | ||
1080 | { TIEQOUTPARERRINT, "CIM TIEQ incoming parity error", -1, 1 }, | ||
1081 | { 0 } | ||
1082 | }; | ||
1083 | static struct intr_info cim_upintr_info[] = { | ||
1084 | { RSVDSPACEINT, "CIM reserved space access", -1, 1 }, | ||
1085 | { ILLTRANSINT, "CIM illegal transaction", -1, 1 }, | ||
1086 | { ILLWRINT, "CIM illegal write", -1, 1 }, | ||
1087 | { ILLRDINT, "CIM illegal read", -1, 1 }, | ||
1088 | { ILLRDBEINT, "CIM illegal read BE", -1, 1 }, | ||
1089 | { ILLWRBEINT, "CIM illegal write BE", -1, 1 }, | ||
1090 | { SGLRDBOOTINT, "CIM single read from boot space", -1, 1 }, | ||
1091 | { SGLWRBOOTINT, "CIM single write to boot space", -1, 1 }, | ||
1092 | { BLKWRBOOTINT, "CIM block write to boot space", -1, 1 }, | ||
1093 | { SGLRDFLASHINT, "CIM single read from flash space", -1, 1 }, | ||
1094 | { SGLWRFLASHINT, "CIM single write to flash space", -1, 1 }, | ||
1095 | { BLKWRFLASHINT, "CIM block write to flash space", -1, 1 }, | ||
1096 | { SGLRDEEPROMINT, "CIM single EEPROM read", -1, 1 }, | ||
1097 | { SGLWREEPROMINT, "CIM single EEPROM write", -1, 1 }, | ||
1098 | { BLKRDEEPROMINT, "CIM block EEPROM read", -1, 1 }, | ||
1099 | { BLKWREEPROMINT, "CIM block EEPROM write", -1, 1 }, | ||
1100 | { SGLRDCTLINT , "CIM single read from CTL space", -1, 1 }, | ||
1101 | { SGLWRCTLINT , "CIM single write to CTL space", -1, 1 }, | ||
1102 | { BLKRDCTLINT , "CIM block read from CTL space", -1, 1 }, | ||
1103 | { BLKWRCTLINT , "CIM block write to CTL space", -1, 1 }, | ||
1104 | { SGLRDPLINT , "CIM single read from PL space", -1, 1 }, | ||
1105 | { SGLWRPLINT , "CIM single write to PL space", -1, 1 }, | ||
1106 | { BLKRDPLINT , "CIM block read from PL space", -1, 1 }, | ||
1107 | { BLKWRPLINT , "CIM block write to PL space", -1, 1 }, | ||
1108 | { REQOVRLOOKUPINT , "CIM request FIFO overwrite", -1, 1 }, | ||
1109 | { RSPOVRLOOKUPINT , "CIM response FIFO overwrite", -1, 1 }, | ||
1110 | { TIMEOUTINT , "CIM PIF timeout", -1, 1 }, | ||
1111 | { TIMEOUTMAINT , "CIM PIF MA timeout", -1, 1 }, | ||
1112 | { 0 } | ||
1113 | }; | ||
1114 | |||
1115 | int fat; | ||
1116 | |||
1117 | fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE, | ||
1118 | cim_intr_info) + | ||
1119 | t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE, | ||
1120 | cim_upintr_info); | ||
1121 | if (fat) | ||
1122 | t4_fatal_err(adapter); | ||
1123 | } | ||
1124 | |||
1125 | /* | ||
1126 | * ULP RX interrupt handler. | ||
1127 | */ | ||
1128 | static void ulprx_intr_handler(struct adapter *adapter) | ||
1129 | { | ||
1130 | static struct intr_info ulprx_intr_info[] = { | ||
1131 | { 0x7fffff, "ULPRX parity error", -1, 1 }, | ||
1132 | { 0 } | ||
1133 | }; | ||
1134 | |||
1135 | if (t4_handle_intr_status(adapter, ULP_RX_INT_CAUSE, ulprx_intr_info)) | ||
1136 | t4_fatal_err(adapter); | ||
1137 | } | ||
1138 | |||
1139 | /* | ||
1140 | * ULP TX interrupt handler. | ||
1141 | */ | ||
1142 | static void ulptx_intr_handler(struct adapter *adapter) | ||
1143 | { | ||
1144 | static struct intr_info ulptx_intr_info[] = { | ||
1145 | { PBL_BOUND_ERR_CH3, "ULPTX channel 3 PBL out of bounds", -1, | ||
1146 | 0 }, | ||
1147 | { PBL_BOUND_ERR_CH2, "ULPTX channel 2 PBL out of bounds", -1, | ||
1148 | 0 }, | ||
1149 | { PBL_BOUND_ERR_CH1, "ULPTX channel 1 PBL out of bounds", -1, | ||
1150 | 0 }, | ||
1151 | { PBL_BOUND_ERR_CH0, "ULPTX channel 0 PBL out of bounds", -1, | ||
1152 | 0 }, | ||
1153 | { 0xfffffff, "ULPTX parity error", -1, 1 }, | ||
1154 | { 0 } | ||
1155 | }; | ||
1156 | |||
1157 | if (t4_handle_intr_status(adapter, ULP_TX_INT_CAUSE, ulptx_intr_info)) | ||
1158 | t4_fatal_err(adapter); | ||
1159 | } | ||
1160 | |||
1161 | /* | ||
1162 | * PM TX interrupt handler. | ||
1163 | */ | ||
1164 | static void pmtx_intr_handler(struct adapter *adapter) | ||
1165 | { | ||
1166 | static struct intr_info pmtx_intr_info[] = { | ||
1167 | { PCMD_LEN_OVFL0, "PMTX channel 0 pcmd too large", -1, 1 }, | ||
1168 | { PCMD_LEN_OVFL1, "PMTX channel 1 pcmd too large", -1, 1 }, | ||
1169 | { PCMD_LEN_OVFL2, "PMTX channel 2 pcmd too large", -1, 1 }, | ||
1170 | { ZERO_C_CMD_ERROR, "PMTX 0-length pcmd", -1, 1 }, | ||
1171 | { PMTX_FRAMING_ERROR, "PMTX framing error", -1, 1 }, | ||
1172 | { OESPI_PAR_ERROR, "PMTX oespi parity error", -1, 1 }, | ||
1173 | { DB_OPTIONS_PAR_ERROR, "PMTX db_options parity error", -1, 1 }, | ||
1174 | { ICSPI_PAR_ERROR, "PMTX icspi parity error", -1, 1 }, | ||
1175 | { C_PCMD_PAR_ERROR, "PMTX c_pcmd parity error", -1, 1}, | ||
1176 | { 0 } | ||
1177 | }; | ||
1178 | |||
1179 | if (t4_handle_intr_status(adapter, PM_TX_INT_CAUSE, pmtx_intr_info)) | ||
1180 | t4_fatal_err(adapter); | ||
1181 | } | ||
1182 | |||
1183 | /* | ||
1184 | * PM RX interrupt handler. | ||
1185 | */ | ||
1186 | static void pmrx_intr_handler(struct adapter *adapter) | ||
1187 | { | ||
1188 | static struct intr_info pmrx_intr_info[] = { | ||
1189 | { ZERO_E_CMD_ERROR, "PMRX 0-length pcmd", -1, 1 }, | ||
1190 | { PMRX_FRAMING_ERROR, "PMRX framing error", -1, 1 }, | ||
1191 | { OCSPI_PAR_ERROR, "PMRX ocspi parity error", -1, 1 }, | ||
1192 | { DB_OPTIONS_PAR_ERROR, "PMRX db_options parity error", -1, 1 }, | ||
1193 | { IESPI_PAR_ERROR, "PMRX iespi parity error", -1, 1 }, | ||
1194 | { E_PCMD_PAR_ERROR, "PMRX e_pcmd parity error", -1, 1}, | ||
1195 | { 0 } | ||
1196 | }; | ||
1197 | |||
1198 | if (t4_handle_intr_status(adapter, PM_RX_INT_CAUSE, pmrx_intr_info)) | ||
1199 | t4_fatal_err(adapter); | ||
1200 | } | ||
1201 | |||
1202 | /* | ||
1203 | * CPL switch interrupt handler. | ||
1204 | */ | ||
1205 | static void cplsw_intr_handler(struct adapter *adapter) | ||
1206 | { | ||
1207 | static struct intr_info cplsw_intr_info[] = { | ||
1208 | { CIM_OP_MAP_PERR, "CPLSW CIM op_map parity error", -1, 1 }, | ||
1209 | { CIM_OVFL_ERROR, "CPLSW CIM overflow", -1, 1 }, | ||
1210 | { TP_FRAMING_ERROR, "CPLSW TP framing error", -1, 1 }, | ||
1211 | { SGE_FRAMING_ERROR, "CPLSW SGE framing error", -1, 1 }, | ||
1212 | { CIM_FRAMING_ERROR, "CPLSW CIM framing error", -1, 1 }, | ||
1213 | { ZERO_SWITCH_ERROR, "CPLSW no-switch error", -1, 1 }, | ||
1214 | { 0 } | ||
1215 | }; | ||
1216 | |||
1217 | if (t4_handle_intr_status(adapter, CPL_INTR_CAUSE, cplsw_intr_info)) | ||
1218 | t4_fatal_err(adapter); | ||
1219 | } | ||
1220 | |||
1221 | /* | ||
1222 | * LE interrupt handler. | ||
1223 | */ | ||
1224 | static void le_intr_handler(struct adapter *adap) | ||
1225 | { | ||
1226 | static struct intr_info le_intr_info[] = { | ||
1227 | { LIPMISS, "LE LIP miss", -1, 0 }, | ||
1228 | { LIP0, "LE 0 LIP error", -1, 0 }, | ||
1229 | { PARITYERR, "LE parity error", -1, 1 }, | ||
1230 | { UNKNOWNCMD, "LE unknown command", -1, 1 }, | ||
1231 | { REQQPARERR, "LE request queue parity error", -1, 1 }, | ||
1232 | { 0 } | ||
1233 | }; | ||
1234 | |||
1235 | if (t4_handle_intr_status(adap, LE_DB_INT_CAUSE, le_intr_info)) | ||
1236 | t4_fatal_err(adap); | ||
1237 | } | ||
1238 | |||
1239 | /* | ||
1240 | * MPS interrupt handler. | ||
1241 | */ | ||
1242 | static void mps_intr_handler(struct adapter *adapter) | ||
1243 | { | ||
1244 | static struct intr_info mps_rx_intr_info[] = { | ||
1245 | { 0xffffff, "MPS Rx parity error", -1, 1 }, | ||
1246 | { 0 } | ||
1247 | }; | ||
1248 | static struct intr_info mps_tx_intr_info[] = { | ||
1249 | { TPFIFO, "MPS Tx TP FIFO parity error", -1, 1 }, | ||
1250 | { NCSIFIFO, "MPS Tx NC-SI FIFO parity error", -1, 1 }, | ||
1251 | { TXDATAFIFO, "MPS Tx data FIFO parity error", -1, 1 }, | ||
1252 | { TXDESCFIFO, "MPS Tx desc FIFO parity error", -1, 1 }, | ||
1253 | { BUBBLE, "MPS Tx underflow", -1, 1 }, | ||
1254 | { SECNTERR, "MPS Tx SOP/EOP error", -1, 1 }, | ||
1255 | { FRMERR, "MPS Tx framing error", -1, 1 }, | ||
1256 | { 0 } | ||
1257 | }; | ||
1258 | static struct intr_info mps_trc_intr_info[] = { | ||
1259 | { FILTMEM, "MPS TRC filter parity error", -1, 1 }, | ||
1260 | { PKTFIFO, "MPS TRC packet FIFO parity error", -1, 1 }, | ||
1261 | { MISCPERR, "MPS TRC misc parity error", -1, 1 }, | ||
1262 | { 0 } | ||
1263 | }; | ||
1264 | static struct intr_info mps_stat_sram_intr_info[] = { | ||
1265 | { 0x1fffff, "MPS statistics SRAM parity error", -1, 1 }, | ||
1266 | { 0 } | ||
1267 | }; | ||
1268 | static struct intr_info mps_stat_tx_intr_info[] = { | ||
1269 | { 0xfffff, "MPS statistics Tx FIFO parity error", -1, 1 }, | ||
1270 | { 0 } | ||
1271 | }; | ||
1272 | static struct intr_info mps_stat_rx_intr_info[] = { | ||
1273 | { 0xffffff, "MPS statistics Rx FIFO parity error", -1, 1 }, | ||
1274 | { 0 } | ||
1275 | }; | ||
1276 | static struct intr_info mps_cls_intr_info[] = { | ||
1277 | { MATCHSRAM, "MPS match SRAM parity error", -1, 1 }, | ||
1278 | { MATCHTCAM, "MPS match TCAM parity error", -1, 1 }, | ||
1279 | { HASHSRAM, "MPS hash SRAM parity error", -1, 1 }, | ||
1280 | { 0 } | ||
1281 | }; | ||
1282 | |||
1283 | int fat; | ||
1284 | |||
1285 | fat = t4_handle_intr_status(adapter, MPS_RX_PERR_INT_CAUSE, | ||
1286 | mps_rx_intr_info) + | ||
1287 | t4_handle_intr_status(adapter, MPS_TX_INT_CAUSE, | ||
1288 | mps_tx_intr_info) + | ||
1289 | t4_handle_intr_status(adapter, MPS_TRC_INT_CAUSE, | ||
1290 | mps_trc_intr_info) + | ||
1291 | t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_SRAM, | ||
1292 | mps_stat_sram_intr_info) + | ||
1293 | t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_TX_FIFO, | ||
1294 | mps_stat_tx_intr_info) + | ||
1295 | t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_RX_FIFO, | ||
1296 | mps_stat_rx_intr_info) + | ||
1297 | t4_handle_intr_status(adapter, MPS_CLS_INT_CAUSE, | ||
1298 | mps_cls_intr_info); | ||
1299 | |||
1300 | t4_write_reg(adapter, MPS_INT_CAUSE, CLSINT | TRCINT | | ||
1301 | RXINT | TXINT | STATINT); | ||
1302 | t4_read_reg(adapter, MPS_INT_CAUSE); /* flush */ | ||
1303 | if (fat) | ||
1304 | t4_fatal_err(adapter); | ||
1305 | } | ||
1306 | |||
1307 | #define MEM_INT_MASK (PERR_INT_CAUSE | ECC_CE_INT_CAUSE | ECC_UE_INT_CAUSE) | ||
1308 | |||
1309 | /* | ||
1310 | * EDC/MC interrupt handler. | ||
1311 | */ | ||
1312 | static void mem_intr_handler(struct adapter *adapter, int idx) | ||
1313 | { | ||
1314 | static const char name[3][5] = { "EDC0", "EDC1", "MC" }; | ||
1315 | |||
1316 | unsigned int addr, cnt_addr, v; | ||
1317 | |||
1318 | if (idx <= MEM_EDC1) { | ||
1319 | addr = EDC_REG(EDC_INT_CAUSE, idx); | ||
1320 | cnt_addr = EDC_REG(EDC_ECC_STATUS, idx); | ||
1321 | } else { | ||
1322 | addr = MC_INT_CAUSE; | ||
1323 | cnt_addr = MC_ECC_STATUS; | ||
1324 | } | ||
1325 | |||
1326 | v = t4_read_reg(adapter, addr) & MEM_INT_MASK; | ||
1327 | if (v & PERR_INT_CAUSE) | ||
1328 | dev_alert(adapter->pdev_dev, "%s FIFO parity error\n", | ||
1329 | name[idx]); | ||
1330 | if (v & ECC_CE_INT_CAUSE) { | ||
1331 | u32 cnt = ECC_CECNT_GET(t4_read_reg(adapter, cnt_addr)); | ||
1332 | |||
1333 | t4_write_reg(adapter, cnt_addr, ECC_CECNT_MASK); | ||
1334 | if (printk_ratelimit()) | ||
1335 | dev_warn(adapter->pdev_dev, | ||
1336 | "%u %s correctable ECC data error%s\n", | ||
1337 | cnt, name[idx], cnt > 1 ? "s" : ""); | ||
1338 | } | ||
1339 | if (v & ECC_UE_INT_CAUSE) | ||
1340 | dev_alert(adapter->pdev_dev, | ||
1341 | "%s uncorrectable ECC data error\n", name[idx]); | ||
1342 | |||
1343 | t4_write_reg(adapter, addr, v); | ||
1344 | if (v & (PERR_INT_CAUSE | ECC_UE_INT_CAUSE)) | ||
1345 | t4_fatal_err(adapter); | ||
1346 | } | ||
1347 | |||
1348 | /* | ||
1349 | * MA interrupt handler. | ||
1350 | */ | ||
1351 | static void ma_intr_handler(struct adapter *adap) | ||
1352 | { | ||
1353 | u32 v, status = t4_read_reg(adap, MA_INT_CAUSE); | ||
1354 | |||
1355 | if (status & MEM_PERR_INT_CAUSE) | ||
1356 | dev_alert(adap->pdev_dev, | ||
1357 | "MA parity error, parity status %#x\n", | ||
1358 | t4_read_reg(adap, MA_PARITY_ERROR_STATUS)); | ||
1359 | if (status & MEM_WRAP_INT_CAUSE) { | ||
1360 | v = t4_read_reg(adap, MA_INT_WRAP_STATUS); | ||
1361 | dev_alert(adap->pdev_dev, "MA address wrap-around error by " | ||
1362 | "client %u to address %#x\n", | ||
1363 | MEM_WRAP_CLIENT_NUM_GET(v), | ||
1364 | MEM_WRAP_ADDRESS_GET(v) << 4); | ||
1365 | } | ||
1366 | t4_write_reg(adap, MA_INT_CAUSE, status); | ||
1367 | t4_fatal_err(adap); | ||
1368 | } | ||
1369 | |||
1370 | /* | ||
1371 | * SMB interrupt handler. | ||
1372 | */ | ||
1373 | static void smb_intr_handler(struct adapter *adap) | ||
1374 | { | ||
1375 | static struct intr_info smb_intr_info[] = { | ||
1376 | { MSTTXFIFOPARINT, "SMB master Tx FIFO parity error", -1, 1 }, | ||
1377 | { MSTRXFIFOPARINT, "SMB master Rx FIFO parity error", -1, 1 }, | ||
1378 | { SLVFIFOPARINT, "SMB slave FIFO parity error", -1, 1 }, | ||
1379 | { 0 } | ||
1380 | }; | ||
1381 | |||
1382 | if (t4_handle_intr_status(adap, SMB_INT_CAUSE, smb_intr_info)) | ||
1383 | t4_fatal_err(adap); | ||
1384 | } | ||
1385 | |||
1386 | /* | ||
1387 | * NC-SI interrupt handler. | ||
1388 | */ | ||
1389 | static void ncsi_intr_handler(struct adapter *adap) | ||
1390 | { | ||
1391 | static struct intr_info ncsi_intr_info[] = { | ||
1392 | { CIM_DM_PRTY_ERR, "NC-SI CIM parity error", -1, 1 }, | ||
1393 | { MPS_DM_PRTY_ERR, "NC-SI MPS parity error", -1, 1 }, | ||
1394 | { TXFIFO_PRTY_ERR, "NC-SI Tx FIFO parity error", -1, 1 }, | ||
1395 | { RXFIFO_PRTY_ERR, "NC-SI Rx FIFO parity error", -1, 1 }, | ||
1396 | { 0 } | ||
1397 | }; | ||
1398 | |||
1399 | if (t4_handle_intr_status(adap, NCSI_INT_CAUSE, ncsi_intr_info)) | ||
1400 | t4_fatal_err(adap); | ||
1401 | } | ||
1402 | |||
1403 | /* | ||
1404 | * XGMAC interrupt handler. | ||
1405 | */ | ||
1406 | static void xgmac_intr_handler(struct adapter *adap, int port) | ||
1407 | { | ||
1408 | u32 v = t4_read_reg(adap, PORT_REG(port, XGMAC_PORT_INT_CAUSE)); | ||
1409 | |||
1410 | v &= TXFIFO_PRTY_ERR | RXFIFO_PRTY_ERR; | ||
1411 | if (!v) | ||
1412 | return; | ||
1413 | |||
1414 | if (v & TXFIFO_PRTY_ERR) | ||
1415 | dev_alert(adap->pdev_dev, "XGMAC %d Tx FIFO parity error\n", | ||
1416 | port); | ||
1417 | if (v & RXFIFO_PRTY_ERR) | ||
1418 | dev_alert(adap->pdev_dev, "XGMAC %d Rx FIFO parity error\n", | ||
1419 | port); | ||
1420 | t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_INT_CAUSE), v); | ||
1421 | t4_fatal_err(adap); | ||
1422 | } | ||
1423 | |||
1424 | /* | ||
1425 | * PL interrupt handler. | ||
1426 | */ | ||
1427 | static void pl_intr_handler(struct adapter *adap) | ||
1428 | { | ||
1429 | static struct intr_info pl_intr_info[] = { | ||
1430 | { FATALPERR, "T4 fatal parity error", -1, 1 }, | ||
1431 | { PERRVFID, "PL VFID_MAP parity error", -1, 1 }, | ||
1432 | { 0 } | ||
1433 | }; | ||
1434 | |||
1435 | if (t4_handle_intr_status(adap, PL_PL_INT_CAUSE, pl_intr_info)) | ||
1436 | t4_fatal_err(adap); | ||
1437 | } | ||
1438 | |||
1439 | #define PF_INTR_MASK (PFSW | PFCIM) | ||
1440 | #define GLBL_INTR_MASK (CIM | MPS | PL | PCIE | MC | EDC0 | \ | ||
1441 | EDC1 | LE | TP | MA | PM_TX | PM_RX | ULP_RX | \ | ||
1442 | CPL_SWITCH | SGE | ULP_TX) | ||
1443 | |||
1444 | /** | ||
1445 | * t4_slow_intr_handler - control path interrupt handler | ||
1446 | * @adapter: the adapter | ||
1447 | * | ||
1448 | * T4 interrupt handler for non-data global interrupt events, e.g., errors. | ||
1449 | * The designation 'slow' is because it involves register reads, while | ||
1450 | * data interrupts typically don't involve any MMIOs. | ||
1451 | */ | ||
1452 | int t4_slow_intr_handler(struct adapter *adapter) | ||
1453 | { | ||
1454 | u32 cause = t4_read_reg(adapter, PL_INT_CAUSE); | ||
1455 | |||
1456 | if (!(cause & GLBL_INTR_MASK)) | ||
1457 | return 0; | ||
1458 | if (cause & CIM) | ||
1459 | cim_intr_handler(adapter); | ||
1460 | if (cause & MPS) | ||
1461 | mps_intr_handler(adapter); | ||
1462 | if (cause & NCSI) | ||
1463 | ncsi_intr_handler(adapter); | ||
1464 | if (cause & PL) | ||
1465 | pl_intr_handler(adapter); | ||
1466 | if (cause & SMB) | ||
1467 | smb_intr_handler(adapter); | ||
1468 | if (cause & XGMAC0) | ||
1469 | xgmac_intr_handler(adapter, 0); | ||
1470 | if (cause & XGMAC1) | ||
1471 | xgmac_intr_handler(adapter, 1); | ||
1472 | if (cause & XGMAC_KR0) | ||
1473 | xgmac_intr_handler(adapter, 2); | ||
1474 | if (cause & XGMAC_KR1) | ||
1475 | xgmac_intr_handler(adapter, 3); | ||
1476 | if (cause & PCIE) | ||
1477 | pcie_intr_handler(adapter); | ||
1478 | if (cause & MC) | ||
1479 | mem_intr_handler(adapter, MEM_MC); | ||
1480 | if (cause & EDC0) | ||
1481 | mem_intr_handler(adapter, MEM_EDC0); | ||
1482 | if (cause & EDC1) | ||
1483 | mem_intr_handler(adapter, MEM_EDC1); | ||
1484 | if (cause & LE) | ||
1485 | le_intr_handler(adapter); | ||
1486 | if (cause & TP) | ||
1487 | tp_intr_handler(adapter); | ||
1488 | if (cause & MA) | ||
1489 | ma_intr_handler(adapter); | ||
1490 | if (cause & PM_TX) | ||
1491 | pmtx_intr_handler(adapter); | ||
1492 | if (cause & PM_RX) | ||
1493 | pmrx_intr_handler(adapter); | ||
1494 | if (cause & ULP_RX) | ||
1495 | ulprx_intr_handler(adapter); | ||
1496 | if (cause & CPL_SWITCH) | ||
1497 | cplsw_intr_handler(adapter); | ||
1498 | if (cause & SGE) | ||
1499 | sge_intr_handler(adapter); | ||
1500 | if (cause & ULP_TX) | ||
1501 | ulptx_intr_handler(adapter); | ||
1502 | |||
1503 | /* Clear the interrupts just processed for which we are the master. */ | ||
1504 | t4_write_reg(adapter, PL_INT_CAUSE, cause & GLBL_INTR_MASK); | ||
1505 | (void) t4_read_reg(adapter, PL_INT_CAUSE); /* flush */ | ||
1506 | return 1; | ||
1507 | } | ||
1508 | |||
1509 | /** | ||
1510 | * t4_intr_enable - enable interrupts | ||
1511 | * @adapter: the adapter whose interrupts should be enabled | ||
1512 | * | ||
1513 | * Enable PF-specific interrupts for the calling function and the top-level | ||
1514 | * interrupt concentrator for global interrupts. Interrupts are already | ||
1515 | * enabled at each module, here we just enable the roots of the interrupt | ||
1516 | * hierarchies. | ||
1517 | * | ||
1518 | * Note: this function should be called only when the driver manages | ||
1519 | * non PF-specific interrupts from the various HW modules. Only one PCI | ||
1520 | * function at a time should be doing this. | ||
1521 | */ | ||
1522 | void t4_intr_enable(struct adapter *adapter) | ||
1523 | { | ||
1524 | u32 pf = SOURCEPF_GET(t4_read_reg(adapter, PL_WHOAMI)); | ||
1525 | |||
1526 | t4_write_reg(adapter, SGE_INT_ENABLE3, ERR_CPL_EXCEED_IQE_SIZE | | ||
1527 | ERR_INVALID_CIDX_INC | ERR_CPL_OPCODE_0 | | ||
1528 | ERR_DROPPED_DB | ERR_DATA_CPL_ON_HIGH_QID1 | | ||
1529 | ERR_DATA_CPL_ON_HIGH_QID0 | ERR_BAD_DB_PIDX3 | | ||
1530 | ERR_BAD_DB_PIDX2 | ERR_BAD_DB_PIDX1 | | ||
1531 | ERR_BAD_DB_PIDX0 | ERR_ING_CTXT_PRIO | | ||
1532 | ERR_EGR_CTXT_PRIO | INGRESS_SIZE_ERR | | ||
1533 | EGRESS_SIZE_ERR); | ||
1534 | t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE), PF_INTR_MASK); | ||
1535 | t4_set_reg_field(adapter, PL_INT_MAP0, 0, 1 << pf); | ||
1536 | } | ||
1537 | |||
1538 | /** | ||
1539 | * t4_intr_disable - disable interrupts | ||
1540 | * @adapter: the adapter whose interrupts should be disabled | ||
1541 | * | ||
1542 | * Disable interrupts. We only disable the top-level interrupt | ||
1543 | * concentrators. The caller must be a PCI function managing global | ||
1544 | * interrupts. | ||
1545 | */ | ||
1546 | void t4_intr_disable(struct adapter *adapter) | ||
1547 | { | ||
1548 | u32 pf = SOURCEPF_GET(t4_read_reg(adapter, PL_WHOAMI)); | ||
1549 | |||
1550 | t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE), 0); | ||
1551 | t4_set_reg_field(adapter, PL_INT_MAP0, 1 << pf, 0); | ||
1552 | } | ||
1553 | |||
1554 | /** | ||
1555 | * t4_intr_clear - clear all interrupts | ||
1556 | * @adapter: the adapter whose interrupts should be cleared | ||
1557 | * | ||
1558 | * Clears all interrupts. The caller must be a PCI function managing | ||
1559 | * global interrupts. | ||
1560 | */ | ||
1561 | void t4_intr_clear(struct adapter *adapter) | ||
1562 | { | ||
1563 | static const unsigned int cause_reg[] = { | ||
1564 | SGE_INT_CAUSE1, SGE_INT_CAUSE2, SGE_INT_CAUSE3, | ||
1565 | PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS, | ||
1566 | PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, | ||
1567 | PCIE_NONFAT_ERR, PCIE_INT_CAUSE, | ||
1568 | MC_INT_CAUSE, | ||
1569 | MA_INT_WRAP_STATUS, MA_PARITY_ERROR_STATUS, MA_INT_CAUSE, | ||
1570 | EDC_INT_CAUSE, EDC_REG(EDC_INT_CAUSE, 1), | ||
1571 | CIM_HOST_INT_CAUSE, CIM_HOST_UPACC_INT_CAUSE, | ||
1572 | MYPF_REG(CIM_PF_HOST_INT_CAUSE), | ||
1573 | TP_INT_CAUSE, | ||
1574 | ULP_RX_INT_CAUSE, ULP_TX_INT_CAUSE, | ||
1575 | PM_RX_INT_CAUSE, PM_TX_INT_CAUSE, | ||
1576 | MPS_RX_PERR_INT_CAUSE, | ||
1577 | CPL_INTR_CAUSE, | ||
1578 | MYPF_REG(PL_PF_INT_CAUSE), | ||
1579 | PL_PL_INT_CAUSE, | ||
1580 | LE_DB_INT_CAUSE, | ||
1581 | }; | ||
1582 | |||
1583 | unsigned int i; | ||
1584 | |||
1585 | for (i = 0; i < ARRAY_SIZE(cause_reg); ++i) | ||
1586 | t4_write_reg(adapter, cause_reg[i], 0xffffffff); | ||
1587 | |||
1588 | t4_write_reg(adapter, PL_INT_CAUSE, GLBL_INTR_MASK); | ||
1589 | (void) t4_read_reg(adapter, PL_INT_CAUSE); /* flush */ | ||
1590 | } | ||
1591 | |||
1592 | /** | ||
1593 | * hash_mac_addr - return the hash value of a MAC address | ||
1594 | * @addr: the 48-bit Ethernet MAC address | ||
1595 | * | ||
1596 | * Hashes a MAC address according to the hash function used by HW inexact | ||
1597 | * (hash) address matching. | ||
1598 | */ | ||
1599 | static int hash_mac_addr(const u8 *addr) | ||
1600 | { | ||
1601 | u32 a = ((u32)addr[0] << 16) | ((u32)addr[1] << 8) | addr[2]; | ||
1602 | u32 b = ((u32)addr[3] << 16) | ((u32)addr[4] << 8) | addr[5]; | ||
1603 | a ^= b; | ||
1604 | a ^= (a >> 12); | ||
1605 | a ^= (a >> 6); | ||
1606 | return a & 0x3f; | ||
1607 | } | ||
1608 | |||
1609 | /** | ||
1610 | * t4_config_rss_range - configure a portion of the RSS mapping table | ||
1611 | * @adapter: the adapter | ||
1612 | * @mbox: mbox to use for the FW command | ||
1613 | * @viid: virtual interface whose RSS subtable is to be written | ||
1614 | * @start: start entry in the table to write | ||
1615 | * @n: how many table entries to write | ||
1616 | * @rspq: values for the response queue lookup table | ||
1617 | * @nrspq: number of values in @rspq | ||
1618 | * | ||
1619 | * Programs the selected part of the VI's RSS mapping table with the | ||
1620 | * provided values. If @nrspq < @n the supplied values are used repeatedly | ||
1621 | * until the full table range is populated. | ||
1622 | * | ||
1623 | * The caller must ensure the values in @rspq are in the range allowed for | ||
1624 | * @viid. | ||
1625 | */ | ||
1626 | int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, | ||
1627 | int start, int n, const u16 *rspq, unsigned int nrspq) | ||
1628 | { | ||
1629 | int ret; | ||
1630 | const u16 *rsp = rspq; | ||
1631 | const u16 *rsp_end = rspq + nrspq; | ||
1632 | struct fw_rss_ind_tbl_cmd cmd; | ||
1633 | |||
1634 | memset(&cmd, 0, sizeof(cmd)); | ||
1635 | cmd.op_to_viid = htonl(FW_CMD_OP(FW_RSS_IND_TBL_CMD) | | ||
1636 | FW_CMD_REQUEST | FW_CMD_WRITE | | ||
1637 | FW_RSS_IND_TBL_CMD_VIID(viid)); | ||
1638 | cmd.retval_len16 = htonl(FW_LEN16(cmd)); | ||
1639 | |||
1640 | /* each fw_rss_ind_tbl_cmd takes up to 32 entries */ | ||
1641 | while (n > 0) { | ||
1642 | int nq = min(n, 32); | ||
1643 | __be32 *qp = &cmd.iq0_to_iq2; | ||
1644 | |||
1645 | cmd.niqid = htons(nq); | ||
1646 | cmd.startidx = htons(start); | ||
1647 | |||
1648 | start += nq; | ||
1649 | n -= nq; | ||
1650 | |||
1651 | while (nq > 0) { | ||
1652 | unsigned int v; | ||
1653 | |||
1654 | v = FW_RSS_IND_TBL_CMD_IQ0(*rsp); | ||
1655 | if (++rsp >= rsp_end) | ||
1656 | rsp = rspq; | ||
1657 | v |= FW_RSS_IND_TBL_CMD_IQ1(*rsp); | ||
1658 | if (++rsp >= rsp_end) | ||
1659 | rsp = rspq; | ||
1660 | v |= FW_RSS_IND_TBL_CMD_IQ2(*rsp); | ||
1661 | if (++rsp >= rsp_end) | ||
1662 | rsp = rspq; | ||
1663 | |||
1664 | *qp++ = htonl(v); | ||
1665 | nq -= 3; | ||
1666 | } | ||
1667 | |||
1668 | ret = t4_wr_mbox(adapter, mbox, &cmd, sizeof(cmd), NULL); | ||
1669 | if (ret) | ||
1670 | return ret; | ||
1671 | } | ||
1672 | return 0; | ||
1673 | } | ||
1674 | |||
1675 | /** | ||
1676 | * t4_config_glbl_rss - configure the global RSS mode | ||
1677 | * @adapter: the adapter | ||
1678 | * @mbox: mbox to use for the FW command | ||
1679 | * @mode: global RSS mode | ||
1680 | * @flags: mode-specific flags | ||
1681 | * | ||
1682 | * Sets the global RSS mode. | ||
1683 | */ | ||
1684 | int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode, | ||
1685 | unsigned int flags) | ||
1686 | { | ||
1687 | struct fw_rss_glb_config_cmd c; | ||
1688 | |||
1689 | memset(&c, 0, sizeof(c)); | ||
1690 | c.op_to_write = htonl(FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) | | ||
1691 | FW_CMD_REQUEST | FW_CMD_WRITE); | ||
1692 | c.retval_len16 = htonl(FW_LEN16(c)); | ||
1693 | if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL) { | ||
1694 | c.u.manual.mode_pkd = htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode)); | ||
1695 | } else if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL) { | ||
1696 | c.u.basicvirtual.mode_pkd = | ||
1697 | htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode)); | ||
1698 | c.u.basicvirtual.synmapen_to_hashtoeplitz = htonl(flags); | ||
1699 | } else | ||
1700 | return -EINVAL; | ||
1701 | return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL); | ||
1702 | } | ||
1703 | |||
1704 | /* Read an RSS table row */ | ||
1705 | static int rd_rss_row(struct adapter *adap, int row, u32 *val) | ||
1706 | { | ||
1707 | t4_write_reg(adap, TP_RSS_LKP_TABLE, 0xfff00000 | row); | ||
1708 | return t4_wait_op_done_val(adap, TP_RSS_LKP_TABLE, LKPTBLROWVLD, 1, | ||
1709 | 5, 0, val); | ||
1710 | } | ||
1711 | |||
1712 | /** | ||
1713 | * t4_read_rss - read the contents of the RSS mapping table | ||
1714 | * @adapter: the adapter | ||
1715 | * @map: holds the contents of the RSS mapping table | ||
1716 | * | ||
1717 | * Reads the contents of the RSS hash->queue mapping table. | ||
1718 | */ | ||
1719 | int t4_read_rss(struct adapter *adapter, u16 *map) | ||
1720 | { | ||
1721 | u32 val; | ||
1722 | int i, ret; | ||
1723 | |||
1724 | for (i = 0; i < RSS_NENTRIES / 2; ++i) { | ||
1725 | ret = rd_rss_row(adapter, i, &val); | ||
1726 | if (ret) | ||
1727 | return ret; | ||
1728 | *map++ = LKPTBLQUEUE0_GET(val); | ||
1729 | *map++ = LKPTBLQUEUE1_GET(val); | ||
1730 | } | ||
1731 | return 0; | ||
1732 | } | ||
1733 | |||
1734 | /** | ||
1735 | * t4_tp_get_tcp_stats - read TP's TCP MIB counters | ||
1736 | * @adap: the adapter | ||
1737 | * @v4: holds the TCP/IP counter values | ||
1738 | * @v6: holds the TCP/IPv6 counter values | ||
1739 | * | ||
1740 | * Returns the values of TP's TCP/IP and TCP/IPv6 MIB counters. | ||
1741 | * Either @v4 or @v6 may be %NULL to skip the corresponding stats. | ||
1742 | */ | ||
1743 | void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, | ||
1744 | struct tp_tcp_stats *v6) | ||
1745 | { | ||
1746 | u32 val[TP_MIB_TCP_RXT_SEG_LO - TP_MIB_TCP_OUT_RST + 1]; | ||
1747 | |||
1748 | #define STAT_IDX(x) ((TP_MIB_TCP_##x) - TP_MIB_TCP_OUT_RST) | ||
1749 | #define STAT(x) val[STAT_IDX(x)] | ||
1750 | #define STAT64(x) (((u64)STAT(x##_HI) << 32) | STAT(x##_LO)) | ||
1751 | |||
1752 | if (v4) { | ||
1753 | t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, val, | ||
1754 | ARRAY_SIZE(val), TP_MIB_TCP_OUT_RST); | ||
1755 | v4->tcpOutRsts = STAT(OUT_RST); | ||
1756 | v4->tcpInSegs = STAT64(IN_SEG); | ||
1757 | v4->tcpOutSegs = STAT64(OUT_SEG); | ||
1758 | v4->tcpRetransSegs = STAT64(RXT_SEG); | ||
1759 | } | ||
1760 | if (v6) { | ||
1761 | t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, val, | ||
1762 | ARRAY_SIZE(val), TP_MIB_TCP_V6OUT_RST); | ||
1763 | v6->tcpOutRsts = STAT(OUT_RST); | ||
1764 | v6->tcpInSegs = STAT64(IN_SEG); | ||
1765 | v6->tcpOutSegs = STAT64(OUT_SEG); | ||
1766 | v6->tcpRetransSegs = STAT64(RXT_SEG); | ||
1767 | } | ||
1768 | #undef STAT64 | ||
1769 | #undef STAT | ||
1770 | #undef STAT_IDX | ||
1771 | } | ||
1772 | |||
1773 | /** | ||
1774 | * t4_tp_get_err_stats - read TP's error MIB counters | ||
1775 | * @adap: the adapter | ||
1776 | * @st: holds the counter values | ||
1777 | * | ||
1778 | * Returns the values of TP's error counters. | ||
1779 | */ | ||
1780 | void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st) | ||
1781 | { | ||
1782 | t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->macInErrs, | ||
1783 | 12, TP_MIB_MAC_IN_ERR_0); | ||
1784 | t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlCongDrops, | ||
1785 | 8, TP_MIB_TNL_CNG_DROP_0); | ||
1786 | t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlTxDrops, | ||
1787 | 4, TP_MIB_TNL_DROP_0); | ||
1788 | t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->ofldVlanDrops, | ||
1789 | 4, TP_MIB_OFD_VLN_DROP_0); | ||
1790 | t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tcp6InErrs, | ||
1791 | 4, TP_MIB_TCP_V6IN_ERR_0); | ||
1792 | t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, &st->ofldNoNeigh, | ||
1793 | 2, TP_MIB_OFD_ARP_DROP); | ||
1794 | } | ||
1795 | |||
1796 | /** | ||
1797 | * t4_read_mtu_tbl - returns the values in the HW path MTU table | ||
1798 | * @adap: the adapter | ||
1799 | * @mtus: where to store the MTU values | ||
1800 | * @mtu_log: where to store the MTU base-2 log (may be %NULL) | ||
1801 | * | ||
1802 | * Reads the HW path MTU table. | ||
1803 | */ | ||
1804 | void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log) | ||
1805 | { | ||
1806 | u32 v; | ||
1807 | int i; | ||
1808 | |||
1809 | for (i = 0; i < NMTUS; ++i) { | ||
1810 | t4_write_reg(adap, TP_MTU_TABLE, | ||
1811 | MTUINDEX(0xff) | MTUVALUE(i)); | ||
1812 | v = t4_read_reg(adap, TP_MTU_TABLE); | ||
1813 | mtus[i] = MTUVALUE_GET(v); | ||
1814 | if (mtu_log) | ||
1815 | mtu_log[i] = MTUWIDTH_GET(v); | ||
1816 | } | ||
1817 | } | ||
1818 | |||
1819 | /** | ||
1820 | * init_cong_ctrl - initialize congestion control parameters | ||
1821 | * @a: the alpha values for congestion control | ||
1822 | * @b: the beta values for congestion control | ||
1823 | * | ||
1824 | * Initialize the congestion control parameters. | ||
1825 | */ | ||
1826 | static void __devinit init_cong_ctrl(unsigned short *a, unsigned short *b) | ||
1827 | { | ||
1828 | a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = a[8] = 1; | ||
1829 | a[9] = 2; | ||
1830 | a[10] = 3; | ||
1831 | a[11] = 4; | ||
1832 | a[12] = 5; | ||
1833 | a[13] = 6; | ||
1834 | a[14] = 7; | ||
1835 | a[15] = 8; | ||
1836 | a[16] = 9; | ||
1837 | a[17] = 10; | ||
1838 | a[18] = 14; | ||
1839 | a[19] = 17; | ||
1840 | a[20] = 21; | ||
1841 | a[21] = 25; | ||
1842 | a[22] = 30; | ||
1843 | a[23] = 35; | ||
1844 | a[24] = 45; | ||
1845 | a[25] = 60; | ||
1846 | a[26] = 80; | ||
1847 | a[27] = 100; | ||
1848 | a[28] = 200; | ||
1849 | a[29] = 300; | ||
1850 | a[30] = 400; | ||
1851 | a[31] = 500; | ||
1852 | |||
1853 | b[0] = b[1] = b[2] = b[3] = b[4] = b[5] = b[6] = b[7] = b[8] = 0; | ||
1854 | b[9] = b[10] = 1; | ||
1855 | b[11] = b[12] = 2; | ||
1856 | b[13] = b[14] = b[15] = b[16] = 3; | ||
1857 | b[17] = b[18] = b[19] = b[20] = b[21] = 4; | ||
1858 | b[22] = b[23] = b[24] = b[25] = b[26] = b[27] = 5; | ||
1859 | b[28] = b[29] = 6; | ||
1860 | b[30] = b[31] = 7; | ||
1861 | } | ||
1862 | |||
1863 | /* The minimum additive increment value for the congestion control table */ | ||
1864 | #define CC_MIN_INCR 2U | ||
1865 | |||
1866 | /** | ||
1867 | * t4_load_mtus - write the MTU and congestion control HW tables | ||
1868 | * @adap: the adapter | ||
1869 | * @mtus: the values for the MTU table | ||
1870 | * @alpha: the values for the congestion control alpha parameter | ||
1871 | * @beta: the values for the congestion control beta parameter | ||
1872 | * | ||
1873 | * Write the HW MTU table with the supplied MTUs and the high-speed | ||
1874 | * congestion control table with the supplied alpha, beta, and MTUs. | ||
1875 | * We write the two tables together because the additive increments | ||
1876 | * depend on the MTUs. | ||
1877 | */ | ||
1878 | void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, | ||
1879 | const unsigned short *alpha, const unsigned short *beta) | ||
1880 | { | ||
1881 | static const unsigned int avg_pkts[NCCTRL_WIN] = { | ||
1882 | 2, 6, 10, 14, 20, 28, 40, 56, 80, 112, 160, 224, 320, 448, 640, | ||
1883 | 896, 1281, 1792, 2560, 3584, 5120, 7168, 10240, 14336, 20480, | ||
1884 | 28672, 40960, 57344, 81920, 114688, 163840, 229376 | ||
1885 | }; | ||
1886 | |||
1887 | unsigned int i, w; | ||
1888 | |||
1889 | for (i = 0; i < NMTUS; ++i) { | ||
1890 | unsigned int mtu = mtus[i]; | ||
1891 | unsigned int log2 = fls(mtu); | ||
1892 | |||
1893 | if (!(mtu & ((1 << log2) >> 2))) /* round */ | ||
1894 | log2--; | ||
1895 | t4_write_reg(adap, TP_MTU_TABLE, MTUINDEX(i) | | ||
1896 | MTUWIDTH(log2) | MTUVALUE(mtu)); | ||
1897 | |||
1898 | for (w = 0; w < NCCTRL_WIN; ++w) { | ||
1899 | unsigned int inc; | ||
1900 | |||
1901 | inc = max(((mtu - 40) * alpha[w]) / avg_pkts[w], | ||
1902 | CC_MIN_INCR); | ||
1903 | |||
1904 | t4_write_reg(adap, TP_CCTRL_TABLE, (i << 21) | | ||
1905 | (w << 16) | (beta[w] << 13) | inc); | ||
1906 | } | ||
1907 | } | ||
1908 | } | ||
1909 | |||
1910 | /** | ||
1911 | * t4_set_trace_filter - configure one of the tracing filters | ||
1912 | * @adap: the adapter | ||
1913 | * @tp: the desired trace filter parameters | ||
1914 | * @idx: which filter to configure | ||
1915 | * @enable: whether to enable or disable the filter | ||
1916 | * | ||
1917 | * Configures one of the tracing filters available in HW. If @enable is | ||
1918 | * %0 @tp is not examined and may be %NULL. | ||
1919 | */ | ||
1920 | int t4_set_trace_filter(struct adapter *adap, const struct trace_params *tp, | ||
1921 | int idx, int enable) | ||
1922 | { | ||
1923 | int i, ofst = idx * 4; | ||
1924 | u32 data_reg, mask_reg, cfg; | ||
1925 | u32 multitrc = TRCMULTIFILTER; | ||
1926 | |||
1927 | if (!enable) { | ||
1928 | t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0); | ||
1929 | goto out; | ||
1930 | } | ||
1931 | |||
1932 | if (tp->port > 11 || tp->invert > 1 || tp->skip_len > 0x1f || | ||
1933 | tp->skip_ofst > 0x1f || tp->min_len > 0x1ff || | ||
1934 | tp->snap_len > 9600 || (idx && tp->snap_len > 256)) | ||
1935 | return -EINVAL; | ||
1936 | |||
1937 | if (tp->snap_len > 256) { /* must be tracer 0 */ | ||
1938 | if ((t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 4) | | ||
1939 | t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 8) | | ||
1940 | t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 12)) & TFEN) | ||
1941 | return -EINVAL; /* other tracers are enabled */ | ||
1942 | multitrc = 0; | ||
1943 | } else if (idx) { | ||
1944 | i = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B); | ||
1945 | if (TFCAPTUREMAX_GET(i) > 256 && | ||
1946 | (t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A) & TFEN)) | ||
1947 | return -EINVAL; | ||
1948 | } | ||
1949 | |||
1950 | /* stop the tracer we'll be changing */ | ||
1951 | t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0); | ||
1952 | |||
1953 | /* disable tracing globally if running in the wrong single/multi mode */ | ||
1954 | cfg = t4_read_reg(adap, MPS_TRC_CFG); | ||
1955 | if ((cfg & TRCEN) && multitrc != (cfg & TRCMULTIFILTER)) { | ||
1956 | t4_write_reg(adap, MPS_TRC_CFG, cfg ^ TRCEN); | ||
1957 | t4_read_reg(adap, MPS_TRC_CFG); /* flush */ | ||
1958 | msleep(1); | ||
1959 | if (!(t4_read_reg(adap, MPS_TRC_CFG) & TRCFIFOEMPTY)) | ||
1960 | return -ETIMEDOUT; | ||
1961 | } | ||
1962 | /* | ||
1963 | * At this point either the tracing is enabled and in the right mode or | ||
1964 | * disabled. | ||
1965 | */ | ||
1966 | |||
1967 | idx *= (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH); | ||
1968 | data_reg = MPS_TRC_FILTER0_MATCH + idx; | ||
1969 | mask_reg = MPS_TRC_FILTER0_DONT_CARE + idx; | ||
1970 | |||
1971 | for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) { | ||
1972 | t4_write_reg(adap, data_reg, tp->data[i]); | ||
1973 | t4_write_reg(adap, mask_reg, ~tp->mask[i]); | ||
1974 | } | ||
1975 | t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst, | ||
1976 | TFCAPTUREMAX(tp->snap_len) | | ||
1977 | TFMINPKTSIZE(tp->min_len)); | ||
1978 | t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, | ||
1979 | TFOFFSET(tp->skip_ofst) | TFLENGTH(tp->skip_len) | | ||
1980 | TFPORT(tp->port) | TFEN | | ||
1981 | (tp->invert ? TFINVERTMATCH : 0)); | ||
1982 | |||
1983 | cfg &= ~TRCMULTIFILTER; | ||
1984 | t4_write_reg(adap, MPS_TRC_CFG, cfg | TRCEN | multitrc); | ||
1985 | out: t4_read_reg(adap, MPS_TRC_CFG); /* flush */ | ||
1986 | return 0; | ||
1987 | } | ||
1988 | |||
1989 | /** | ||
1990 | * t4_get_trace_filter - query one of the tracing filters | ||
1991 | * @adap: the adapter | ||
1992 | * @tp: the current trace filter parameters | ||
1993 | * @idx: which trace filter to query | ||
1994 | * @enabled: non-zero if the filter is enabled | ||
1995 | * | ||
1996 | * Returns the current settings of one of the HW tracing filters. | ||
1997 | */ | ||
1998 | void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx, | ||
1999 | int *enabled) | ||
2000 | { | ||
2001 | u32 ctla, ctlb; | ||
2002 | int i, ofst = idx * 4; | ||
2003 | u32 data_reg, mask_reg; | ||
2004 | |||
2005 | ctla = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst); | ||
2006 | ctlb = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst); | ||
2007 | |||
2008 | *enabled = !!(ctla & TFEN); | ||
2009 | tp->snap_len = TFCAPTUREMAX_GET(ctlb); | ||
2010 | tp->min_len = TFMINPKTSIZE_GET(ctlb); | ||
2011 | tp->skip_ofst = TFOFFSET_GET(ctla); | ||
2012 | tp->skip_len = TFLENGTH_GET(ctla); | ||
2013 | tp->invert = !!(ctla & TFINVERTMATCH); | ||
2014 | tp->port = TFPORT_GET(ctla); | ||
2015 | |||
2016 | ofst = (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH) * idx; | ||
2017 | data_reg = MPS_TRC_FILTER0_MATCH + ofst; | ||
2018 | mask_reg = MPS_TRC_FILTER0_DONT_CARE + ofst; | ||
2019 | |||
2020 | for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) { | ||
2021 | tp->mask[i] = ~t4_read_reg(adap, mask_reg); | ||
2022 | tp->data[i] = t4_read_reg(adap, data_reg) & tp->mask[i]; | ||
2023 | } | ||
2024 | } | ||
2025 | |||
2026 | /** | ||
2027 | * get_mps_bg_map - return the buffer groups associated with a port | ||
2028 | * @adap: the adapter | ||
2029 | * @idx: the port index | ||
2030 | * | ||
2031 | * Returns a bitmap indicating which MPS buffer groups are associated | ||
2032 | * with the given port. Bit i is set if buffer group i is used by the | ||
2033 | * port. | ||
2034 | */ | ||
2035 | static unsigned int get_mps_bg_map(struct adapter *adap, int idx) | ||
2036 | { | ||
2037 | u32 n = NUMPORTS_GET(t4_read_reg(adap, MPS_CMN_CTL)); | ||
2038 | |||
2039 | if (n == 0) | ||
2040 | return idx == 0 ? 0xf : 0; | ||
2041 | if (n == 1) | ||
2042 | return idx < 2 ? (3 << (2 * idx)) : 0; | ||
2043 | return 1 << idx; | ||
2044 | } | ||
2045 | |||
2046 | /** | ||
2047 | * t4_get_port_stats - collect port statistics | ||
2048 | * @adap: the adapter | ||
2049 | * @idx: the port index | ||
2050 | * @p: the stats structure to fill | ||
2051 | * | ||
2052 | * Collect statistics related to the given port from HW. | ||
2053 | */ | ||
2054 | void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p) | ||
2055 | { | ||
2056 | u32 bgmap = get_mps_bg_map(adap, idx); | ||
2057 | |||
2058 | #define GET_STAT(name) \ | ||
2059 | t4_read_reg64(adap, PORT_REG(idx, MPS_PORT_STAT_##name##_L)) | ||
2060 | #define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L) | ||
2061 | |||
2062 | p->tx_octets = GET_STAT(TX_PORT_BYTES); | ||
2063 | p->tx_frames = GET_STAT(TX_PORT_FRAMES); | ||
2064 | p->tx_bcast_frames = GET_STAT(TX_PORT_BCAST); | ||
2065 | p->tx_mcast_frames = GET_STAT(TX_PORT_MCAST); | ||
2066 | p->tx_ucast_frames = GET_STAT(TX_PORT_UCAST); | ||
2067 | p->tx_error_frames = GET_STAT(TX_PORT_ERROR); | ||
2068 | p->tx_frames_64 = GET_STAT(TX_PORT_64B); | ||
2069 | p->tx_frames_65_127 = GET_STAT(TX_PORT_65B_127B); | ||
2070 | p->tx_frames_128_255 = GET_STAT(TX_PORT_128B_255B); | ||
2071 | p->tx_frames_256_511 = GET_STAT(TX_PORT_256B_511B); | ||
2072 | p->tx_frames_512_1023 = GET_STAT(TX_PORT_512B_1023B); | ||
2073 | p->tx_frames_1024_1518 = GET_STAT(TX_PORT_1024B_1518B); | ||
2074 | p->tx_frames_1519_max = GET_STAT(TX_PORT_1519B_MAX); | ||
2075 | p->tx_drop = GET_STAT(TX_PORT_DROP); | ||
2076 | p->tx_pause = GET_STAT(TX_PORT_PAUSE); | ||
2077 | p->tx_ppp0 = GET_STAT(TX_PORT_PPP0); | ||
2078 | p->tx_ppp1 = GET_STAT(TX_PORT_PPP1); | ||
2079 | p->tx_ppp2 = GET_STAT(TX_PORT_PPP2); | ||
2080 | p->tx_ppp3 = GET_STAT(TX_PORT_PPP3); | ||
2081 | p->tx_ppp4 = GET_STAT(TX_PORT_PPP4); | ||
2082 | p->tx_ppp5 = GET_STAT(TX_PORT_PPP5); | ||
2083 | p->tx_ppp6 = GET_STAT(TX_PORT_PPP6); | ||
2084 | p->tx_ppp7 = GET_STAT(TX_PORT_PPP7); | ||
2085 | |||
2086 | p->rx_octets = GET_STAT(RX_PORT_BYTES); | ||
2087 | p->rx_frames = GET_STAT(RX_PORT_FRAMES); | ||
2088 | p->rx_bcast_frames = GET_STAT(RX_PORT_BCAST); | ||
2089 | p->rx_mcast_frames = GET_STAT(RX_PORT_MCAST); | ||
2090 | p->rx_ucast_frames = GET_STAT(RX_PORT_UCAST); | ||
2091 | p->rx_too_long = GET_STAT(RX_PORT_MTU_ERROR); | ||
2092 | p->rx_jabber = GET_STAT(RX_PORT_MTU_CRC_ERROR); | ||
2093 | p->rx_fcs_err = GET_STAT(RX_PORT_CRC_ERROR); | ||
2094 | p->rx_len_err = GET_STAT(RX_PORT_LEN_ERROR); | ||
2095 | p->rx_symbol_err = GET_STAT(RX_PORT_SYM_ERROR); | ||
2096 | p->rx_runt = GET_STAT(RX_PORT_LESS_64B); | ||
2097 | p->rx_frames_64 = GET_STAT(RX_PORT_64B); | ||
2098 | p->rx_frames_65_127 = GET_STAT(RX_PORT_65B_127B); | ||
2099 | p->rx_frames_128_255 = GET_STAT(RX_PORT_128B_255B); | ||
2100 | p->rx_frames_256_511 = GET_STAT(RX_PORT_256B_511B); | ||
2101 | p->rx_frames_512_1023 = GET_STAT(RX_PORT_512B_1023B); | ||
2102 | p->rx_frames_1024_1518 = GET_STAT(RX_PORT_1024B_1518B); | ||
2103 | p->rx_frames_1519_max = GET_STAT(RX_PORT_1519B_MAX); | ||
2104 | p->rx_pause = GET_STAT(RX_PORT_PAUSE); | ||
2105 | p->rx_ppp0 = GET_STAT(RX_PORT_PPP0); | ||
2106 | p->rx_ppp1 = GET_STAT(RX_PORT_PPP1); | ||
2107 | p->rx_ppp2 = GET_STAT(RX_PORT_PPP2); | ||
2108 | p->rx_ppp3 = GET_STAT(RX_PORT_PPP3); | ||
2109 | p->rx_ppp4 = GET_STAT(RX_PORT_PPP4); | ||
2110 | p->rx_ppp5 = GET_STAT(RX_PORT_PPP5); | ||
2111 | p->rx_ppp6 = GET_STAT(RX_PORT_PPP6); | ||
2112 | p->rx_ppp7 = GET_STAT(RX_PORT_PPP7); | ||
2113 | |||
2114 | p->rx_ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_DROP_FRAME) : 0; | ||
2115 | p->rx_ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_DROP_FRAME) : 0; | ||
2116 | p->rx_ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_DROP_FRAME) : 0; | ||
2117 | p->rx_ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_DROP_FRAME) : 0; | ||
2118 | p->rx_trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_TRUNC_FRAME) : 0; | ||
2119 | p->rx_trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_TRUNC_FRAME) : 0; | ||
2120 | p->rx_trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_TRUNC_FRAME) : 0; | ||
2121 | p->rx_trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_TRUNC_FRAME) : 0; | ||
2122 | |||
2123 | #undef GET_STAT | ||
2124 | #undef GET_STAT_COM | ||
2125 | } | ||
2126 | |||
2127 | /** | ||
2128 | * t4_get_lb_stats - collect loopback port statistics | ||
2129 | * @adap: the adapter | ||
2130 | * @idx: the loopback port index | ||
2131 | * @p: the stats structure to fill | ||
2132 | * | ||
2133 | * Return HW statistics for the given loopback port. | ||
2134 | */ | ||
2135 | void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p) | ||
2136 | { | ||
2137 | u32 bgmap = get_mps_bg_map(adap, idx); | ||
2138 | |||
2139 | #define GET_STAT(name) \ | ||
2140 | t4_read_reg64(adap, PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L)) | ||
2141 | #define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L) | ||
2142 | |||
2143 | p->octets = GET_STAT(BYTES); | ||
2144 | p->frames = GET_STAT(FRAMES); | ||
2145 | p->bcast_frames = GET_STAT(BCAST); | ||
2146 | p->mcast_frames = GET_STAT(MCAST); | ||
2147 | p->ucast_frames = GET_STAT(UCAST); | ||
2148 | p->error_frames = GET_STAT(ERROR); | ||
2149 | |||
2150 | p->frames_64 = GET_STAT(64B); | ||
2151 | p->frames_65_127 = GET_STAT(65B_127B); | ||
2152 | p->frames_128_255 = GET_STAT(128B_255B); | ||
2153 | p->frames_256_511 = GET_STAT(256B_511B); | ||
2154 | p->frames_512_1023 = GET_STAT(512B_1023B); | ||
2155 | p->frames_1024_1518 = GET_STAT(1024B_1518B); | ||
2156 | p->frames_1519_max = GET_STAT(1519B_MAX); | ||
2157 | p->drop = t4_read_reg(adap, PORT_REG(idx, | ||
2158 | MPS_PORT_STAT_LB_PORT_DROP_FRAMES)); | ||
2159 | |||
2160 | p->ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_DROP_FRAME) : 0; | ||
2161 | p->ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_DROP_FRAME) : 0; | ||
2162 | p->ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_DROP_FRAME) : 0; | ||
2163 | p->ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_DROP_FRAME) : 0; | ||
2164 | p->trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_TRUNC_FRAME) : 0; | ||
2165 | p->trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_TRUNC_FRAME) : 0; | ||
2166 | p->trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_TRUNC_FRAME) : 0; | ||
2167 | p->trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_TRUNC_FRAME) : 0; | ||
2168 | |||
2169 | #undef GET_STAT | ||
2170 | #undef GET_STAT_COM | ||
2171 | } | ||
2172 | |||
2173 | /** | ||
2174 | * t4_wol_magic_enable - enable/disable magic packet WoL | ||
2175 | * @adap: the adapter | ||
2176 | * @port: the physical port index | ||
2177 | * @addr: MAC address expected in magic packets, %NULL to disable | ||
2178 | * | ||
2179 | * Enables/disables magic packet wake-on-LAN for the selected port. | ||
2180 | */ | ||
2181 | void t4_wol_magic_enable(struct adapter *adap, unsigned int port, | ||
2182 | const u8 *addr) | ||
2183 | { | ||
2184 | if (addr) { | ||
2185 | t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_MAGIC_MACID_LO), | ||
2186 | (addr[2] << 24) | (addr[3] << 16) | | ||
2187 | (addr[4] << 8) | addr[5]); | ||
2188 | t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_MAGIC_MACID_HI), | ||
2189 | (addr[0] << 8) | addr[1]); | ||
2190 | } | ||
2191 | t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2), MAGICEN, | ||
2192 | addr ? MAGICEN : 0); | ||
2193 | } | ||
2194 | |||
2195 | /** | ||
2196 | * t4_wol_pat_enable - enable/disable pattern-based WoL | ||
2197 | * @adap: the adapter | ||
2198 | * @port: the physical port index | ||
2199 | * @map: bitmap of which HW pattern filters to set | ||
2200 | * @mask0: byte mask for bytes 0-63 of a packet | ||
2201 | * @mask1: byte mask for bytes 64-127 of a packet | ||
2202 | * @crc: Ethernet CRC for selected bytes | ||
2203 | * @enable: enable/disable switch | ||
2204 | * | ||
2205 | * Sets the pattern filters indicated in @map to mask out the bytes | ||
2206 | * specified in @mask0/@mask1 in received packets and compare the CRC of | ||
2207 | * the resulting packet against @crc. If @enable is %true pattern-based | ||
2208 | * WoL is enabled, otherwise disabled. | ||
2209 | */ | ||
2210 | int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, | ||
2211 | u64 mask0, u64 mask1, unsigned int crc, bool enable) | ||
2212 | { | ||
2213 | int i; | ||
2214 | |||
2215 | if (!enable) { | ||
2216 | t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2), | ||
2217 | PATEN, 0); | ||
2218 | return 0; | ||
2219 | } | ||
2220 | if (map > 0xff) | ||
2221 | return -EINVAL; | ||
2222 | |||
2223 | #define EPIO_REG(name) PORT_REG(port, XGMAC_PORT_EPIO_##name) | ||
2224 | |||
2225 | t4_write_reg(adap, EPIO_REG(DATA1), mask0 >> 32); | ||
2226 | t4_write_reg(adap, EPIO_REG(DATA2), mask1); | ||
2227 | t4_write_reg(adap, EPIO_REG(DATA3), mask1 >> 32); | ||
2228 | |||
2229 | for (i = 0; i < NWOL_PAT; i++, map >>= 1) { | ||
2230 | if (!(map & 1)) | ||
2231 | continue; | ||
2232 | |||
2233 | /* write byte masks */ | ||
2234 | t4_write_reg(adap, EPIO_REG(DATA0), mask0); | ||
2235 | t4_write_reg(adap, EPIO_REG(OP), ADDRESS(i) | EPIOWR); | ||
2236 | t4_read_reg(adap, EPIO_REG(OP)); /* flush */ | ||
2237 | if (t4_read_reg(adap, EPIO_REG(OP)) & BUSY) | ||
2238 | return -ETIMEDOUT; | ||
2239 | |||
2240 | /* write CRC */ | ||
2241 | t4_write_reg(adap, EPIO_REG(DATA0), crc); | ||
2242 | t4_write_reg(adap, EPIO_REG(OP), ADDRESS(i + 32) | EPIOWR); | ||
2243 | t4_read_reg(adap, EPIO_REG(OP)); /* flush */ | ||
2244 | if (t4_read_reg(adap, EPIO_REG(OP)) & BUSY) | ||
2245 | return -ETIMEDOUT; | ||
2246 | } | ||
2247 | #undef EPIO_REG | ||
2248 | |||
2249 | t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2), 0, PATEN); | ||
2250 | return 0; | ||
2251 | } | ||
2252 | |||
2253 | #define INIT_CMD(var, cmd, rd_wr) do { \ | ||
2254 | (var).op_to_write = htonl(FW_CMD_OP(FW_##cmd##_CMD) | \ | ||
2255 | FW_CMD_REQUEST | FW_CMD_##rd_wr); \ | ||
2256 | (var).retval_len16 = htonl(FW_LEN16(var)); \ | ||
2257 | } while (0) | ||
2258 | |||
2259 | /** | ||
2260 | * t4_mdio_rd - read a PHY register through MDIO | ||
2261 | * @adap: the adapter | ||
2262 | * @mbox: mailbox to use for the FW command | ||
2263 | * @phy_addr: the PHY address | ||
2264 | * @mmd: the PHY MMD to access (0 for clause 22 PHYs) | ||
2265 | * @reg: the register to read | ||
2266 | * @valp: where to store the value | ||
2267 | * | ||
2268 | * Issues a FW command through the given mailbox to read a PHY register. | ||
2269 | */ | ||
2270 | int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, | ||
2271 | unsigned int mmd, unsigned int reg, u16 *valp) | ||
2272 | { | ||
2273 | int ret; | ||
2274 | struct fw_ldst_cmd c; | ||
2275 | |||
2276 | memset(&c, 0, sizeof(c)); | ||
2277 | c.op_to_addrspace = htonl(FW_CMD_OP(FW_LDST_CMD) | FW_CMD_REQUEST | | ||
2278 | FW_CMD_READ | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO)); | ||
2279 | c.cycles_to_len16 = htonl(FW_LEN16(c)); | ||
2280 | c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR(phy_addr) | | ||
2281 | FW_LDST_CMD_MMD(mmd)); | ||
2282 | c.u.mdio.raddr = htons(reg); | ||
2283 | |||
2284 | ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); | ||
2285 | if (ret == 0) | ||
2286 | *valp = ntohs(c.u.mdio.rval); | ||
2287 | return ret; | ||
2288 | } | ||
2289 | |||
2290 | /** | ||
2291 | * t4_mdio_wr - write a PHY register through MDIO | ||
2292 | * @adap: the adapter | ||
2293 | * @mbox: mailbox to use for the FW command | ||
2294 | * @phy_addr: the PHY address | ||
2295 | * @mmd: the PHY MMD to access (0 for clause 22 PHYs) | ||
2296 | * @reg: the register to write | ||
2297 | * @valp: value to write | ||
2298 | * | ||
2299 | * Issues a FW command through the given mailbox to write a PHY register. | ||
2300 | */ | ||
2301 | int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, | ||
2302 | unsigned int mmd, unsigned int reg, u16 val) | ||
2303 | { | ||
2304 | struct fw_ldst_cmd c; | ||
2305 | |||
2306 | memset(&c, 0, sizeof(c)); | ||
2307 | c.op_to_addrspace = htonl(FW_CMD_OP(FW_LDST_CMD) | FW_CMD_REQUEST | | ||
2308 | FW_CMD_WRITE | FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO)); | ||
2309 | c.cycles_to_len16 = htonl(FW_LEN16(c)); | ||
2310 | c.u.mdio.paddr_mmd = htons(FW_LDST_CMD_PADDR(phy_addr) | | ||
2311 | FW_LDST_CMD_MMD(mmd)); | ||
2312 | c.u.mdio.raddr = htons(reg); | ||
2313 | c.u.mdio.rval = htons(val); | ||
2314 | |||
2315 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2316 | } | ||
2317 | |||
2318 | /** | ||
2319 | * t4_fw_hello - establish communication with FW | ||
2320 | * @adap: the adapter | ||
2321 | * @mbox: mailbox to use for the FW command | ||
2322 | * @evt_mbox: mailbox to receive async FW events | ||
2323 | * @master: specifies the caller's willingness to be the device master | ||
2324 | * @state: returns the current device state | ||
2325 | * | ||
2326 | * Issues a command to establish communication with FW. | ||
2327 | */ | ||
2328 | int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, | ||
2329 | enum dev_master master, enum dev_state *state) | ||
2330 | { | ||
2331 | int ret; | ||
2332 | struct fw_hello_cmd c; | ||
2333 | |||
2334 | INIT_CMD(c, HELLO, WRITE); | ||
2335 | c.err_to_mbasyncnot = htonl( | ||
2336 | FW_HELLO_CMD_MASTERDIS(master == MASTER_CANT) | | ||
2337 | FW_HELLO_CMD_MASTERFORCE(master == MASTER_MUST) | | ||
2338 | FW_HELLO_CMD_MBMASTER(master == MASTER_MUST ? mbox : 0xff) | | ||
2339 | FW_HELLO_CMD_MBASYNCNOT(evt_mbox)); | ||
2340 | |||
2341 | ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); | ||
2342 | if (ret == 0 && state) { | ||
2343 | u32 v = ntohl(c.err_to_mbasyncnot); | ||
2344 | if (v & FW_HELLO_CMD_INIT) | ||
2345 | *state = DEV_STATE_INIT; | ||
2346 | else if (v & FW_HELLO_CMD_ERR) | ||
2347 | *state = DEV_STATE_ERR; | ||
2348 | else | ||
2349 | *state = DEV_STATE_UNINIT; | ||
2350 | } | ||
2351 | return ret; | ||
2352 | } | ||
2353 | |||
2354 | /** | ||
2355 | * t4_fw_bye - end communication with FW | ||
2356 | * @adap: the adapter | ||
2357 | * @mbox: mailbox to use for the FW command | ||
2358 | * | ||
2359 | * Issues a command to terminate communication with FW. | ||
2360 | */ | ||
2361 | int t4_fw_bye(struct adapter *adap, unsigned int mbox) | ||
2362 | { | ||
2363 | struct fw_bye_cmd c; | ||
2364 | |||
2365 | INIT_CMD(c, BYE, WRITE); | ||
2366 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2367 | } | ||
2368 | |||
2369 | /** | ||
2370 | * t4_init_cmd - ask FW to initialize the device | ||
2371 | * @adap: the adapter | ||
2372 | * @mbox: mailbox to use for the FW command | ||
2373 | * | ||
2374 | * Issues a command to FW to partially initialize the device. This | ||
2375 | * performs initialization that generally doesn't depend on user input. | ||
2376 | */ | ||
2377 | int t4_early_init(struct adapter *adap, unsigned int mbox) | ||
2378 | { | ||
2379 | struct fw_initialize_cmd c; | ||
2380 | |||
2381 | INIT_CMD(c, INITIALIZE, WRITE); | ||
2382 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2383 | } | ||
2384 | |||
2385 | /** | ||
2386 | * t4_fw_reset - issue a reset to FW | ||
2387 | * @adap: the adapter | ||
2388 | * @mbox: mailbox to use for the FW command | ||
2389 | * @reset: specifies the type of reset to perform | ||
2390 | * | ||
2391 | * Issues a reset command of the specified type to FW. | ||
2392 | */ | ||
2393 | int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset) | ||
2394 | { | ||
2395 | struct fw_reset_cmd c; | ||
2396 | |||
2397 | INIT_CMD(c, RESET, WRITE); | ||
2398 | c.val = htonl(reset); | ||
2399 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2400 | } | ||
2401 | |||
2402 | /** | ||
2403 | * t4_query_params - query FW or device parameters | ||
2404 | * @adap: the adapter | ||
2405 | * @mbox: mailbox to use for the FW command | ||
2406 | * @pf: the PF | ||
2407 | * @vf: the VF | ||
2408 | * @nparams: the number of parameters | ||
2409 | * @params: the parameter names | ||
2410 | * @val: the parameter values | ||
2411 | * | ||
2412 | * Reads the value of FW or device parameters. Up to 7 parameters can be | ||
2413 | * queried at once. | ||
2414 | */ | ||
2415 | int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
2416 | unsigned int vf, unsigned int nparams, const u32 *params, | ||
2417 | u32 *val) | ||
2418 | { | ||
2419 | int i, ret; | ||
2420 | struct fw_params_cmd c; | ||
2421 | __be32 *p = &c.param[0].mnem; | ||
2422 | |||
2423 | if (nparams > 7) | ||
2424 | return -EINVAL; | ||
2425 | |||
2426 | memset(&c, 0, sizeof(c)); | ||
2427 | c.op_to_vfn = htonl(FW_CMD_OP(FW_PARAMS_CMD) | FW_CMD_REQUEST | | ||
2428 | FW_CMD_READ | FW_PARAMS_CMD_PFN(pf) | | ||
2429 | FW_PARAMS_CMD_VFN(vf)); | ||
2430 | c.retval_len16 = htonl(FW_LEN16(c)); | ||
2431 | for (i = 0; i < nparams; i++, p += 2) | ||
2432 | *p = htonl(*params++); | ||
2433 | |||
2434 | ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); | ||
2435 | if (ret == 0) | ||
2436 | for (i = 0, p = &c.param[0].val; i < nparams; i++, p += 2) | ||
2437 | *val++ = ntohl(*p); | ||
2438 | return ret; | ||
2439 | } | ||
2440 | |||
2441 | /** | ||
2442 | * t4_set_params - sets FW or device parameters | ||
2443 | * @adap: the adapter | ||
2444 | * @mbox: mailbox to use for the FW command | ||
2445 | * @pf: the PF | ||
2446 | * @vf: the VF | ||
2447 | * @nparams: the number of parameters | ||
2448 | * @params: the parameter names | ||
2449 | * @val: the parameter values | ||
2450 | * | ||
2451 | * Sets the value of FW or device parameters. Up to 7 parameters can be | ||
2452 | * specified at once. | ||
2453 | */ | ||
2454 | int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
2455 | unsigned int vf, unsigned int nparams, const u32 *params, | ||
2456 | const u32 *val) | ||
2457 | { | ||
2458 | struct fw_params_cmd c; | ||
2459 | __be32 *p = &c.param[0].mnem; | ||
2460 | |||
2461 | if (nparams > 7) | ||
2462 | return -EINVAL; | ||
2463 | |||
2464 | memset(&c, 0, sizeof(c)); | ||
2465 | c.op_to_vfn = htonl(FW_CMD_OP(FW_PARAMS_CMD) | FW_CMD_REQUEST | | ||
2466 | FW_CMD_WRITE | FW_PARAMS_CMD_PFN(pf) | | ||
2467 | FW_PARAMS_CMD_VFN(vf)); | ||
2468 | c.retval_len16 = htonl(FW_LEN16(c)); | ||
2469 | while (nparams--) { | ||
2470 | *p++ = htonl(*params++); | ||
2471 | *p++ = htonl(*val++); | ||
2472 | } | ||
2473 | |||
2474 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2475 | } | ||
2476 | |||
2477 | /** | ||
2478 | * t4_cfg_pfvf - configure PF/VF resource limits | ||
2479 | * @adap: the adapter | ||
2480 | * @mbox: mailbox to use for the FW command | ||
2481 | * @pf: the PF being configured | ||
2482 | * @vf: the VF being configured | ||
2483 | * @txq: the max number of egress queues | ||
2484 | * @txq_eth_ctrl: the max number of egress Ethernet or control queues | ||
2485 | * @rxqi: the max number of interrupt-capable ingress queues | ||
2486 | * @rxq: the max number of interruptless ingress queues | ||
2487 | * @tc: the PCI traffic class | ||
2488 | * @vi: the max number of virtual interfaces | ||
2489 | * @cmask: the channel access rights mask for the PF/VF | ||
2490 | * @pmask: the port access rights mask for the PF/VF | ||
2491 | * @nexact: the maximum number of exact MPS filters | ||
2492 | * @rcaps: read capabilities | ||
2493 | * @wxcaps: write/execute capabilities | ||
2494 | * | ||
2495 | * Configures resource limits and capabilities for a physical or virtual | ||
2496 | * function. | ||
2497 | */ | ||
2498 | int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
2499 | unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl, | ||
2500 | unsigned int rxqi, unsigned int rxq, unsigned int tc, | ||
2501 | unsigned int vi, unsigned int cmask, unsigned int pmask, | ||
2502 | unsigned int nexact, unsigned int rcaps, unsigned int wxcaps) | ||
2503 | { | ||
2504 | struct fw_pfvf_cmd c; | ||
2505 | |||
2506 | memset(&c, 0, sizeof(c)); | ||
2507 | c.op_to_vfn = htonl(FW_CMD_OP(FW_PFVF_CMD) | FW_CMD_REQUEST | | ||
2508 | FW_CMD_WRITE | FW_PFVF_CMD_PFN(pf) | | ||
2509 | FW_PFVF_CMD_VFN(vf)); | ||
2510 | c.retval_len16 = htonl(FW_LEN16(c)); | ||
2511 | c.niqflint_niq = htonl(FW_PFVF_CMD_NIQFLINT(rxqi) | | ||
2512 | FW_PFVF_CMD_NIQ(rxq)); | ||
2513 | c.cmask_to_neq = htonl(FW_PFVF_CMD_CMASK(cmask) | | ||
2514 | FW_PFVF_CMD_PMASK(pmask) | | ||
2515 | FW_PFVF_CMD_NEQ(txq)); | ||
2516 | c.tc_to_nexactf = htonl(FW_PFVF_CMD_TC(tc) | FW_PFVF_CMD_NVI(vi) | | ||
2517 | FW_PFVF_CMD_NEXACTF(nexact)); | ||
2518 | c.r_caps_to_nethctrl = htonl(FW_PFVF_CMD_R_CAPS(rcaps) | | ||
2519 | FW_PFVF_CMD_WX_CAPS(wxcaps) | | ||
2520 | FW_PFVF_CMD_NETHCTRL(txq_eth_ctrl)); | ||
2521 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2522 | } | ||
2523 | |||
2524 | /** | ||
2525 | * t4_alloc_vi - allocate a virtual interface | ||
2526 | * @adap: the adapter | ||
2527 | * @mbox: mailbox to use for the FW command | ||
2528 | * @port: physical port associated with the VI | ||
2529 | * @pf: the PF owning the VI | ||
2530 | * @vf: the VF owning the VI | ||
2531 | * @nmac: number of MAC addresses needed (1 to 5) | ||
2532 | * @mac: the MAC addresses of the VI | ||
2533 | * @rss_size: size of RSS table slice associated with this VI | ||
2534 | * | ||
2535 | * Allocates a virtual interface for the given physical port. If @mac is | ||
2536 | * not %NULL it contains the MAC addresses of the VI as assigned by FW. | ||
2537 | * @mac should be large enough to hold @nmac Ethernet addresses, they are | ||
2538 | * stored consecutively so the space needed is @nmac * 6 bytes. | ||
2539 | * Returns a negative error number or the non-negative VI id. | ||
2540 | */ | ||
2541 | int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port, | ||
2542 | unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac, | ||
2543 | unsigned int *rss_size) | ||
2544 | { | ||
2545 | int ret; | ||
2546 | struct fw_vi_cmd c; | ||
2547 | |||
2548 | memset(&c, 0, sizeof(c)); | ||
2549 | c.op_to_vfn = htonl(FW_CMD_OP(FW_VI_CMD) | FW_CMD_REQUEST | | ||
2550 | FW_CMD_WRITE | FW_CMD_EXEC | | ||
2551 | FW_VI_CMD_PFN(pf) | FW_VI_CMD_VFN(vf)); | ||
2552 | c.alloc_to_len16 = htonl(FW_VI_CMD_ALLOC | FW_LEN16(c)); | ||
2553 | c.portid_pkd = FW_VI_CMD_PORTID(port); | ||
2554 | c.nmac = nmac - 1; | ||
2555 | |||
2556 | ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); | ||
2557 | if (ret) | ||
2558 | return ret; | ||
2559 | |||
2560 | if (mac) { | ||
2561 | memcpy(mac, c.mac, sizeof(c.mac)); | ||
2562 | switch (nmac) { | ||
2563 | case 5: | ||
2564 | memcpy(mac + 24, c.nmac3, sizeof(c.nmac3)); | ||
2565 | case 4: | ||
2566 | memcpy(mac + 18, c.nmac2, sizeof(c.nmac2)); | ||
2567 | case 3: | ||
2568 | memcpy(mac + 12, c.nmac1, sizeof(c.nmac1)); | ||
2569 | case 2: | ||
2570 | memcpy(mac + 6, c.nmac0, sizeof(c.nmac0)); | ||
2571 | } | ||
2572 | } | ||
2573 | if (rss_size) | ||
2574 | *rss_size = FW_VI_CMD_RSSSIZE_GET(ntohs(c.rsssize_pkd)); | ||
2575 | return ntohs(c.viid_pkd); | ||
2576 | } | ||
2577 | |||
2578 | /** | ||
2579 | * t4_free_vi - free a virtual interface | ||
2580 | * @adap: the adapter | ||
2581 | * @mbox: mailbox to use for the FW command | ||
2582 | * @pf: the PF owning the VI | ||
2583 | * @vf: the VF owning the VI | ||
2584 | * @viid: virtual interface identifiler | ||
2585 | * | ||
2586 | * Free a previously allocated virtual interface. | ||
2587 | */ | ||
2588 | int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
2589 | unsigned int vf, unsigned int viid) | ||
2590 | { | ||
2591 | struct fw_vi_cmd c; | ||
2592 | |||
2593 | memset(&c, 0, sizeof(c)); | ||
2594 | c.op_to_vfn = htonl(FW_CMD_OP(FW_VI_CMD) | FW_CMD_REQUEST | | ||
2595 | FW_CMD_EXEC | FW_VI_CMD_PFN(pf) | | ||
2596 | FW_VI_CMD_VFN(vf)); | ||
2597 | c.alloc_to_len16 = htonl(FW_VI_CMD_FREE | FW_LEN16(c)); | ||
2598 | c.viid_pkd = htons(FW_VI_CMD_VIID(viid)); | ||
2599 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); | ||
2600 | } | ||
2601 | |||
2602 | /** | ||
2603 | * t4_set_rxmode - set Rx properties of a virtual interface | ||
2604 | * @adap: the adapter | ||
2605 | * @mbox: mailbox to use for the FW command | ||
2606 | * @viid: the VI id | ||
2607 | * @mtu: the new MTU or -1 | ||
2608 | * @promisc: 1 to enable promiscuous mode, 0 to disable it, -1 no change | ||
2609 | * @all_multi: 1 to enable all-multi mode, 0 to disable it, -1 no change | ||
2610 | * @bcast: 1 to enable broadcast Rx, 0 to disable it, -1 no change | ||
2611 | * @sleep_ok: if true we may sleep while awaiting command completion | ||
2612 | * | ||
2613 | * Sets Rx properties of a virtual interface. | ||
2614 | */ | ||
2615 | int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid, | ||
2616 | int mtu, int promisc, int all_multi, int bcast, bool sleep_ok) | ||
2617 | { | ||
2618 | struct fw_vi_rxmode_cmd c; | ||
2619 | |||
2620 | /* convert to FW values */ | ||
2621 | if (mtu < 0) | ||
2622 | mtu = FW_RXMODE_MTU_NO_CHG; | ||
2623 | if (promisc < 0) | ||
2624 | promisc = FW_VI_RXMODE_CMD_PROMISCEN_MASK; | ||
2625 | if (all_multi < 0) | ||
2626 | all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_MASK; | ||
2627 | if (bcast < 0) | ||
2628 | bcast = FW_VI_RXMODE_CMD_BROADCASTEN_MASK; | ||
2629 | |||
2630 | memset(&c, 0, sizeof(c)); | ||
2631 | c.op_to_viid = htonl(FW_CMD_OP(FW_VI_RXMODE_CMD) | FW_CMD_REQUEST | | ||
2632 | FW_CMD_WRITE | FW_VI_RXMODE_CMD_VIID(viid)); | ||
2633 | c.retval_len16 = htonl(FW_LEN16(c)); | ||
2634 | c.mtu_to_broadcasten = htonl(FW_VI_RXMODE_CMD_MTU(mtu) | | ||
2635 | FW_VI_RXMODE_CMD_PROMISCEN(promisc) | | ||
2636 | FW_VI_RXMODE_CMD_ALLMULTIEN(all_multi) | | ||
2637 | FW_VI_RXMODE_CMD_BROADCASTEN(bcast)); | ||
2638 | return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok); | ||
2639 | } | ||
2640 | |||
2641 | /** | ||
2642 | * t4_alloc_mac_filt - allocates exact-match filters for MAC addresses | ||
2643 | * @adap: the adapter | ||
2644 | * @mbox: mailbox to use for the FW command | ||
2645 | * @viid: the VI id | ||
2646 | * @free: if true any existing filters for this VI id are first removed | ||
2647 | * @naddr: the number of MAC addresses to allocate filters for (up to 7) | ||
2648 | * @addr: the MAC address(es) | ||
2649 | * @idx: where to store the index of each allocated filter | ||
2650 | * @hash: pointer to hash address filter bitmap | ||
2651 | * @sleep_ok: call is allowed to sleep | ||
2652 | * | ||
2653 | * Allocates an exact-match filter for each of the supplied addresses and | ||
2654 | * sets it to the corresponding address. If @idx is not %NULL it should | ||
2655 | * have at least @naddr entries, each of which will be set to the index of | ||
2656 | * the filter allocated for the corresponding MAC address. If a filter | ||
2657 | * could not be allocated for an address its index is set to 0xffff. | ||
2658 | * If @hash is not %NULL addresses that fail to allocate an exact filter | ||
2659 | * are hashed and update the hash filter bitmap pointed at by @hash. | ||
2660 | * | ||
2661 | * Returns a negative error number or the number of filters allocated. | ||
2662 | */ | ||
2663 | int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, | ||
2664 | unsigned int viid, bool free, unsigned int naddr, | ||
2665 | const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok) | ||
2666 | { | ||
2667 | int i, ret; | ||
2668 | struct fw_vi_mac_cmd c; | ||
2669 | struct fw_vi_mac_exact *p; | ||
2670 | |||
2671 | if (naddr > 7) | ||
2672 | return -EINVAL; | ||
2673 | |||
2674 | memset(&c, 0, sizeof(c)); | ||
2675 | c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST | | ||
2676 | FW_CMD_WRITE | (free ? FW_CMD_EXEC : 0) | | ||
2677 | FW_VI_MAC_CMD_VIID(viid)); | ||
2678 | c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_FREEMACS(free) | | ||
2679 | FW_CMD_LEN16((naddr + 2) / 2)); | ||
2680 | |||
2681 | for (i = 0, p = c.u.exact; i < naddr; i++, p++) { | ||
2682 | p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID | | ||
2683 | FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC)); | ||
2684 | memcpy(p->macaddr, addr[i], sizeof(p->macaddr)); | ||
2685 | } | ||
2686 | |||
2687 | ret = t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), &c, sleep_ok); | ||
2688 | if (ret) | ||
2689 | return ret; | ||
2690 | |||
2691 | for (i = 0, p = c.u.exact; i < naddr; i++, p++) { | ||
2692 | u16 index = FW_VI_MAC_CMD_IDX_GET(ntohs(p->valid_to_idx)); | ||
2693 | |||
2694 | if (idx) | ||
2695 | idx[i] = index >= NEXACT_MAC ? 0xffff : index; | ||
2696 | if (index < NEXACT_MAC) | ||
2697 | ret++; | ||
2698 | else if (hash) | ||
2699 | *hash |= (1 << hash_mac_addr(addr[i])); | ||
2700 | } | ||
2701 | return ret; | ||
2702 | } | ||
2703 | |||
2704 | /** | ||
2705 | * t4_change_mac - modifies the exact-match filter for a MAC address | ||
2706 | * @adap: the adapter | ||
2707 | * @mbox: mailbox to use for the FW command | ||
2708 | * @viid: the VI id | ||
2709 | * @idx: index of existing filter for old value of MAC address, or -1 | ||
2710 | * @addr: the new MAC address value | ||
2711 | * @persist: whether a new MAC allocation should be persistent | ||
2712 | * @add_smt: if true also add the address to the HW SMT | ||
2713 | * | ||
2714 | * Modifies an exact-match filter and sets it to the new MAC address. | ||
2715 | * Note that in general it is not possible to modify the value of a given | ||
2716 | * filter so the generic way to modify an address filter is to free the one | ||
2717 | * being used by the old address value and allocate a new filter for the | ||
2718 | * new address value. @idx can be -1 if the address is a new addition. | ||
2719 | * | ||
2720 | * Returns a negative error number or the index of the filter with the new | ||
2721 | * MAC value. | ||
2722 | */ | ||
2723 | int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, | ||
2724 | int idx, const u8 *addr, bool persist, bool add_smt) | ||
2725 | { | ||
2726 | int ret, mode; | ||
2727 | struct fw_vi_mac_cmd c; | ||
2728 | struct fw_vi_mac_exact *p = c.u.exact; | ||
2729 | |||
2730 | if (idx < 0) /* new allocation */ | ||
2731 | idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC; | ||
2732 | mode = add_smt ? FW_VI_MAC_SMT_AND_MPSTCAM : FW_VI_MAC_MPS_TCAM_ENTRY; | ||
2733 | |||
2734 | memset(&c, 0, sizeof(c)); | ||
2735 | c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST | | ||
2736 | FW_CMD_WRITE | FW_VI_MAC_CMD_VIID(viid)); | ||
2737 | c.freemacs_to_len16 = htonl(FW_CMD_LEN16(1)); | ||
2738 | p->valid_to_idx = htons(FW_VI_MAC_CMD_VALID | | ||
2739 | FW_VI_MAC_CMD_SMAC_RESULT(mode) | | ||
2740 | FW_VI_MAC_CMD_IDX(idx)); | ||
2741 | memcpy(p->macaddr, addr, sizeof(p->macaddr)); | ||
2742 | |||
2743 | ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); | ||
2744 | if (ret == 0) { | ||
2745 | ret = FW_VI_MAC_CMD_IDX_GET(ntohs(p->valid_to_idx)); | ||
2746 | if (ret >= NEXACT_MAC) | ||
2747 | ret = -ENOMEM; | ||
2748 | } | ||
2749 | return ret; | ||
2750 | } | ||
2751 | |||
2752 | /** | ||
2753 | * t4_set_addr_hash - program the MAC inexact-match hash filter | ||
2754 | * @adap: the adapter | ||
2755 | * @mbox: mailbox to use for the FW command | ||
2756 | * @viid: the VI id | ||
2757 | * @ucast: whether the hash filter should also match unicast addresses | ||
2758 | * @vec: the value to be written to the hash filter | ||
2759 | * @sleep_ok: call is allowed to sleep | ||
2760 | * | ||
2761 | * Sets the 64-bit inexact-match hash filter for a virtual interface. | ||
2762 | */ | ||
2763 | int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid, | ||
2764 | bool ucast, u64 vec, bool sleep_ok) | ||
2765 | { | ||
2766 | struct fw_vi_mac_cmd c; | ||
2767 | |||
2768 | memset(&c, 0, sizeof(c)); | ||
2769 | c.op_to_viid = htonl(FW_CMD_OP(FW_VI_MAC_CMD) | FW_CMD_REQUEST | | ||
2770 | FW_CMD_WRITE | FW_VI_ENABLE_CMD_VIID(viid)); | ||
2771 | c.freemacs_to_len16 = htonl(FW_VI_MAC_CMD_HASHVECEN | | ||
2772 | FW_VI_MAC_CMD_HASHUNIEN(ucast) | | ||
2773 | FW_CMD_LEN16(1)); | ||
2774 | c.u.hash.hashvec = cpu_to_be64(vec); | ||
2775 | return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok); | ||
2776 | } | ||
2777 | |||
2778 | /** | ||
2779 | * t4_enable_vi - enable/disable a virtual interface | ||
2780 | * @adap: the adapter | ||
2781 | * @mbox: mailbox to use for the FW command | ||
2782 | * @viid: the VI id | ||
2783 | * @rx_en: 1=enable Rx, 0=disable Rx | ||
2784 | * @tx_en: 1=enable Tx, 0=disable Tx | ||
2785 | * | ||
2786 | * Enables/disables a virtual interface. | ||
2787 | */ | ||
2788 | int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid, | ||
2789 | bool rx_en, bool tx_en) | ||
2790 | { | ||
2791 | struct fw_vi_enable_cmd c; | ||
2792 | |||
2793 | memset(&c, 0, sizeof(c)); | ||
2794 | c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | | ||
2795 | FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); | ||
2796 | c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_IEN(rx_en) | | ||
2797 | FW_VI_ENABLE_CMD_EEN(tx_en) | FW_LEN16(c)); | ||
2798 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2799 | } | ||
2800 | |||
2801 | /** | ||
2802 | * t4_identify_port - identify a VI's port by blinking its LED | ||
2803 | * @adap: the adapter | ||
2804 | * @mbox: mailbox to use for the FW command | ||
2805 | * @viid: the VI id | ||
2806 | * @nblinks: how many times to blink LED at 2.5 Hz | ||
2807 | * | ||
2808 | * Identifies a VI's port by blinking its LED. | ||
2809 | */ | ||
2810 | int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, | ||
2811 | unsigned int nblinks) | ||
2812 | { | ||
2813 | struct fw_vi_enable_cmd c; | ||
2814 | |||
2815 | c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | | ||
2816 | FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); | ||
2817 | c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); | ||
2818 | c.blinkdur = htons(nblinks); | ||
2819 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2820 | } | ||
2821 | |||
2822 | /** | ||
2823 | * t4_iq_start_stop - enable/disable an ingress queue and its FLs | ||
2824 | * @adap: the adapter | ||
2825 | * @mbox: mailbox to use for the FW command | ||
2826 | * @start: %true to enable the queues, %false to disable them | ||
2827 | * @pf: the PF owning the queues | ||
2828 | * @vf: the VF owning the queues | ||
2829 | * @iqid: ingress queue id | ||
2830 | * @fl0id: FL0 queue id or 0xffff if no attached FL0 | ||
2831 | * @fl1id: FL1 queue id or 0xffff if no attached FL1 | ||
2832 | * | ||
2833 | * Starts or stops an ingress queue and its associated FLs, if any. | ||
2834 | */ | ||
2835 | int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start, | ||
2836 | unsigned int pf, unsigned int vf, unsigned int iqid, | ||
2837 | unsigned int fl0id, unsigned int fl1id) | ||
2838 | { | ||
2839 | struct fw_iq_cmd c; | ||
2840 | |||
2841 | memset(&c, 0, sizeof(c)); | ||
2842 | c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST | | ||
2843 | FW_CMD_EXEC | FW_IQ_CMD_PFN(pf) | | ||
2844 | FW_IQ_CMD_VFN(vf)); | ||
2845 | c.alloc_to_len16 = htonl(FW_IQ_CMD_IQSTART(start) | | ||
2846 | FW_IQ_CMD_IQSTOP(!start) | FW_LEN16(c)); | ||
2847 | c.iqid = htons(iqid); | ||
2848 | c.fl0id = htons(fl0id); | ||
2849 | c.fl1id = htons(fl1id); | ||
2850 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2851 | } | ||
2852 | |||
2853 | /** | ||
2854 | * t4_iq_free - free an ingress queue and its FLs | ||
2855 | * @adap: the adapter | ||
2856 | * @mbox: mailbox to use for the FW command | ||
2857 | * @pf: the PF owning the queues | ||
2858 | * @vf: the VF owning the queues | ||
2859 | * @iqtype: the ingress queue type | ||
2860 | * @iqid: ingress queue id | ||
2861 | * @fl0id: FL0 queue id or 0xffff if no attached FL0 | ||
2862 | * @fl1id: FL1 queue id or 0xffff if no attached FL1 | ||
2863 | * | ||
2864 | * Frees an ingress queue and its associated FLs, if any. | ||
2865 | */ | ||
2866 | int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
2867 | unsigned int vf, unsigned int iqtype, unsigned int iqid, | ||
2868 | unsigned int fl0id, unsigned int fl1id) | ||
2869 | { | ||
2870 | struct fw_iq_cmd c; | ||
2871 | |||
2872 | memset(&c, 0, sizeof(c)); | ||
2873 | c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST | | ||
2874 | FW_CMD_EXEC | FW_IQ_CMD_PFN(pf) | | ||
2875 | FW_IQ_CMD_VFN(vf)); | ||
2876 | c.alloc_to_len16 = htonl(FW_IQ_CMD_FREE | FW_LEN16(c)); | ||
2877 | c.type_to_iqandstindex = htonl(FW_IQ_CMD_TYPE(iqtype)); | ||
2878 | c.iqid = htons(iqid); | ||
2879 | c.fl0id = htons(fl0id); | ||
2880 | c.fl1id = htons(fl1id); | ||
2881 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2882 | } | ||
2883 | |||
2884 | /** | ||
2885 | * t4_eth_eq_free - free an Ethernet egress queue | ||
2886 | * @adap: the adapter | ||
2887 | * @mbox: mailbox to use for the FW command | ||
2888 | * @pf: the PF owning the queue | ||
2889 | * @vf: the VF owning the queue | ||
2890 | * @eqid: egress queue id | ||
2891 | * | ||
2892 | * Frees an Ethernet egress queue. | ||
2893 | */ | ||
2894 | int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
2895 | unsigned int vf, unsigned int eqid) | ||
2896 | { | ||
2897 | struct fw_eq_eth_cmd c; | ||
2898 | |||
2899 | memset(&c, 0, sizeof(c)); | ||
2900 | c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_ETH_CMD) | FW_CMD_REQUEST | | ||
2901 | FW_CMD_EXEC | FW_EQ_ETH_CMD_PFN(pf) | | ||
2902 | FW_EQ_ETH_CMD_VFN(vf)); | ||
2903 | c.alloc_to_len16 = htonl(FW_EQ_ETH_CMD_FREE | FW_LEN16(c)); | ||
2904 | c.eqid_pkd = htonl(FW_EQ_ETH_CMD_EQID(eqid)); | ||
2905 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2906 | } | ||
2907 | |||
2908 | /** | ||
2909 | * t4_ctrl_eq_free - free a control egress queue | ||
2910 | * @adap: the adapter | ||
2911 | * @mbox: mailbox to use for the FW command | ||
2912 | * @pf: the PF owning the queue | ||
2913 | * @vf: the VF owning the queue | ||
2914 | * @eqid: egress queue id | ||
2915 | * | ||
2916 | * Frees a control egress queue. | ||
2917 | */ | ||
2918 | int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
2919 | unsigned int vf, unsigned int eqid) | ||
2920 | { | ||
2921 | struct fw_eq_ctrl_cmd c; | ||
2922 | |||
2923 | memset(&c, 0, sizeof(c)); | ||
2924 | c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_CTRL_CMD) | FW_CMD_REQUEST | | ||
2925 | FW_CMD_EXEC | FW_EQ_CTRL_CMD_PFN(pf) | | ||
2926 | FW_EQ_CTRL_CMD_VFN(vf)); | ||
2927 | c.alloc_to_len16 = htonl(FW_EQ_CTRL_CMD_FREE | FW_LEN16(c)); | ||
2928 | c.cmpliqid_eqid = htonl(FW_EQ_CTRL_CMD_EQID(eqid)); | ||
2929 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2930 | } | ||
2931 | |||
2932 | /** | ||
2933 | * t4_ofld_eq_free - free an offload egress queue | ||
2934 | * @adap: the adapter | ||
2935 | * @mbox: mailbox to use for the FW command | ||
2936 | * @pf: the PF owning the queue | ||
2937 | * @vf: the VF owning the queue | ||
2938 | * @eqid: egress queue id | ||
2939 | * | ||
2940 | * Frees a control egress queue. | ||
2941 | */ | ||
2942 | int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, | ||
2943 | unsigned int vf, unsigned int eqid) | ||
2944 | { | ||
2945 | struct fw_eq_ofld_cmd c; | ||
2946 | |||
2947 | memset(&c, 0, sizeof(c)); | ||
2948 | c.op_to_vfn = htonl(FW_CMD_OP(FW_EQ_OFLD_CMD) | FW_CMD_REQUEST | | ||
2949 | FW_CMD_EXEC | FW_EQ_OFLD_CMD_PFN(pf) | | ||
2950 | FW_EQ_OFLD_CMD_VFN(vf)); | ||
2951 | c.alloc_to_len16 = htonl(FW_EQ_OFLD_CMD_FREE | FW_LEN16(c)); | ||
2952 | c.eqid_pkd = htonl(FW_EQ_OFLD_CMD_EQID(eqid)); | ||
2953 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | ||
2954 | } | ||
2955 | |||
2956 | /** | ||
2957 | * t4_handle_fw_rpl - process a FW reply message | ||
2958 | * @adap: the adapter | ||
2959 | * @rpl: start of the FW message | ||
2960 | * | ||
2961 | * Processes a FW message, such as link state change messages. | ||
2962 | */ | ||
2963 | int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) | ||
2964 | { | ||
2965 | u8 opcode = *(const u8 *)rpl; | ||
2966 | |||
2967 | if (opcode == FW_PORT_CMD) { /* link/module state change message */ | ||
2968 | int speed = 0, fc = 0; | ||
2969 | const struct fw_port_cmd *p = (void *)rpl; | ||
2970 | int chan = FW_PORT_CMD_PORTID_GET(ntohl(p->op_to_portid)); | ||
2971 | int port = adap->chan_map[chan]; | ||
2972 | struct port_info *pi = adap2pinfo(adap, port); | ||
2973 | struct link_config *lc = &pi->link_cfg; | ||
2974 | u32 stat = ntohl(p->u.info.lstatus_to_modtype); | ||
2975 | int link_ok = (stat & FW_PORT_CMD_LSTATUS) != 0; | ||
2976 | u32 mod = FW_PORT_CMD_MODTYPE_GET(stat); | ||
2977 | |||
2978 | if (stat & FW_PORT_CMD_RXPAUSE) | ||
2979 | fc |= PAUSE_RX; | ||
2980 | if (stat & FW_PORT_CMD_TXPAUSE) | ||
2981 | fc |= PAUSE_TX; | ||
2982 | if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) | ||
2983 | speed = SPEED_100; | ||
2984 | else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) | ||
2985 | speed = SPEED_1000; | ||
2986 | else if (stat & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) | ||
2987 | speed = SPEED_10000; | ||
2988 | |||
2989 | if (link_ok != lc->link_ok || speed != lc->speed || | ||
2990 | fc != lc->fc) { /* something changed */ | ||
2991 | lc->link_ok = link_ok; | ||
2992 | lc->speed = speed; | ||
2993 | lc->fc = fc; | ||
2994 | t4_os_link_changed(adap, port, link_ok); | ||
2995 | } | ||
2996 | if (mod != pi->mod_type) { | ||
2997 | pi->mod_type = mod; | ||
2998 | t4_os_portmod_changed(adap, port); | ||
2999 | } | ||
3000 | } | ||
3001 | return 0; | ||
3002 | } | ||
3003 | |||
3004 | static void __devinit get_pci_mode(struct adapter *adapter, | ||
3005 | struct pci_params *p) | ||
3006 | { | ||
3007 | u16 val; | ||
3008 | u32 pcie_cap = pci_pcie_cap(adapter->pdev); | ||
3009 | |||
3010 | if (pcie_cap) { | ||
3011 | pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA, | ||
3012 | &val); | ||
3013 | p->speed = val & PCI_EXP_LNKSTA_CLS; | ||
3014 | p->width = (val & PCI_EXP_LNKSTA_NLW) >> 4; | ||
3015 | } | ||
3016 | } | ||
3017 | |||
3018 | /** | ||
3019 | * init_link_config - initialize a link's SW state | ||
3020 | * @lc: structure holding the link state | ||
3021 | * @caps: link capabilities | ||
3022 | * | ||
3023 | * Initializes the SW state maintained for each link, including the link's | ||
3024 | * capabilities and default speed/flow-control/autonegotiation settings. | ||
3025 | */ | ||
3026 | static void __devinit init_link_config(struct link_config *lc, | ||
3027 | unsigned int caps) | ||
3028 | { | ||
3029 | lc->supported = caps; | ||
3030 | lc->requested_speed = 0; | ||
3031 | lc->speed = 0; | ||
3032 | lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX; | ||
3033 | if (lc->supported & FW_PORT_CAP_ANEG) { | ||
3034 | lc->advertising = lc->supported & ADVERT_MASK; | ||
3035 | lc->autoneg = AUTONEG_ENABLE; | ||
3036 | lc->requested_fc |= PAUSE_AUTONEG; | ||
3037 | } else { | ||
3038 | lc->advertising = 0; | ||
3039 | lc->autoneg = AUTONEG_DISABLE; | ||
3040 | } | ||
3041 | } | ||
3042 | |||
3043 | static int __devinit wait_dev_ready(struct adapter *adap) | ||
3044 | { | ||
3045 | if (t4_read_reg(adap, PL_WHOAMI) != 0xffffffff) | ||
3046 | return 0; | ||
3047 | msleep(500); | ||
3048 | return t4_read_reg(adap, PL_WHOAMI) != 0xffffffff ? 0 : -EIO; | ||
3049 | } | ||
3050 | |||
3051 | /** | ||
3052 | * t4_prep_adapter - prepare SW and HW for operation | ||
3053 | * @adapter: the adapter | ||
3054 | * @reset: if true perform a HW reset | ||
3055 | * | ||
3056 | * Initialize adapter SW state for the various HW modules, set initial | ||
3057 | * values for some adapter tunables, take PHYs out of reset, and | ||
3058 | * initialize the MDIO interface. | ||
3059 | */ | ||
3060 | int __devinit t4_prep_adapter(struct adapter *adapter) | ||
3061 | { | ||
3062 | int ret; | ||
3063 | |||
3064 | ret = wait_dev_ready(adapter); | ||
3065 | if (ret < 0) | ||
3066 | return ret; | ||
3067 | |||
3068 | get_pci_mode(adapter, &adapter->params.pci); | ||
3069 | adapter->params.rev = t4_read_reg(adapter, PL_REV); | ||
3070 | |||
3071 | ret = get_vpd_params(adapter, &adapter->params.vpd); | ||
3072 | if (ret < 0) | ||
3073 | return ret; | ||
3074 | |||
3075 | init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd); | ||
3076 | |||
3077 | /* | ||
3078 | * Default port for debugging in case we can't reach FW. | ||
3079 | */ | ||
3080 | adapter->params.nports = 1; | ||
3081 | adapter->params.portvec = 1; | ||
3082 | return 0; | ||
3083 | } | ||
3084 | |||
3085 | int __devinit t4_port_init(struct adapter *adap, int mbox, int pf, int vf) | ||
3086 | { | ||
3087 | u8 addr[6]; | ||
3088 | int ret, i, j = 0; | ||
3089 | struct fw_port_cmd c; | ||
3090 | |||
3091 | memset(&c, 0, sizeof(c)); | ||
3092 | |||
3093 | for_each_port(adap, i) { | ||
3094 | unsigned int rss_size; | ||
3095 | struct port_info *p = adap2pinfo(adap, i); | ||
3096 | |||
3097 | while ((adap->params.portvec & (1 << j)) == 0) | ||
3098 | j++; | ||
3099 | |||
3100 | c.op_to_portid = htonl(FW_CMD_OP(FW_PORT_CMD) | | ||
3101 | FW_CMD_REQUEST | FW_CMD_READ | | ||
3102 | FW_PORT_CMD_PORTID(j)); | ||
3103 | c.action_to_len16 = htonl( | ||
3104 | FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) | | ||
3105 | FW_LEN16(c)); | ||
3106 | ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); | ||
3107 | if (ret) | ||
3108 | return ret; | ||
3109 | |||
3110 | ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size); | ||
3111 | if (ret < 0) | ||
3112 | return ret; | ||
3113 | |||
3114 | p->viid = ret; | ||
3115 | p->tx_chan = j; | ||
3116 | p->lport = j; | ||
3117 | p->rss_size = rss_size; | ||
3118 | memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN); | ||
3119 | memcpy(adap->port[i]->perm_addr, addr, ETH_ALEN); | ||
3120 | |||
3121 | ret = ntohl(c.u.info.lstatus_to_modtype); | ||
3122 | p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP) ? | ||
3123 | FW_PORT_CMD_MDIOADDR_GET(ret) : -1; | ||
3124 | p->port_type = FW_PORT_CMD_PTYPE_GET(ret); | ||
3125 | p->mod_type = FW_PORT_CMD_MODTYPE_GET(ret); | ||
3126 | |||
3127 | init_link_config(&p->link_cfg, ntohs(c.u.info.pcap)); | ||
3128 | j++; | ||
3129 | } | ||
3130 | return 0; | ||
3131 | } | ||
diff --git a/drivers/net/cxgb4/t4_hw.h b/drivers/net/cxgb4/t4_hw.h new file mode 100644 index 000000000000..025623285c93 --- /dev/null +++ b/drivers/net/cxgb4/t4_hw.h | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * This file is part of the Chelsio T4 Ethernet driver for Linux. | ||
3 | * | ||
4 | * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved. | ||
5 | * | ||
6 | * This software is available to you under a choice of one of two | ||
7 | * licenses. You may choose to be licensed under the terms of the GNU | ||
8 | * General Public License (GPL) Version 2, available from the file | ||
9 | * COPYING in the main directory of this source tree, or the | ||
10 | * OpenIB.org BSD license below: | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or | ||
13 | * without modification, are permitted provided that the following | ||
14 | * conditions are met: | ||
15 | * | ||
16 | * - Redistributions of source code must retain the above | ||
17 | * copyright notice, this list of conditions and the following | ||
18 | * disclaimer. | ||
19 | * | ||
20 | * - Redistributions in binary form must reproduce the above | ||
21 | * copyright notice, this list of conditions and the following | ||
22 | * disclaimer in the documentation and/or other materials | ||
23 | * provided with the distribution. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
32 | * SOFTWARE. | ||
33 | */ | ||
34 | |||
35 | #ifndef __T4_HW_H | ||
36 | #define __T4_HW_H | ||
37 | |||
38 | #include <linux/types.h> | ||
39 | |||
40 | enum { | ||
41 | NCHAN = 4, /* # of HW channels */ | ||
42 | MAX_MTU = 9600, /* max MAC MTU, excluding header + FCS */ | ||
43 | EEPROMSIZE = 17408, /* Serial EEPROM physical size */ | ||
44 | EEPROMVSIZE = 32768, /* Serial EEPROM virtual address space size */ | ||
45 | RSS_NENTRIES = 2048, /* # of entries in RSS mapping table */ | ||
46 | TCB_SIZE = 128, /* TCB size */ | ||
47 | NMTUS = 16, /* size of MTU table */ | ||
48 | NCCTRL_WIN = 32, /* # of congestion control windows */ | ||
49 | NEXACT_MAC = 336, /* # of exact MAC address filters */ | ||
50 | L2T_SIZE = 4096, /* # of L2T entries */ | ||
51 | MBOX_LEN = 64, /* mailbox size in bytes */ | ||
52 | TRACE_LEN = 112, /* length of trace data and mask */ | ||
53 | FILTER_OPT_LEN = 36, /* filter tuple width for optional components */ | ||
54 | NWOL_PAT = 8, /* # of WoL patterns */ | ||
55 | WOL_PAT_LEN = 128, /* length of WoL patterns */ | ||
56 | }; | ||
57 | |||
58 | enum { | ||
59 | SF_PAGE_SIZE = 256, /* serial flash page size */ | ||
60 | SF_SEC_SIZE = 64 * 1024, /* serial flash sector size */ | ||
61 | SF_SIZE = SF_SEC_SIZE * 16, /* serial flash size */ | ||
62 | }; | ||
63 | |||
64 | enum { RSP_TYPE_FLBUF, RSP_TYPE_CPL, RSP_TYPE_INTR }; /* response entry types */ | ||
65 | |||
66 | enum { MBOX_OWNER_NONE, MBOX_OWNER_FW, MBOX_OWNER_DRV }; /* mailbox owners */ | ||
67 | |||
68 | enum { | ||
69 | SGE_MAX_WR_LEN = 512, /* max WR size in bytes */ | ||
70 | SGE_NTIMERS = 6, /* # of interrupt holdoff timer values */ | ||
71 | SGE_NCOUNTERS = 4, /* # of interrupt packet counter values */ | ||
72 | }; | ||
73 | |||
74 | struct sge_qstat { /* data written to SGE queue status entries */ | ||
75 | __be32 qid; | ||
76 | __be16 cidx; | ||
77 | __be16 pidx; | ||
78 | }; | ||
79 | |||
80 | /* | ||
81 | * Structure for last 128 bits of response descriptors | ||
82 | */ | ||
83 | struct rsp_ctrl { | ||
84 | __be32 hdrbuflen_pidx; | ||
85 | __be32 pldbuflen_qid; | ||
86 | union { | ||
87 | u8 type_gen; | ||
88 | __be64 last_flit; | ||
89 | }; | ||
90 | }; | ||
91 | |||
92 | #define RSPD_NEWBUF 0x80000000U | ||
93 | #define RSPD_LEN 0x7fffffffU | ||
94 | |||
95 | #define RSPD_GEN(x) ((x) >> 7) | ||
96 | #define RSPD_TYPE(x) (((x) >> 4) & 3) | ||
97 | |||
98 | #define QINTR_CNT_EN 0x1 | ||
99 | #define QINTR_TIMER_IDX(x) ((x) << 1) | ||
100 | #endif /* __T4_HW_H */ | ||
diff --git a/drivers/net/cxgb4/t4_msg.h b/drivers/net/cxgb4/t4_msg.h new file mode 100644 index 000000000000..fdb117443144 --- /dev/null +++ b/drivers/net/cxgb4/t4_msg.h | |||
@@ -0,0 +1,664 @@ | |||
1 | /* | ||
2 | * This file is part of the Chelsio T4 Ethernet driver for Linux. | ||
3 | * | ||
4 | * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved. | ||
5 | * | ||
6 | * This software is available to you under a choice of one of two | ||
7 | * licenses. You may choose to be licensed under the terms of the GNU | ||
8 | * General Public License (GPL) Version 2, available from the file | ||
9 | * COPYING in the main directory of this source tree, or the | ||
10 | * OpenIB.org BSD license below: | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or | ||
13 | * without modification, are permitted provided that the following | ||
14 | * conditions are met: | ||
15 | * | ||
16 | * - Redistributions of source code must retain the above | ||
17 | * copyright notice, this list of conditions and the following | ||
18 | * disclaimer. | ||
19 | * | ||
20 | * - Redistributions in binary form must reproduce the above | ||
21 | * copyright notice, this list of conditions and the following | ||
22 | * disclaimer in the documentation and/or other materials | ||
23 | * provided with the distribution. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
32 | * SOFTWARE. | ||
33 | */ | ||
34 | |||
35 | #ifndef __T4_MSG_H | ||
36 | #define __T4_MSG_H | ||
37 | |||
38 | #include <linux/types.h> | ||
39 | |||
40 | enum { | ||
41 | CPL_PASS_OPEN_REQ = 0x1, | ||
42 | CPL_PASS_ACCEPT_RPL = 0x2, | ||
43 | CPL_ACT_OPEN_REQ = 0x3, | ||
44 | CPL_SET_TCB_FIELD = 0x5, | ||
45 | CPL_GET_TCB = 0x6, | ||
46 | CPL_CLOSE_CON_REQ = 0x8, | ||
47 | CPL_CLOSE_LISTSRV_REQ = 0x9, | ||
48 | CPL_ABORT_REQ = 0xA, | ||
49 | CPL_ABORT_RPL = 0xB, | ||
50 | CPL_RX_DATA_ACK = 0xD, | ||
51 | CPL_TX_PKT = 0xE, | ||
52 | CPL_L2T_WRITE_REQ = 0x12, | ||
53 | CPL_TID_RELEASE = 0x1A, | ||
54 | |||
55 | CPL_CLOSE_LISTSRV_RPL = 0x20, | ||
56 | CPL_L2T_WRITE_RPL = 0x23, | ||
57 | CPL_PASS_OPEN_RPL = 0x24, | ||
58 | CPL_ACT_OPEN_RPL = 0x25, | ||
59 | CPL_PEER_CLOSE = 0x26, | ||
60 | CPL_ABORT_REQ_RSS = 0x2B, | ||
61 | CPL_ABORT_RPL_RSS = 0x2D, | ||
62 | |||
63 | CPL_CLOSE_CON_RPL = 0x32, | ||
64 | CPL_ISCSI_HDR = 0x33, | ||
65 | CPL_RDMA_CQE = 0x35, | ||
66 | CPL_RDMA_CQE_READ_RSP = 0x36, | ||
67 | CPL_RDMA_CQE_ERR = 0x37, | ||
68 | CPL_RX_DATA = 0x39, | ||
69 | CPL_SET_TCB_RPL = 0x3A, | ||
70 | CPL_RX_PKT = 0x3B, | ||
71 | CPL_RX_DDP_COMPLETE = 0x3F, | ||
72 | |||
73 | CPL_ACT_ESTABLISH = 0x40, | ||
74 | CPL_PASS_ESTABLISH = 0x41, | ||
75 | CPL_RX_DATA_DDP = 0x42, | ||
76 | CPL_PASS_ACCEPT_REQ = 0x44, | ||
77 | |||
78 | CPL_RDMA_READ_REQ = 0x60, | ||
79 | |||
80 | CPL_PASS_OPEN_REQ6 = 0x81, | ||
81 | CPL_ACT_OPEN_REQ6 = 0x83, | ||
82 | |||
83 | CPL_RDMA_TERMINATE = 0xA2, | ||
84 | CPL_RDMA_WRITE = 0xA4, | ||
85 | CPL_SGE_EGR_UPDATE = 0xA5, | ||
86 | |||
87 | CPL_TRACE_PKT = 0xB0, | ||
88 | |||
89 | CPL_FW4_MSG = 0xC0, | ||
90 | CPL_FW4_PLD = 0xC1, | ||
91 | CPL_FW4_ACK = 0xC3, | ||
92 | |||
93 | CPL_FW6_MSG = 0xE0, | ||
94 | CPL_FW6_PLD = 0xE1, | ||
95 | CPL_TX_PKT_LSO = 0xED, | ||
96 | CPL_TX_PKT_XT = 0xEE, | ||
97 | |||
98 | NUM_CPL_CMDS | ||
99 | }; | ||
100 | |||
101 | enum CPL_error { | ||
102 | CPL_ERR_NONE = 0, | ||
103 | CPL_ERR_TCAM_FULL = 3, | ||
104 | CPL_ERR_BAD_LENGTH = 15, | ||
105 | CPL_ERR_BAD_ROUTE = 18, | ||
106 | CPL_ERR_CONN_RESET = 20, | ||
107 | CPL_ERR_CONN_EXIST_SYNRECV = 21, | ||
108 | CPL_ERR_CONN_EXIST = 22, | ||
109 | CPL_ERR_ARP_MISS = 23, | ||
110 | CPL_ERR_BAD_SYN = 24, | ||
111 | CPL_ERR_CONN_TIMEDOUT = 30, | ||
112 | CPL_ERR_XMIT_TIMEDOUT = 31, | ||
113 | CPL_ERR_PERSIST_TIMEDOUT = 32, | ||
114 | CPL_ERR_FINWAIT2_TIMEDOUT = 33, | ||
115 | CPL_ERR_KEEPALIVE_TIMEDOUT = 34, | ||
116 | CPL_ERR_RTX_NEG_ADVICE = 35, | ||
117 | CPL_ERR_PERSIST_NEG_ADVICE = 36, | ||
118 | CPL_ERR_ABORT_FAILED = 42, | ||
119 | CPL_ERR_IWARP_FLM = 50, | ||
120 | }; | ||
121 | |||
122 | enum { | ||
123 | ULP_MODE_NONE = 0, | ||
124 | ULP_MODE_ISCSI = 2, | ||
125 | ULP_MODE_RDMA = 4, | ||
126 | ULP_MODE_FCOE = 6, | ||
127 | }; | ||
128 | |||
129 | enum { | ||
130 | ULP_CRC_HEADER = 1 << 0, | ||
131 | ULP_CRC_DATA = 1 << 1 | ||
132 | }; | ||
133 | |||
134 | enum { | ||
135 | CPL_ABORT_SEND_RST = 0, | ||
136 | CPL_ABORT_NO_RST, | ||
137 | }; | ||
138 | |||
139 | enum { /* TX_PKT_XT checksum types */ | ||
140 | TX_CSUM_TCP = 0, | ||
141 | TX_CSUM_UDP = 1, | ||
142 | TX_CSUM_CRC16 = 4, | ||
143 | TX_CSUM_CRC32 = 5, | ||
144 | TX_CSUM_CRC32C = 6, | ||
145 | TX_CSUM_FCOE = 7, | ||
146 | TX_CSUM_TCPIP = 8, | ||
147 | TX_CSUM_UDPIP = 9, | ||
148 | TX_CSUM_TCPIP6 = 10, | ||
149 | TX_CSUM_UDPIP6 = 11, | ||
150 | TX_CSUM_IP = 12, | ||
151 | }; | ||
152 | |||
153 | union opcode_tid { | ||
154 | __be32 opcode_tid; | ||
155 | u8 opcode; | ||
156 | }; | ||
157 | |||
158 | #define CPL_OPCODE(x) ((x) << 24) | ||
159 | #define MK_OPCODE_TID(opcode, tid) (CPL_OPCODE(opcode) | (tid)) | ||
160 | #define OPCODE_TID(cmd) ((cmd)->ot.opcode_tid) | ||
161 | #define GET_TID(cmd) (ntohl(OPCODE_TID(cmd)) & 0xFFFFFF) | ||
162 | |||
163 | /* partitioning of TID fields that also carry a queue id */ | ||
164 | #define GET_TID_TID(x) ((x) & 0x3fff) | ||
165 | #define GET_TID_QID(x) (((x) >> 14) & 0x3ff) | ||
166 | #define TID_QID(x) ((x) << 14) | ||
167 | |||
168 | struct rss_header { | ||
169 | u8 opcode; | ||
170 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
171 | u8 channel:2; | ||
172 | u8 filter_hit:1; | ||
173 | u8 filter_tid:1; | ||
174 | u8 hash_type:2; | ||
175 | u8 ipv6:1; | ||
176 | u8 send2fw:1; | ||
177 | #else | ||
178 | u8 send2fw:1; | ||
179 | u8 ipv6:1; | ||
180 | u8 hash_type:2; | ||
181 | u8 filter_tid:1; | ||
182 | u8 filter_hit:1; | ||
183 | u8 channel:2; | ||
184 | #endif | ||
185 | __be16 qid; | ||
186 | __be32 hash_val; | ||
187 | }; | ||
188 | |||
189 | struct work_request_hdr { | ||
190 | __be32 wr_hi; | ||
191 | __be32 wr_mid; | ||
192 | __be64 wr_lo; | ||
193 | }; | ||
194 | |||
195 | #define WR_HDR struct work_request_hdr wr | ||
196 | |||
197 | struct cpl_pass_open_req { | ||
198 | WR_HDR; | ||
199 | union opcode_tid ot; | ||
200 | __be16 local_port; | ||
201 | __be16 peer_port; | ||
202 | __be32 local_ip; | ||
203 | __be32 peer_ip; | ||
204 | __be64 opt0; | ||
205 | #define TX_CHAN(x) ((x) << 2) | ||
206 | #define DELACK(x) ((x) << 5) | ||
207 | #define ULP_MODE(x) ((x) << 8) | ||
208 | #define RCV_BUFSIZ(x) ((x) << 12) | ||
209 | #define DSCP(x) ((x) << 22) | ||
210 | #define SMAC_SEL(x) ((u64)(x) << 28) | ||
211 | #define L2T_IDX(x) ((u64)(x) << 36) | ||
212 | #define NAGLE(x) ((u64)(x) << 49) | ||
213 | #define WND_SCALE(x) ((u64)(x) << 50) | ||
214 | #define KEEP_ALIVE(x) ((u64)(x) << 54) | ||
215 | #define MSS_IDX(x) ((u64)(x) << 60) | ||
216 | __be64 opt1; | ||
217 | #define SYN_RSS_ENABLE (1 << 0) | ||
218 | #define SYN_RSS_QUEUE(x) ((x) << 2) | ||
219 | #define CONN_POLICY_ASK (1 << 22) | ||
220 | }; | ||
221 | |||
222 | struct cpl_pass_open_req6 { | ||
223 | WR_HDR; | ||
224 | union opcode_tid ot; | ||
225 | __be16 local_port; | ||
226 | __be16 peer_port; | ||
227 | __be64 local_ip_hi; | ||
228 | __be64 local_ip_lo; | ||
229 | __be64 peer_ip_hi; | ||
230 | __be64 peer_ip_lo; | ||
231 | __be64 opt0; | ||
232 | __be64 opt1; | ||
233 | }; | ||
234 | |||
235 | struct cpl_pass_open_rpl { | ||
236 | union opcode_tid ot; | ||
237 | u8 rsvd[3]; | ||
238 | u8 status; | ||
239 | }; | ||
240 | |||
241 | struct cpl_pass_accept_rpl { | ||
242 | WR_HDR; | ||
243 | union opcode_tid ot; | ||
244 | __be32 opt2; | ||
245 | #define RSS_QUEUE(x) ((x) << 0) | ||
246 | #define RSS_QUEUE_VALID (1 << 10) | ||
247 | #define RX_COALESCE_VALID(x) ((x) << 11) | ||
248 | #define RX_COALESCE(x) ((x) << 12) | ||
249 | #define TX_QUEUE(x) ((x) << 23) | ||
250 | #define RX_CHANNEL(x) ((x) << 26) | ||
251 | #define WND_SCALE_EN(x) ((x) << 28) | ||
252 | #define TSTAMPS_EN(x) ((x) << 29) | ||
253 | #define SACK_EN(x) ((x) << 30) | ||
254 | __be64 opt0; | ||
255 | }; | ||
256 | |||
257 | struct cpl_act_open_req { | ||
258 | WR_HDR; | ||
259 | union opcode_tid ot; | ||
260 | __be16 local_port; | ||
261 | __be16 peer_port; | ||
262 | __be32 local_ip; | ||
263 | __be32 peer_ip; | ||
264 | __be64 opt0; | ||
265 | __be32 params; | ||
266 | __be32 opt2; | ||
267 | }; | ||
268 | |||
269 | struct cpl_act_open_req6 { | ||
270 | WR_HDR; | ||
271 | union opcode_tid ot; | ||
272 | __be16 local_port; | ||
273 | __be16 peer_port; | ||
274 | __be64 local_ip_hi; | ||
275 | __be64 local_ip_lo; | ||
276 | __be64 peer_ip_hi; | ||
277 | __be64 peer_ip_lo; | ||
278 | __be64 opt0; | ||
279 | __be32 params; | ||
280 | __be32 opt2; | ||
281 | }; | ||
282 | |||
283 | struct cpl_act_open_rpl { | ||
284 | union opcode_tid ot; | ||
285 | __be32 atid_status; | ||
286 | #define GET_AOPEN_STATUS(x) ((x) & 0xff) | ||
287 | #define GET_AOPEN_ATID(x) (((x) >> 8) & 0xffffff) | ||
288 | }; | ||
289 | |||
290 | struct cpl_pass_establish { | ||
291 | union opcode_tid ot; | ||
292 | __be32 rsvd; | ||
293 | __be32 tos_stid; | ||
294 | #define GET_POPEN_TID(x) ((x) & 0xffffff) | ||
295 | #define GET_POPEN_TOS(x) (((x) >> 24) & 0xff) | ||
296 | __be16 mac_idx; | ||
297 | __be16 tcp_opt; | ||
298 | #define GET_TCPOPT_WSCALE_OK(x) (((x) >> 5) & 1) | ||
299 | #define GET_TCPOPT_SACK(x) (((x) >> 6) & 1) | ||
300 | #define GET_TCPOPT_TSTAMP(x) (((x) >> 7) & 1) | ||
301 | #define GET_TCPOPT_SND_WSCALE(x) (((x) >> 8) & 0xf) | ||
302 | #define GET_TCPOPT_MSS(x) (((x) >> 12) & 0xf) | ||
303 | __be32 snd_isn; | ||
304 | __be32 rcv_isn; | ||
305 | }; | ||
306 | |||
307 | struct cpl_act_establish { | ||
308 | union opcode_tid ot; | ||
309 | __be32 rsvd; | ||
310 | __be32 tos_atid; | ||
311 | __be16 mac_idx; | ||
312 | __be16 tcp_opt; | ||
313 | __be32 snd_isn; | ||
314 | __be32 rcv_isn; | ||
315 | }; | ||
316 | |||
317 | struct cpl_get_tcb { | ||
318 | WR_HDR; | ||
319 | union opcode_tid ot; | ||
320 | __be16 reply_ctrl; | ||
321 | #define QUEUENO(x) ((x) << 0) | ||
322 | #define REPLY_CHAN(x) ((x) << 14) | ||
323 | #define NO_REPLY(x) ((x) << 15) | ||
324 | __be16 cookie; | ||
325 | }; | ||
326 | |||
327 | struct cpl_set_tcb_field { | ||
328 | WR_HDR; | ||
329 | union opcode_tid ot; | ||
330 | __be16 reply_ctrl; | ||
331 | __be16 word_cookie; | ||
332 | #define TCB_WORD(x) ((x) << 0) | ||
333 | #define TCB_COOKIE(x) ((x) << 5) | ||
334 | __be64 mask; | ||
335 | __be64 val; | ||
336 | }; | ||
337 | |||
338 | struct cpl_set_tcb_rpl { | ||
339 | union opcode_tid ot; | ||
340 | __be16 rsvd; | ||
341 | u8 cookie; | ||
342 | u8 status; | ||
343 | __be64 oldval; | ||
344 | }; | ||
345 | |||
346 | struct cpl_close_con_req { | ||
347 | WR_HDR; | ||
348 | union opcode_tid ot; | ||
349 | __be32 rsvd; | ||
350 | }; | ||
351 | |||
352 | struct cpl_close_con_rpl { | ||
353 | union opcode_tid ot; | ||
354 | u8 rsvd[3]; | ||
355 | u8 status; | ||
356 | __be32 snd_nxt; | ||
357 | __be32 rcv_nxt; | ||
358 | }; | ||
359 | |||
360 | struct cpl_close_listsvr_req { | ||
361 | WR_HDR; | ||
362 | union opcode_tid ot; | ||
363 | __be16 reply_ctrl; | ||
364 | #define LISTSVR_IPV6 (1 << 14) | ||
365 | __be16 rsvd; | ||
366 | }; | ||
367 | |||
368 | struct cpl_close_listsvr_rpl { | ||
369 | union opcode_tid ot; | ||
370 | u8 rsvd[3]; | ||
371 | u8 status; | ||
372 | }; | ||
373 | |||
374 | struct cpl_abort_req_rss { | ||
375 | union opcode_tid ot; | ||
376 | u8 rsvd[3]; | ||
377 | u8 status; | ||
378 | }; | ||
379 | |||
380 | struct cpl_abort_req { | ||
381 | WR_HDR; | ||
382 | union opcode_tid ot; | ||
383 | __be32 rsvd0; | ||
384 | u8 rsvd1; | ||
385 | u8 cmd; | ||
386 | u8 rsvd2[6]; | ||
387 | }; | ||
388 | |||
389 | struct cpl_abort_rpl_rss { | ||
390 | union opcode_tid ot; | ||
391 | u8 rsvd[3]; | ||
392 | u8 status; | ||
393 | }; | ||
394 | |||
395 | struct cpl_abort_rpl { | ||
396 | WR_HDR; | ||
397 | union opcode_tid ot; | ||
398 | __be32 rsvd0; | ||
399 | u8 rsvd1; | ||
400 | u8 cmd; | ||
401 | u8 rsvd2[6]; | ||
402 | }; | ||
403 | |||
404 | struct cpl_peer_close { | ||
405 | union opcode_tid ot; | ||
406 | __be32 rcv_nxt; | ||
407 | }; | ||
408 | |||
409 | struct cpl_tid_release { | ||
410 | WR_HDR; | ||
411 | union opcode_tid ot; | ||
412 | __be32 rsvd; | ||
413 | }; | ||
414 | |||
415 | struct cpl_tx_pkt_core { | ||
416 | __be32 ctrl0; | ||
417 | #define TXPKT_VF(x) ((x) << 0) | ||
418 | #define TXPKT_PF(x) ((x) << 8) | ||
419 | #define TXPKT_VF_VLD (1 << 11) | ||
420 | #define TXPKT_OVLAN_IDX(x) ((x) << 12) | ||
421 | #define TXPKT_INTF(x) ((x) << 16) | ||
422 | #define TXPKT_INS_OVLAN (1 << 21) | ||
423 | #define TXPKT_OPCODE(x) ((x) << 24) | ||
424 | __be16 pack; | ||
425 | __be16 len; | ||
426 | __be64 ctrl1; | ||
427 | #define TXPKT_CSUM_END(x) ((x) << 12) | ||
428 | #define TXPKT_CSUM_START(x) ((x) << 20) | ||
429 | #define TXPKT_IPHDR_LEN(x) ((u64)(x) << 20) | ||
430 | #define TXPKT_CSUM_LOC(x) ((u64)(x) << 30) | ||
431 | #define TXPKT_ETHHDR_LEN(x) ((u64)(x) << 34) | ||
432 | #define TXPKT_CSUM_TYPE(x) ((u64)(x) << 40) | ||
433 | #define TXPKT_VLAN(x) ((u64)(x) << 44) | ||
434 | #define TXPKT_VLAN_VLD (1ULL << 60) | ||
435 | #define TXPKT_IPCSUM_DIS (1ULL << 62) | ||
436 | #define TXPKT_L4CSUM_DIS (1ULL << 63) | ||
437 | }; | ||
438 | |||
439 | struct cpl_tx_pkt { | ||
440 | WR_HDR; | ||
441 | struct cpl_tx_pkt_core c; | ||
442 | }; | ||
443 | |||
444 | #define cpl_tx_pkt_xt cpl_tx_pkt | ||
445 | |||
446 | struct cpl_tx_pkt_lso { | ||
447 | WR_HDR; | ||
448 | __be32 lso_ctrl; | ||
449 | #define LSO_TCPHDR_LEN(x) ((x) << 0) | ||
450 | #define LSO_IPHDR_LEN(x) ((x) << 4) | ||
451 | #define LSO_ETHHDR_LEN(x) ((x) << 16) | ||
452 | #define LSO_IPV6(x) ((x) << 20) | ||
453 | #define LSO_LAST_SLICE (1 << 22) | ||
454 | #define LSO_FIRST_SLICE (1 << 23) | ||
455 | #define LSO_OPCODE(x) ((x) << 24) | ||
456 | __be16 ipid_ofst; | ||
457 | __be16 mss; | ||
458 | __be32 seqno_offset; | ||
459 | __be32 len; | ||
460 | /* encapsulated CPL (TX_PKT, TX_PKT_XT or TX_DATA) follows here */ | ||
461 | }; | ||
462 | |||
463 | struct cpl_iscsi_hdr { | ||
464 | union opcode_tid ot; | ||
465 | __be16 pdu_len_ddp; | ||
466 | #define ISCSI_PDU_LEN(x) ((x) & 0x7FFF) | ||
467 | #define ISCSI_DDP (1 << 15) | ||
468 | __be16 len; | ||
469 | __be32 seq; | ||
470 | __be16 urg; | ||
471 | u8 rsvd; | ||
472 | u8 status; | ||
473 | }; | ||
474 | |||
475 | struct cpl_rx_data { | ||
476 | union opcode_tid ot; | ||
477 | __be16 rsvd; | ||
478 | __be16 len; | ||
479 | __be32 seq; | ||
480 | __be16 urg; | ||
481 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
482 | u8 dack_mode:2; | ||
483 | u8 psh:1; | ||
484 | u8 heartbeat:1; | ||
485 | u8 ddp_off:1; | ||
486 | u8 :3; | ||
487 | #else | ||
488 | u8 :3; | ||
489 | u8 ddp_off:1; | ||
490 | u8 heartbeat:1; | ||
491 | u8 psh:1; | ||
492 | u8 dack_mode:2; | ||
493 | #endif | ||
494 | u8 status; | ||
495 | }; | ||
496 | |||
497 | struct cpl_rx_data_ack { | ||
498 | WR_HDR; | ||
499 | union opcode_tid ot; | ||
500 | __be32 credit_dack; | ||
501 | #define RX_CREDITS(x) ((x) << 0) | ||
502 | #define RX_FORCE_ACK(x) ((x) << 28) | ||
503 | }; | ||
504 | |||
505 | struct cpl_rx_pkt { | ||
506 | u8 opcode; | ||
507 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
508 | u8 iff:4; | ||
509 | u8 csum_calc:1; | ||
510 | u8 ipmi_pkt:1; | ||
511 | u8 vlan_ex:1; | ||
512 | u8 ip_frag:1; | ||
513 | #else | ||
514 | u8 ip_frag:1; | ||
515 | u8 vlan_ex:1; | ||
516 | u8 ipmi_pkt:1; | ||
517 | u8 csum_calc:1; | ||
518 | u8 iff:4; | ||
519 | #endif | ||
520 | __be16 csum; | ||
521 | __be16 vlan; | ||
522 | __be16 len; | ||
523 | __be32 l2info; | ||
524 | #define RXF_UDP (1 << 22) | ||
525 | #define RXF_TCP (1 << 23) | ||
526 | __be16 hdr_len; | ||
527 | __be16 err_vec; | ||
528 | }; | ||
529 | |||
530 | struct cpl_trace_pkt { | ||
531 | u8 opcode; | ||
532 | u8 intf; | ||
533 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
534 | u8 runt:4; | ||
535 | u8 filter_hit:4; | ||
536 | u8 :6; | ||
537 | u8 err:1; | ||
538 | u8 trunc:1; | ||
539 | #else | ||
540 | u8 filter_hit:4; | ||
541 | u8 runt:4; | ||
542 | u8 trunc:1; | ||
543 | u8 err:1; | ||
544 | u8 :6; | ||
545 | #endif | ||
546 | __be16 rsvd; | ||
547 | __be16 len; | ||
548 | __be64 tstamp; | ||
549 | }; | ||
550 | |||
551 | struct cpl_l2t_write_req { | ||
552 | WR_HDR; | ||
553 | union opcode_tid ot; | ||
554 | __be16 params; | ||
555 | #define L2T_W_INFO(x) ((x) << 2) | ||
556 | #define L2T_W_PORT(x) ((x) << 8) | ||
557 | #define L2T_W_NOREPLY(x) ((x) << 15) | ||
558 | __be16 l2t_idx; | ||
559 | __be16 vlan; | ||
560 | u8 dst_mac[6]; | ||
561 | }; | ||
562 | |||
563 | struct cpl_l2t_write_rpl { | ||
564 | union opcode_tid ot; | ||
565 | u8 status; | ||
566 | u8 rsvd[3]; | ||
567 | }; | ||
568 | |||
569 | struct cpl_rdma_terminate { | ||
570 | union opcode_tid ot; | ||
571 | __be16 rsvd; | ||
572 | __be16 len; | ||
573 | }; | ||
574 | |||
575 | struct cpl_sge_egr_update { | ||
576 | __be32 opcode_qid; | ||
577 | #define EGR_QID(x) ((x) & 0x1FFFF) | ||
578 | __be16 cidx; | ||
579 | __be16 pidx; | ||
580 | }; | ||
581 | |||
582 | struct cpl_fw4_pld { | ||
583 | u8 opcode; | ||
584 | u8 rsvd0[3]; | ||
585 | u8 type; | ||
586 | u8 rsvd1; | ||
587 | __be16 len; | ||
588 | __be64 data; | ||
589 | __be64 rsvd2; | ||
590 | }; | ||
591 | |||
592 | struct cpl_fw6_pld { | ||
593 | u8 opcode; | ||
594 | u8 rsvd[5]; | ||
595 | __be16 len; | ||
596 | __be64 data[4]; | ||
597 | }; | ||
598 | |||
599 | struct cpl_fw4_msg { | ||
600 | u8 opcode; | ||
601 | u8 type; | ||
602 | __be16 rsvd0; | ||
603 | __be32 rsvd1; | ||
604 | __be64 data[2]; | ||
605 | }; | ||
606 | |||
607 | struct cpl_fw4_ack { | ||
608 | union opcode_tid ot; | ||
609 | u8 credits; | ||
610 | u8 rsvd0[2]; | ||
611 | u8 seq_vld; | ||
612 | __be32 snd_nxt; | ||
613 | __be32 snd_una; | ||
614 | __be64 rsvd1; | ||
615 | }; | ||
616 | |||
617 | struct cpl_fw6_msg { | ||
618 | u8 opcode; | ||
619 | u8 type; | ||
620 | __be16 rsvd0; | ||
621 | __be32 rsvd1; | ||
622 | __be64 data[4]; | ||
623 | }; | ||
624 | |||
625 | enum { | ||
626 | ULP_TX_MEM_READ = 2, | ||
627 | ULP_TX_MEM_WRITE = 3, | ||
628 | ULP_TX_PKT = 4 | ||
629 | }; | ||
630 | |||
631 | enum { | ||
632 | ULP_TX_SC_NOOP = 0x80, | ||
633 | ULP_TX_SC_IMM = 0x81, | ||
634 | ULP_TX_SC_DSGL = 0x82, | ||
635 | ULP_TX_SC_ISGL = 0x83 | ||
636 | }; | ||
637 | |||
638 | struct ulptx_sge_pair { | ||
639 | __be32 len[2]; | ||
640 | __be64 addr[2]; | ||
641 | }; | ||
642 | |||
643 | struct ulptx_sgl { | ||
644 | __be32 cmd_nsge; | ||
645 | #define ULPTX_CMD(x) ((x) << 24) | ||
646 | #define ULPTX_NSGE(x) ((x) << 0) | ||
647 | __be32 len0; | ||
648 | __be64 addr0; | ||
649 | struct ulptx_sge_pair sge[0]; | ||
650 | }; | ||
651 | |||
652 | struct ulp_mem_io { | ||
653 | WR_HDR; | ||
654 | __be32 cmd; | ||
655 | #define ULP_MEMIO_ORDER(x) ((x) << 23) | ||
656 | __be32 len16; /* command length */ | ||
657 | __be32 dlen; /* data length in 32-byte units */ | ||
658 | #define ULP_MEMIO_DATA_LEN(x) ((x) << 0) | ||
659 | __be32 lock_addr; | ||
660 | #define ULP_MEMIO_ADDR(x) ((x) << 0) | ||
661 | #define ULP_MEMIO_LOCK(x) ((x) << 31) | ||
662 | }; | ||
663 | |||
664 | #endif /* __T4_MSG_H */ | ||
diff --git a/drivers/net/cxgb4/t4_regs.h b/drivers/net/cxgb4/t4_regs.h new file mode 100644 index 000000000000..5ed56483cbc2 --- /dev/null +++ b/drivers/net/cxgb4/t4_regs.h | |||
@@ -0,0 +1,878 @@ | |||
1 | /* | ||
2 | * This file is part of the Chelsio T4 Ethernet driver for Linux. | ||
3 | * | ||
4 | * Copyright (c) 2010 Chelsio Communications, Inc. All rights reserved. | ||
5 | * | ||
6 | * This software is available to you under a choice of one of two | ||
7 | * licenses. You may choose to be licensed under the terms of the GNU | ||
8 | * General Public License (GPL) Version 2, available from the file | ||
9 | * COPYING in the main directory of this source tree, or the | ||
10 | * OpenIB.org BSD license below: | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or | ||
13 | * without modification, are permitted provided that the following | ||
14 | * conditions are met: | ||
15 | * | ||
16 | * - Redistributions of source code must retain the above | ||
17 | * copyright notice, this list of conditions and the following | ||
18 | * disclaimer. | ||
19 | * | ||
20 | * - Redistributions in binary form must reproduce the above | ||
21 | * copyright notice, this list of conditions and the following | ||
22 | * disclaimer in the documentation and/or other materials | ||
23 | * provided with the distribution. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
32 | * SOFTWARE. | ||
33 | */ | ||
34 | |||
35 | #ifndef __T4_REGS_H | ||
36 | #define __T4_REGS_H | ||
37 | |||
38 | #define MYPF_BASE 0x1b000 | ||
39 | #define MYPF_REG(reg_addr) (MYPF_BASE + (reg_addr)) | ||
40 | |||
41 | #define PF0_BASE 0x1e000 | ||
42 | #define PF0_REG(reg_addr) (PF0_BASE + (reg_addr)) | ||
43 | |||
44 | #define PF_STRIDE 0x400 | ||
45 | #define PF_BASE(idx) (PF0_BASE + (idx) * PF_STRIDE) | ||
46 | #define PF_REG(idx, reg) (PF_BASE(idx) + (reg)) | ||
47 | |||
48 | #define MYPORT_BASE 0x1c000 | ||
49 | #define MYPORT_REG(reg_addr) (MYPORT_BASE + (reg_addr)) | ||
50 | |||
51 | #define PORT0_BASE 0x20000 | ||
52 | #define PORT0_REG(reg_addr) (PORT0_BASE + (reg_addr)) | ||
53 | |||
54 | #define PORT_STRIDE 0x2000 | ||
55 | #define PORT_BASE(idx) (PORT0_BASE + (idx) * PORT_STRIDE) | ||
56 | #define PORT_REG(idx, reg) (PORT_BASE(idx) + (reg)) | ||
57 | |||
58 | #define EDC_STRIDE (EDC_1_BASE_ADDR - EDC_0_BASE_ADDR) | ||
59 | #define EDC_REG(reg, idx) (reg + EDC_STRIDE * idx) | ||
60 | |||
61 | #define PCIE_MEM_ACCESS_REG(reg_addr, idx) ((reg_addr) + (idx) * 8) | ||
62 | #define PCIE_MAILBOX_REG(reg_addr, idx) ((reg_addr) + (idx) * 8) | ||
63 | #define MC_BIST_STATUS_REG(reg_addr, idx) ((reg_addr) + (idx) * 4) | ||
64 | #define EDC_BIST_STATUS_REG(reg_addr, idx) ((reg_addr) + (idx) * 4) | ||
65 | |||
66 | #define SGE_PF_KDOORBELL 0x0 | ||
67 | #define QID_MASK 0xffff8000U | ||
68 | #define QID_SHIFT 15 | ||
69 | #define QID(x) ((x) << QID_SHIFT) | ||
70 | #define DBPRIO 0x00004000U | ||
71 | #define PIDX_MASK 0x00003fffU | ||
72 | #define PIDX_SHIFT 0 | ||
73 | #define PIDX(x) ((x) << PIDX_SHIFT) | ||
74 | |||
75 | #define SGE_PF_GTS 0x4 | ||
76 | #define INGRESSQID_MASK 0xffff0000U | ||
77 | #define INGRESSQID_SHIFT 16 | ||
78 | #define INGRESSQID(x) ((x) << INGRESSQID_SHIFT) | ||
79 | #define TIMERREG_MASK 0x0000e000U | ||
80 | #define TIMERREG_SHIFT 13 | ||
81 | #define TIMERREG(x) ((x) << TIMERREG_SHIFT) | ||
82 | #define SEINTARM_MASK 0x00001000U | ||
83 | #define SEINTARM_SHIFT 12 | ||
84 | #define SEINTARM(x) ((x) << SEINTARM_SHIFT) | ||
85 | #define CIDXINC_MASK 0x00000fffU | ||
86 | #define CIDXINC_SHIFT 0 | ||
87 | #define CIDXINC(x) ((x) << CIDXINC_SHIFT) | ||
88 | |||
89 | #define SGE_CONTROL 0x1008 | ||
90 | #define DCASYSTYPE 0x00080000U | ||
91 | #define RXPKTCPLMODE 0x00040000U | ||
92 | #define EGRSTATUSPAGESIZE 0x00020000U | ||
93 | #define PKTSHIFT_MASK 0x00001c00U | ||
94 | #define PKTSHIFT_SHIFT 10 | ||
95 | #define PKTSHIFT(x) ((x) << PKTSHIFT_SHIFT) | ||
96 | #define INGPCIEBOUNDARY_MASK 0x00000380U | ||
97 | #define INGPCIEBOUNDARY_SHIFT 7 | ||
98 | #define INGPCIEBOUNDARY(x) ((x) << INGPCIEBOUNDARY_SHIFT) | ||
99 | #define INGPADBOUNDARY_MASK 0x00000070U | ||
100 | #define INGPADBOUNDARY_SHIFT 4 | ||
101 | #define INGPADBOUNDARY(x) ((x) << INGPADBOUNDARY_SHIFT) | ||
102 | #define EGRPCIEBOUNDARY_MASK 0x0000000eU | ||
103 | #define EGRPCIEBOUNDARY_SHIFT 1 | ||
104 | #define EGRPCIEBOUNDARY(x) ((x) << EGRPCIEBOUNDARY_SHIFT) | ||
105 | #define GLOBALENABLE 0x00000001U | ||
106 | |||
107 | #define SGE_HOST_PAGE_SIZE 0x100c | ||
108 | #define HOSTPAGESIZEPF0_MASK 0x0000000fU | ||
109 | #define HOSTPAGESIZEPF0_SHIFT 0 | ||
110 | #define HOSTPAGESIZEPF0(x) ((x) << HOSTPAGESIZEPF0_SHIFT) | ||
111 | |||
112 | #define SGE_EGRESS_QUEUES_PER_PAGE_PF 0x1010 | ||
113 | #define QUEUESPERPAGEPF0_MASK 0x0000000fU | ||
114 | #define QUEUESPERPAGEPF0_GET(x) ((x) & QUEUESPERPAGEPF0_MASK) | ||
115 | |||
116 | #define SGE_INT_CAUSE1 0x1024 | ||
117 | #define SGE_INT_CAUSE2 0x1030 | ||
118 | #define SGE_INT_CAUSE3 0x103c | ||
119 | #define ERR_FLM_DBP 0x80000000U | ||
120 | #define ERR_FLM_IDMA1 0x40000000U | ||
121 | #define ERR_FLM_IDMA0 0x20000000U | ||
122 | #define ERR_FLM_HINT 0x10000000U | ||
123 | #define ERR_PCIE_ERROR3 0x08000000U | ||
124 | #define ERR_PCIE_ERROR2 0x04000000U | ||
125 | #define ERR_PCIE_ERROR1 0x02000000U | ||
126 | #define ERR_PCIE_ERROR0 0x01000000U | ||
127 | #define ERR_TIMER_ABOVE_MAX_QID 0x00800000U | ||
128 | #define ERR_CPL_EXCEED_IQE_SIZE 0x00400000U | ||
129 | #define ERR_INVALID_CIDX_INC 0x00200000U | ||
130 | #define ERR_ITP_TIME_PAUSED 0x00100000U | ||
131 | #define ERR_CPL_OPCODE_0 0x00080000U | ||
132 | #define ERR_DROPPED_DB 0x00040000U | ||
133 | #define ERR_DATA_CPL_ON_HIGH_QID1 0x00020000U | ||
134 | #define ERR_DATA_CPL_ON_HIGH_QID0 0x00010000U | ||
135 | #define ERR_BAD_DB_PIDX3 0x00008000U | ||
136 | #define ERR_BAD_DB_PIDX2 0x00004000U | ||
137 | #define ERR_BAD_DB_PIDX1 0x00002000U | ||
138 | #define ERR_BAD_DB_PIDX0 0x00001000U | ||
139 | #define ERR_ING_PCIE_CHAN 0x00000800U | ||
140 | #define ERR_ING_CTXT_PRIO 0x00000400U | ||
141 | #define ERR_EGR_CTXT_PRIO 0x00000200U | ||
142 | #define DBFIFO_HP_INT 0x00000100U | ||
143 | #define DBFIFO_LP_INT 0x00000080U | ||
144 | #define REG_ADDRESS_ERR 0x00000040U | ||
145 | #define INGRESS_SIZE_ERR 0x00000020U | ||
146 | #define EGRESS_SIZE_ERR 0x00000010U | ||
147 | #define ERR_INV_CTXT3 0x00000008U | ||
148 | #define ERR_INV_CTXT2 0x00000004U | ||
149 | #define ERR_INV_CTXT1 0x00000002U | ||
150 | #define ERR_INV_CTXT0 0x00000001U | ||
151 | |||
152 | #define SGE_INT_ENABLE3 0x1040 | ||
153 | #define SGE_FL_BUFFER_SIZE0 0x1044 | ||
154 | #define SGE_FL_BUFFER_SIZE1 0x1048 | ||
155 | #define SGE_INGRESS_RX_THRESHOLD 0x10a0 | ||
156 | #define THRESHOLD_0_MASK 0x3f000000U | ||
157 | #define THRESHOLD_0_SHIFT 24 | ||
158 | #define THRESHOLD_0(x) ((x) << THRESHOLD_0_SHIFT) | ||
159 | #define THRESHOLD_0_GET(x) (((x) & THRESHOLD_0_MASK) >> THRESHOLD_0_SHIFT) | ||
160 | #define THRESHOLD_1_MASK 0x003f0000U | ||
161 | #define THRESHOLD_1_SHIFT 16 | ||
162 | #define THRESHOLD_1(x) ((x) << THRESHOLD_1_SHIFT) | ||
163 | #define THRESHOLD_1_GET(x) (((x) & THRESHOLD_1_MASK) >> THRESHOLD_1_SHIFT) | ||
164 | #define THRESHOLD_2_MASK 0x00003f00U | ||
165 | #define THRESHOLD_2_SHIFT 8 | ||
166 | #define THRESHOLD_2(x) ((x) << THRESHOLD_2_SHIFT) | ||
167 | #define THRESHOLD_2_GET(x) (((x) & THRESHOLD_2_MASK) >> THRESHOLD_2_SHIFT) | ||
168 | #define THRESHOLD_3_MASK 0x0000003fU | ||
169 | #define THRESHOLD_3_SHIFT 0 | ||
170 | #define THRESHOLD_3(x) ((x) << THRESHOLD_3_SHIFT) | ||
171 | #define THRESHOLD_3_GET(x) (((x) & THRESHOLD_3_MASK) >> THRESHOLD_3_SHIFT) | ||
172 | |||
173 | #define SGE_TIMER_VALUE_0_AND_1 0x10b8 | ||
174 | #define TIMERVALUE0_MASK 0xffff0000U | ||
175 | #define TIMERVALUE0_SHIFT 16 | ||
176 | #define TIMERVALUE0(x) ((x) << TIMERVALUE0_SHIFT) | ||
177 | #define TIMERVALUE0_GET(x) (((x) & TIMERVALUE0_MASK) >> TIMERVALUE0_SHIFT) | ||
178 | #define TIMERVALUE1_MASK 0x0000ffffU | ||
179 | #define TIMERVALUE1_SHIFT 0 | ||
180 | #define TIMERVALUE1(x) ((x) << TIMERVALUE1_SHIFT) | ||
181 | #define TIMERVALUE1_GET(x) (((x) & TIMERVALUE1_MASK) >> TIMERVALUE1_SHIFT) | ||
182 | |||
183 | #define SGE_TIMER_VALUE_2_AND_3 0x10bc | ||
184 | #define SGE_TIMER_VALUE_4_AND_5 0x10c0 | ||
185 | #define SGE_DEBUG_INDEX 0x10cc | ||
186 | #define SGE_DEBUG_DATA_HIGH 0x10d0 | ||
187 | #define SGE_DEBUG_DATA_LOW 0x10d4 | ||
188 | #define SGE_INGRESS_QUEUES_PER_PAGE_PF 0x10f4 | ||
189 | |||
190 | #define PCIE_PF_CLI 0x44 | ||
191 | #define PCIE_INT_CAUSE 0x3004 | ||
192 | #define UNXSPLCPLERR 0x20000000U | ||
193 | #define PCIEPINT 0x10000000U | ||
194 | #define PCIESINT 0x08000000U | ||
195 | #define RPLPERR 0x04000000U | ||
196 | #define RXWRPERR 0x02000000U | ||
197 | #define RXCPLPERR 0x01000000U | ||
198 | #define PIOTAGPERR 0x00800000U | ||
199 | #define MATAGPERR 0x00400000U | ||
200 | #define INTXCLRPERR 0x00200000U | ||
201 | #define FIDPERR 0x00100000U | ||
202 | #define CFGSNPPERR 0x00080000U | ||
203 | #define HRSPPERR 0x00040000U | ||
204 | #define HREQPERR 0x00020000U | ||
205 | #define HCNTPERR 0x00010000U | ||
206 | #define DRSPPERR 0x00008000U | ||
207 | #define DREQPERR 0x00004000U | ||
208 | #define DCNTPERR 0x00002000U | ||
209 | #define CRSPPERR 0x00001000U | ||
210 | #define CREQPERR 0x00000800U | ||
211 | #define CCNTPERR 0x00000400U | ||
212 | #define TARTAGPERR 0x00000200U | ||
213 | #define PIOREQPERR 0x00000100U | ||
214 | #define PIOCPLPERR 0x00000080U | ||
215 | #define MSIXDIPERR 0x00000040U | ||
216 | #define MSIXDATAPERR 0x00000020U | ||
217 | #define MSIXADDRHPERR 0x00000010U | ||
218 | #define MSIXADDRLPERR 0x00000008U | ||
219 | #define MSIDATAPERR 0x00000004U | ||
220 | #define MSIADDRHPERR 0x00000002U | ||
221 | #define MSIADDRLPERR 0x00000001U | ||
222 | |||
223 | #define PCIE_NONFAT_ERR 0x3010 | ||
224 | #define PCIE_MEM_ACCESS_BASE_WIN 0x3068 | ||
225 | #define PCIEOFST_MASK 0xfffffc00U | ||
226 | #define BIR_MASK 0x00000300U | ||
227 | #define BIR_SHIFT 8 | ||
228 | #define BIR(x) ((x) << BIR_SHIFT) | ||
229 | #define WINDOW_MASK 0x000000ffU | ||
230 | #define WINDOW_SHIFT 0 | ||
231 | #define WINDOW(x) ((x) << WINDOW_SHIFT) | ||
232 | |||
233 | #define PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS 0x5908 | ||
234 | #define RNPP 0x80000000U | ||
235 | #define RPCP 0x20000000U | ||
236 | #define RCIP 0x08000000U | ||
237 | #define RCCP 0x04000000U | ||
238 | #define RFTP 0x00800000U | ||
239 | #define PTRP 0x00100000U | ||
240 | |||
241 | #define PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS 0x59a4 | ||
242 | #define TPCP 0x40000000U | ||
243 | #define TNPP 0x20000000U | ||
244 | #define TFTP 0x10000000U | ||
245 | #define TCAP 0x08000000U | ||
246 | #define TCIP 0x04000000U | ||
247 | #define RCAP 0x02000000U | ||
248 | #define PLUP 0x00800000U | ||
249 | #define PLDN 0x00400000U | ||
250 | #define OTDD 0x00200000U | ||
251 | #define GTRP 0x00100000U | ||
252 | #define RDPE 0x00040000U | ||
253 | #define TDCE 0x00020000U | ||
254 | #define TDUE 0x00010000U | ||
255 | |||
256 | #define MC_INT_CAUSE 0x7518 | ||
257 | #define ECC_UE_INT_CAUSE 0x00000004U | ||
258 | #define ECC_CE_INT_CAUSE 0x00000002U | ||
259 | #define PERR_INT_CAUSE 0x00000001U | ||
260 | |||
261 | #define MC_ECC_STATUS 0x751c | ||
262 | #define ECC_CECNT_MASK 0xffff0000U | ||
263 | #define ECC_CECNT_SHIFT 16 | ||
264 | #define ECC_CECNT(x) ((x) << ECC_CECNT_SHIFT) | ||
265 | #define ECC_CECNT_GET(x) (((x) & ECC_CECNT_MASK) >> ECC_CECNT_SHIFT) | ||
266 | #define ECC_UECNT_MASK 0x0000ffffU | ||
267 | #define ECC_UECNT_SHIFT 0 | ||
268 | #define ECC_UECNT(x) ((x) << ECC_UECNT_SHIFT) | ||
269 | #define ECC_UECNT_GET(x) (((x) & ECC_UECNT_MASK) >> ECC_UECNT_SHIFT) | ||
270 | |||
271 | #define MC_BIST_CMD 0x7600 | ||
272 | #define START_BIST 0x80000000U | ||
273 | #define BIST_CMD_GAP_MASK 0x0000ff00U | ||
274 | #define BIST_CMD_GAP_SHIFT 8 | ||
275 | #define BIST_CMD_GAP(x) ((x) << BIST_CMD_GAP_SHIFT) | ||
276 | #define BIST_OPCODE_MASK 0x00000003U | ||
277 | #define BIST_OPCODE_SHIFT 0 | ||
278 | #define BIST_OPCODE(x) ((x) << BIST_OPCODE_SHIFT) | ||
279 | |||
280 | #define MC_BIST_CMD_ADDR 0x7604 | ||
281 | #define MC_BIST_CMD_LEN 0x7608 | ||
282 | #define MC_BIST_DATA_PATTERN 0x760c | ||
283 | #define BIST_DATA_TYPE_MASK 0x0000000fU | ||
284 | #define BIST_DATA_TYPE_SHIFT 0 | ||
285 | #define BIST_DATA_TYPE(x) ((x) << BIST_DATA_TYPE_SHIFT) | ||
286 | |||
287 | #define MC_BIST_STATUS_RDATA 0x7688 | ||
288 | |||
289 | #define MA_EXT_MEMORY_BAR 0x77c8 | ||
290 | #define EXT_MEM_SIZE_MASK 0x00000fffU | ||
291 | #define EXT_MEM_SIZE_SHIFT 0 | ||
292 | #define EXT_MEM_SIZE_GET(x) (((x) & EXT_MEM_SIZE_MASK) >> EXT_MEM_SIZE_SHIFT) | ||
293 | |||
294 | #define MA_TARGET_MEM_ENABLE 0x77d8 | ||
295 | #define EXT_MEM_ENABLE 0x00000004U | ||
296 | #define EDRAM1_ENABLE 0x00000002U | ||
297 | #define EDRAM0_ENABLE 0x00000001U | ||
298 | |||
299 | #define MA_INT_CAUSE 0x77e0 | ||
300 | #define MEM_PERR_INT_CAUSE 0x00000002U | ||
301 | #define MEM_WRAP_INT_CAUSE 0x00000001U | ||
302 | |||
303 | #define MA_INT_WRAP_STATUS 0x77e4 | ||
304 | #define MEM_WRAP_ADDRESS_MASK 0xfffffff0U | ||
305 | #define MEM_WRAP_ADDRESS_SHIFT 4 | ||
306 | #define MEM_WRAP_ADDRESS_GET(x) (((x) & MEM_WRAP_ADDRESS_MASK) >> MEM_WRAP_ADDRESS_SHIFT) | ||
307 | #define MEM_WRAP_CLIENT_NUM_MASK 0x0000000fU | ||
308 | #define MEM_WRAP_CLIENT_NUM_SHIFT 0 | ||
309 | #define MEM_WRAP_CLIENT_NUM_GET(x) (((x) & MEM_WRAP_CLIENT_NUM_MASK) >> MEM_WRAP_CLIENT_NUM_SHIFT) | ||
310 | |||
311 | #define MA_PARITY_ERROR_STATUS 0x77f4 | ||
312 | |||
313 | #define EDC_0_BASE_ADDR 0x7900 | ||
314 | |||
315 | #define EDC_BIST_CMD 0x7904 | ||
316 | #define EDC_BIST_CMD_ADDR 0x7908 | ||
317 | #define EDC_BIST_CMD_LEN 0x790c | ||
318 | #define EDC_BIST_DATA_PATTERN 0x7910 | ||
319 | #define EDC_BIST_STATUS_RDATA 0x7928 | ||
320 | #define EDC_INT_CAUSE 0x7978 | ||
321 | #define ECC_UE_PAR 0x00000020U | ||
322 | #define ECC_CE_PAR 0x00000010U | ||
323 | #define PERR_PAR_CAUSE 0x00000008U | ||
324 | |||
325 | #define EDC_ECC_STATUS 0x797c | ||
326 | |||
327 | #define EDC_1_BASE_ADDR 0x7980 | ||
328 | |||
329 | #define CIM_PF_MAILBOX_DATA 0x240 | ||
330 | #define CIM_PF_MAILBOX_CTRL 0x280 | ||
331 | #define MBMSGVALID 0x00000008U | ||
332 | #define MBINTREQ 0x00000004U | ||
333 | #define MBOWNER_MASK 0x00000003U | ||
334 | #define MBOWNER_SHIFT 0 | ||
335 | #define MBOWNER(x) ((x) << MBOWNER_SHIFT) | ||
336 | #define MBOWNER_GET(x) (((x) & MBOWNER_MASK) >> MBOWNER_SHIFT) | ||
337 | |||
338 | #define CIM_PF_HOST_INT_CAUSE 0x28c | ||
339 | #define MBMSGRDYINT 0x00080000U | ||
340 | |||
341 | #define CIM_HOST_INT_CAUSE 0x7b2c | ||
342 | #define TIEQOUTPARERRINT 0x00100000U | ||
343 | #define TIEQINPARERRINT 0x00080000U | ||
344 | #define MBHOSTPARERR 0x00040000U | ||
345 | #define MBUPPARERR 0x00020000U | ||
346 | #define IBQPARERR 0x0001f800U | ||
347 | #define IBQTP0PARERR 0x00010000U | ||
348 | #define IBQTP1PARERR 0x00008000U | ||
349 | #define IBQULPPARERR 0x00004000U | ||
350 | #define IBQSGELOPARERR 0x00002000U | ||
351 | #define IBQSGEHIPARERR 0x00001000U | ||
352 | #define IBQNCSIPARERR 0x00000800U | ||
353 | #define OBQPARERR 0x000007e0U | ||
354 | #define OBQULP0PARERR 0x00000400U | ||
355 | #define OBQULP1PARERR 0x00000200U | ||
356 | #define OBQULP2PARERR 0x00000100U | ||
357 | #define OBQULP3PARERR 0x00000080U | ||
358 | #define OBQSGEPARERR 0x00000040U | ||
359 | #define OBQNCSIPARERR 0x00000020U | ||
360 | #define PREFDROPINT 0x00000002U | ||
361 | #define UPACCNONZERO 0x00000001U | ||
362 | |||
363 | #define CIM_HOST_UPACC_INT_CAUSE 0x7b34 | ||
364 | #define EEPROMWRINT 0x40000000U | ||
365 | #define TIMEOUTMAINT 0x20000000U | ||
366 | #define TIMEOUTINT 0x10000000U | ||
367 | #define RSPOVRLOOKUPINT 0x08000000U | ||
368 | #define REQOVRLOOKUPINT 0x04000000U | ||
369 | #define BLKWRPLINT 0x02000000U | ||
370 | #define BLKRDPLINT 0x01000000U | ||
371 | #define SGLWRPLINT 0x00800000U | ||
372 | #define SGLRDPLINT 0x00400000U | ||
373 | #define BLKWRCTLINT 0x00200000U | ||
374 | #define BLKRDCTLINT 0x00100000U | ||
375 | #define SGLWRCTLINT 0x00080000U | ||
376 | #define SGLRDCTLINT 0x00040000U | ||
377 | #define BLKWREEPROMINT 0x00020000U | ||
378 | #define BLKRDEEPROMINT 0x00010000U | ||
379 | #define SGLWREEPROMINT 0x00008000U | ||
380 | #define SGLRDEEPROMINT 0x00004000U | ||
381 | #define BLKWRFLASHINT 0x00002000U | ||
382 | #define BLKRDFLASHINT 0x00001000U | ||
383 | #define SGLWRFLASHINT 0x00000800U | ||
384 | #define SGLRDFLASHINT 0x00000400U | ||
385 | #define BLKWRBOOTINT 0x00000200U | ||
386 | #define BLKRDBOOTINT 0x00000100U | ||
387 | #define SGLWRBOOTINT 0x00000080U | ||
388 | #define SGLRDBOOTINT 0x00000040U | ||
389 | #define ILLWRBEINT 0x00000020U | ||
390 | #define ILLRDBEINT 0x00000010U | ||
391 | #define ILLRDINT 0x00000008U | ||
392 | #define ILLWRINT 0x00000004U | ||
393 | #define ILLTRANSINT 0x00000002U | ||
394 | #define RSVDSPACEINT 0x00000001U | ||
395 | |||
396 | #define TP_OUT_CONFIG 0x7d04 | ||
397 | #define VLANEXTENABLE_MASK 0x0000f000U | ||
398 | #define VLANEXTENABLE_SHIFT 12 | ||
399 | |||
400 | #define TP_PARA_REG2 0x7d68 | ||
401 | #define MAXRXDATA_MASK 0xffff0000U | ||
402 | #define MAXRXDATA_SHIFT 16 | ||
403 | #define MAXRXDATA_GET(x) (((x) & MAXRXDATA_MASK) >> MAXRXDATA_SHIFT) | ||
404 | |||
405 | #define TP_TIMER_RESOLUTION 0x7d90 | ||
406 | #define TIMERRESOLUTION_MASK 0x00ff0000U | ||
407 | #define TIMERRESOLUTION_SHIFT 16 | ||
408 | #define TIMERRESOLUTION_GET(x) (((x) & TIMERRESOLUTION_MASK) >> TIMERRESOLUTION_SHIFT) | ||
409 | |||
410 | #define TP_SHIFT_CNT 0x7dc0 | ||
411 | |||
412 | #define TP_CCTRL_TABLE 0x7ddc | ||
413 | #define TP_MTU_TABLE 0x7de4 | ||
414 | #define MTUINDEX_MASK 0xff000000U | ||
415 | #define MTUINDEX_SHIFT 24 | ||
416 | #define MTUINDEX(x) ((x) << MTUINDEX_SHIFT) | ||
417 | #define MTUWIDTH_MASK 0x000f0000U | ||
418 | #define MTUWIDTH_SHIFT 16 | ||
419 | #define MTUWIDTH(x) ((x) << MTUWIDTH_SHIFT) | ||
420 | #define MTUWIDTH_GET(x) (((x) & MTUWIDTH_MASK) >> MTUWIDTH_SHIFT) | ||
421 | #define MTUVALUE_MASK 0x00003fffU | ||
422 | #define MTUVALUE_SHIFT 0 | ||
423 | #define MTUVALUE(x) ((x) << MTUVALUE_SHIFT) | ||
424 | #define MTUVALUE_GET(x) (((x) & MTUVALUE_MASK) >> MTUVALUE_SHIFT) | ||
425 | |||
426 | #define TP_RSS_LKP_TABLE 0x7dec | ||
427 | #define LKPTBLROWVLD 0x80000000U | ||
428 | #define LKPTBLQUEUE1_MASK 0x000ffc00U | ||
429 | #define LKPTBLQUEUE1_SHIFT 10 | ||
430 | #define LKPTBLQUEUE1(x) ((x) << LKPTBLQUEUE1_SHIFT) | ||
431 | #define LKPTBLQUEUE1_GET(x) (((x) & LKPTBLQUEUE1_MASK) >> LKPTBLQUEUE1_SHIFT) | ||
432 | #define LKPTBLQUEUE0_MASK 0x000003ffU | ||
433 | #define LKPTBLQUEUE0_SHIFT 0 | ||
434 | #define LKPTBLQUEUE0(x) ((x) << LKPTBLQUEUE0_SHIFT) | ||
435 | #define LKPTBLQUEUE0_GET(x) (((x) & LKPTBLQUEUE0_MASK) >> LKPTBLQUEUE0_SHIFT) | ||
436 | |||
437 | #define TP_PIO_ADDR 0x7e40 | ||
438 | #define TP_PIO_DATA 0x7e44 | ||
439 | #define TP_MIB_INDEX 0x7e50 | ||
440 | #define TP_MIB_DATA 0x7e54 | ||
441 | #define TP_INT_CAUSE 0x7e74 | ||
442 | #define FLMTXFLSTEMPTY 0x40000000U | ||
443 | |||
444 | #define TP_INGRESS_CONFIG 0x141 | ||
445 | #define VNIC 0x00000800U | ||
446 | #define CSUM_HAS_PSEUDO_HDR 0x00000400U | ||
447 | #define RM_OVLAN 0x00000200U | ||
448 | #define LOOKUPEVERYPKT 0x00000100U | ||
449 | |||
450 | #define TP_MIB_MAC_IN_ERR_0 0x0 | ||
451 | #define TP_MIB_TCP_OUT_RST 0xc | ||
452 | #define TP_MIB_TCP_IN_SEG_HI 0x10 | ||
453 | #define TP_MIB_TCP_IN_SEG_LO 0x11 | ||
454 | #define TP_MIB_TCP_OUT_SEG_HI 0x12 | ||
455 | #define TP_MIB_TCP_OUT_SEG_LO 0x13 | ||
456 | #define TP_MIB_TCP_RXT_SEG_HI 0x14 | ||
457 | #define TP_MIB_TCP_RXT_SEG_LO 0x15 | ||
458 | #define TP_MIB_TNL_CNG_DROP_0 0x18 | ||
459 | #define TP_MIB_TCP_V6IN_ERR_0 0x28 | ||
460 | #define TP_MIB_TCP_V6OUT_RST 0x2c | ||
461 | #define TP_MIB_OFD_ARP_DROP 0x36 | ||
462 | #define TP_MIB_TNL_DROP_0 0x44 | ||
463 | #define TP_MIB_OFD_VLN_DROP_0 0x58 | ||
464 | |||
465 | #define ULP_TX_INT_CAUSE 0x8dcc | ||
466 | #define PBL_BOUND_ERR_CH3 0x80000000U | ||
467 | #define PBL_BOUND_ERR_CH2 0x40000000U | ||
468 | #define PBL_BOUND_ERR_CH1 0x20000000U | ||
469 | #define PBL_BOUND_ERR_CH0 0x10000000U | ||
470 | |||
471 | #define PM_RX_INT_CAUSE 0x8fdc | ||
472 | #define ZERO_E_CMD_ERROR 0x00400000U | ||
473 | #define PMRX_FRAMING_ERROR 0x003ffff0U | ||
474 | #define OCSPI_PAR_ERROR 0x00000008U | ||
475 | #define DB_OPTIONS_PAR_ERROR 0x00000004U | ||
476 | #define IESPI_PAR_ERROR 0x00000002U | ||
477 | #define E_PCMD_PAR_ERROR 0x00000001U | ||
478 | |||
479 | #define PM_TX_INT_CAUSE 0x8ffc | ||
480 | #define PCMD_LEN_OVFL0 0x80000000U | ||
481 | #define PCMD_LEN_OVFL1 0x40000000U | ||
482 | #define PCMD_LEN_OVFL2 0x20000000U | ||
483 | #define ZERO_C_CMD_ERROR 0x10000000U | ||
484 | #define PMTX_FRAMING_ERROR 0x0ffffff0U | ||
485 | #define OESPI_PAR_ERROR 0x00000008U | ||
486 | #define ICSPI_PAR_ERROR 0x00000002U | ||
487 | #define C_PCMD_PAR_ERROR 0x00000001U | ||
488 | |||
489 | #define MPS_PORT_STAT_TX_PORT_BYTES_L 0x400 | ||
490 | #define MPS_PORT_STAT_TX_PORT_BYTES_H 0x404 | ||
491 | #define MPS_PORT_STAT_TX_PORT_FRAMES_L 0x408 | ||
492 | #define MPS_PORT_STAT_TX_PORT_FRAMES_H 0x40c | ||
493 | #define MPS_PORT_STAT_TX_PORT_BCAST_L 0x410 | ||
494 | #define MPS_PORT_STAT_TX_PORT_BCAST_H 0x414 | ||
495 | #define MPS_PORT_STAT_TX_PORT_MCAST_L 0x418 | ||
496 | #define MPS_PORT_STAT_TX_PORT_MCAST_H 0x41c | ||
497 | #define MPS_PORT_STAT_TX_PORT_UCAST_L 0x420 | ||
498 | #define MPS_PORT_STAT_TX_PORT_UCAST_H 0x424 | ||
499 | #define MPS_PORT_STAT_TX_PORT_ERROR_L 0x428 | ||
500 | #define MPS_PORT_STAT_TX_PORT_ERROR_H 0x42c | ||
501 | #define MPS_PORT_STAT_TX_PORT_64B_L 0x430 | ||
502 | #define MPS_PORT_STAT_TX_PORT_64B_H 0x434 | ||
503 | #define MPS_PORT_STAT_TX_PORT_65B_127B_L 0x438 | ||
504 | #define MPS_PORT_STAT_TX_PORT_65B_127B_H 0x43c | ||
505 | #define MPS_PORT_STAT_TX_PORT_128B_255B_L 0x440 | ||
506 | #define MPS_PORT_STAT_TX_PORT_128B_255B_H 0x444 | ||
507 | #define MPS_PORT_STAT_TX_PORT_256B_511B_L 0x448 | ||
508 | #define MPS_PORT_STAT_TX_PORT_256B_511B_H 0x44c | ||
509 | #define MPS_PORT_STAT_TX_PORT_512B_1023B_L 0x450 | ||
510 | #define MPS_PORT_STAT_TX_PORT_512B_1023B_H 0x454 | ||
511 | #define MPS_PORT_STAT_TX_PORT_1024B_1518B_L 0x458 | ||
512 | #define MPS_PORT_STAT_TX_PORT_1024B_1518B_H 0x45c | ||
513 | #define MPS_PORT_STAT_TX_PORT_1519B_MAX_L 0x460 | ||
514 | #define MPS_PORT_STAT_TX_PORT_1519B_MAX_H 0x464 | ||
515 | #define MPS_PORT_STAT_TX_PORT_DROP_L 0x468 | ||
516 | #define MPS_PORT_STAT_TX_PORT_DROP_H 0x46c | ||
517 | #define MPS_PORT_STAT_TX_PORT_PAUSE_L 0x470 | ||
518 | #define MPS_PORT_STAT_TX_PORT_PAUSE_H 0x474 | ||
519 | #define MPS_PORT_STAT_TX_PORT_PPP0_L 0x478 | ||
520 | #define MPS_PORT_STAT_TX_PORT_PPP0_H 0x47c | ||
521 | #define MPS_PORT_STAT_TX_PORT_PPP1_L 0x480 | ||
522 | #define MPS_PORT_STAT_TX_PORT_PPP1_H 0x484 | ||
523 | #define MPS_PORT_STAT_TX_PORT_PPP2_L 0x488 | ||
524 | #define MPS_PORT_STAT_TX_PORT_PPP2_H 0x48c | ||
525 | #define MPS_PORT_STAT_TX_PORT_PPP3_L 0x490 | ||
526 | #define MPS_PORT_STAT_TX_PORT_PPP3_H 0x494 | ||
527 | #define MPS_PORT_STAT_TX_PORT_PPP4_L 0x498 | ||
528 | #define MPS_PORT_STAT_TX_PORT_PPP4_H 0x49c | ||
529 | #define MPS_PORT_STAT_TX_PORT_PPP5_L 0x4a0 | ||
530 | #define MPS_PORT_STAT_TX_PORT_PPP5_H 0x4a4 | ||
531 | #define MPS_PORT_STAT_TX_PORT_PPP6_L 0x4a8 | ||
532 | #define MPS_PORT_STAT_TX_PORT_PPP6_H 0x4ac | ||
533 | #define MPS_PORT_STAT_TX_PORT_PPP7_L 0x4b0 | ||
534 | #define MPS_PORT_STAT_TX_PORT_PPP7_H 0x4b4 | ||
535 | #define MPS_PORT_STAT_LB_PORT_BYTES_L 0x4c0 | ||
536 | #define MPS_PORT_STAT_LB_PORT_BYTES_H 0x4c4 | ||
537 | #define MPS_PORT_STAT_LB_PORT_FRAMES_L 0x4c8 | ||
538 | #define MPS_PORT_STAT_LB_PORT_FRAMES_H 0x4cc | ||
539 | #define MPS_PORT_STAT_LB_PORT_BCAST_L 0x4d0 | ||
540 | #define MPS_PORT_STAT_LB_PORT_BCAST_H 0x4d4 | ||
541 | #define MPS_PORT_STAT_LB_PORT_MCAST_L 0x4d8 | ||
542 | #define MPS_PORT_STAT_LB_PORT_MCAST_H 0x4dc | ||
543 | #define MPS_PORT_STAT_LB_PORT_UCAST_L 0x4e0 | ||
544 | #define MPS_PORT_STAT_LB_PORT_UCAST_H 0x4e4 | ||
545 | #define MPS_PORT_STAT_LB_PORT_ERROR_L 0x4e8 | ||
546 | #define MPS_PORT_STAT_LB_PORT_ERROR_H 0x4ec | ||
547 | #define MPS_PORT_STAT_LB_PORT_64B_L 0x4f0 | ||
548 | #define MPS_PORT_STAT_LB_PORT_64B_H 0x4f4 | ||
549 | #define MPS_PORT_STAT_LB_PORT_65B_127B_L 0x4f8 | ||
550 | #define MPS_PORT_STAT_LB_PORT_65B_127B_H 0x4fc | ||
551 | #define MPS_PORT_STAT_LB_PORT_128B_255B_L 0x500 | ||
552 | #define MPS_PORT_STAT_LB_PORT_128B_255B_H 0x504 | ||
553 | #define MPS_PORT_STAT_LB_PORT_256B_511B_L 0x508 | ||
554 | #define MPS_PORT_STAT_LB_PORT_256B_511B_H 0x50c | ||
555 | #define MPS_PORT_STAT_LB_PORT_512B_1023B_L 0x510 | ||
556 | #define MPS_PORT_STAT_LB_PORT_512B_1023B_H 0x514 | ||
557 | #define MPS_PORT_STAT_LB_PORT_1024B_1518B_L 0x518 | ||
558 | #define MPS_PORT_STAT_LB_PORT_1024B_1518B_H 0x51c | ||
559 | #define MPS_PORT_STAT_LB_PORT_1519B_MAX_L 0x520 | ||
560 | #define MPS_PORT_STAT_LB_PORT_1519B_MAX_H 0x524 | ||
561 | #define MPS_PORT_STAT_LB_PORT_DROP_FRAMES 0x528 | ||
562 | #define MPS_PORT_STAT_RX_PORT_BYTES_L 0x540 | ||
563 | #define MPS_PORT_STAT_RX_PORT_BYTES_H 0x544 | ||
564 | #define MPS_PORT_STAT_RX_PORT_FRAMES_L 0x548 | ||
565 | #define MPS_PORT_STAT_RX_PORT_FRAMES_H 0x54c | ||
566 | #define MPS_PORT_STAT_RX_PORT_BCAST_L 0x550 | ||
567 | #define MPS_PORT_STAT_RX_PORT_BCAST_H 0x554 | ||
568 | #define MPS_PORT_STAT_RX_PORT_MCAST_L 0x558 | ||
569 | #define MPS_PORT_STAT_RX_PORT_MCAST_H 0x55c | ||
570 | #define MPS_PORT_STAT_RX_PORT_UCAST_L 0x560 | ||
571 | #define MPS_PORT_STAT_RX_PORT_UCAST_H 0x564 | ||
572 | #define MPS_PORT_STAT_RX_PORT_MTU_ERROR_L 0x568 | ||
573 | #define MPS_PORT_STAT_RX_PORT_MTU_ERROR_H 0x56c | ||
574 | #define MPS_PORT_STAT_RX_PORT_MTU_CRC_ERROR_L 0x570 | ||
575 | #define MPS_PORT_STAT_RX_PORT_MTU_CRC_ERROR_H 0x574 | ||
576 | #define MPS_PORT_STAT_RX_PORT_CRC_ERROR_L 0x578 | ||
577 | #define MPS_PORT_STAT_RX_PORT_CRC_ERROR_H 0x57c | ||
578 | #define MPS_PORT_STAT_RX_PORT_LEN_ERROR_L 0x580 | ||
579 | #define MPS_PORT_STAT_RX_PORT_LEN_ERROR_H 0x584 | ||
580 | #define MPS_PORT_STAT_RX_PORT_SYM_ERROR_L 0x588 | ||
581 | #define MPS_PORT_STAT_RX_PORT_SYM_ERROR_H 0x58c | ||
582 | #define MPS_PORT_STAT_RX_PORT_64B_L 0x590 | ||
583 | #define MPS_PORT_STAT_RX_PORT_64B_H 0x594 | ||
584 | #define MPS_PORT_STAT_RX_PORT_65B_127B_L 0x598 | ||
585 | #define MPS_PORT_STAT_RX_PORT_65B_127B_H 0x59c | ||
586 | #define MPS_PORT_STAT_RX_PORT_128B_255B_L 0x5a0 | ||
587 | #define MPS_PORT_STAT_RX_PORT_128B_255B_H 0x5a4 | ||
588 | #define MPS_PORT_STAT_RX_PORT_256B_511B_L 0x5a8 | ||
589 | #define MPS_PORT_STAT_RX_PORT_256B_511B_H 0x5ac | ||
590 | #define MPS_PORT_STAT_RX_PORT_512B_1023B_L 0x5b0 | ||
591 | #define MPS_PORT_STAT_RX_PORT_512B_1023B_H 0x5b4 | ||
592 | #define MPS_PORT_STAT_RX_PORT_1024B_1518B_L 0x5b8 | ||
593 | #define MPS_PORT_STAT_RX_PORT_1024B_1518B_H 0x5bc | ||
594 | #define MPS_PORT_STAT_RX_PORT_1519B_MAX_L 0x5c0 | ||
595 | #define MPS_PORT_STAT_RX_PORT_1519B_MAX_H 0x5c4 | ||
596 | #define MPS_PORT_STAT_RX_PORT_PAUSE_L 0x5c8 | ||
597 | #define MPS_PORT_STAT_RX_PORT_PAUSE_H 0x5cc | ||
598 | #define MPS_PORT_STAT_RX_PORT_PPP0_L 0x5d0 | ||
599 | #define MPS_PORT_STAT_RX_PORT_PPP0_H 0x5d4 | ||
600 | #define MPS_PORT_STAT_RX_PORT_PPP1_L 0x5d8 | ||
601 | #define MPS_PORT_STAT_RX_PORT_PPP1_H 0x5dc | ||
602 | #define MPS_PORT_STAT_RX_PORT_PPP2_L 0x5e0 | ||
603 | #define MPS_PORT_STAT_RX_PORT_PPP2_H 0x5e4 | ||
604 | #define MPS_PORT_STAT_RX_PORT_PPP3_L 0x5e8 | ||
605 | #define MPS_PORT_STAT_RX_PORT_PPP3_H 0x5ec | ||
606 | #define MPS_PORT_STAT_RX_PORT_PPP4_L 0x5f0 | ||
607 | #define MPS_PORT_STAT_RX_PORT_PPP4_H 0x5f4 | ||
608 | #define MPS_PORT_STAT_RX_PORT_PPP5_L 0x5f8 | ||
609 | #define MPS_PORT_STAT_RX_PORT_PPP5_H 0x5fc | ||
610 | #define MPS_PORT_STAT_RX_PORT_PPP6_L 0x600 | ||
611 | #define MPS_PORT_STAT_RX_PORT_PPP6_H 0x604 | ||
612 | #define MPS_PORT_STAT_RX_PORT_PPP7_L 0x608 | ||
613 | #define MPS_PORT_STAT_RX_PORT_PPP7_H 0x60c | ||
614 | #define MPS_PORT_STAT_RX_PORT_LESS_64B_L 0x610 | ||
615 | #define MPS_PORT_STAT_RX_PORT_LESS_64B_H 0x614 | ||
616 | #define MPS_CMN_CTL 0x9000 | ||
617 | #define NUMPORTS_MASK 0x00000003U | ||
618 | #define NUMPORTS_SHIFT 0 | ||
619 | #define NUMPORTS_GET(x) (((x) & NUMPORTS_MASK) >> NUMPORTS_SHIFT) | ||
620 | |||
621 | #define MPS_INT_CAUSE 0x9008 | ||
622 | #define STATINT 0x00000020U | ||
623 | #define TXINT 0x00000010U | ||
624 | #define RXINT 0x00000008U | ||
625 | #define TRCINT 0x00000004U | ||
626 | #define CLSINT 0x00000002U | ||
627 | #define PLINT 0x00000001U | ||
628 | |||
629 | #define MPS_TX_INT_CAUSE 0x9408 | ||
630 | #define PORTERR 0x00010000U | ||
631 | #define FRMERR 0x00008000U | ||
632 | #define SECNTERR 0x00004000U | ||
633 | #define BUBBLE 0x00002000U | ||
634 | #define TXDESCFIFO 0x00001e00U | ||
635 | #define TXDATAFIFO 0x000001e0U | ||
636 | #define NCSIFIFO 0x00000010U | ||
637 | #define TPFIFO 0x0000000fU | ||
638 | |||
639 | #define MPS_STAT_PERR_INT_CAUSE_SRAM 0x9614 | ||
640 | #define MPS_STAT_PERR_INT_CAUSE_TX_FIFO 0x9620 | ||
641 | #define MPS_STAT_PERR_INT_CAUSE_RX_FIFO 0x962c | ||
642 | |||
643 | #define MPS_STAT_RX_BG_0_MAC_DROP_FRAME_L 0x9640 | ||
644 | #define MPS_STAT_RX_BG_0_MAC_DROP_FRAME_H 0x9644 | ||
645 | #define MPS_STAT_RX_BG_1_MAC_DROP_FRAME_L 0x9648 | ||
646 | #define MPS_STAT_RX_BG_1_MAC_DROP_FRAME_H 0x964c | ||
647 | #define MPS_STAT_RX_BG_2_MAC_DROP_FRAME_L 0x9650 | ||
648 | #define MPS_STAT_RX_BG_2_MAC_DROP_FRAME_H 0x9654 | ||
649 | #define MPS_STAT_RX_BG_3_MAC_DROP_FRAME_L 0x9658 | ||
650 | #define MPS_STAT_RX_BG_3_MAC_DROP_FRAME_H 0x965c | ||
651 | #define MPS_STAT_RX_BG_0_LB_DROP_FRAME_L 0x9660 | ||
652 | #define MPS_STAT_RX_BG_0_LB_DROP_FRAME_H 0x9664 | ||
653 | #define MPS_STAT_RX_BG_1_LB_DROP_FRAME_L 0x9668 | ||
654 | #define MPS_STAT_RX_BG_1_LB_DROP_FRAME_H 0x966c | ||
655 | #define MPS_STAT_RX_BG_2_LB_DROP_FRAME_L 0x9670 | ||
656 | #define MPS_STAT_RX_BG_2_LB_DROP_FRAME_H 0x9674 | ||
657 | #define MPS_STAT_RX_BG_3_LB_DROP_FRAME_L 0x9678 | ||
658 | #define MPS_STAT_RX_BG_3_LB_DROP_FRAME_H 0x967c | ||
659 | #define MPS_STAT_RX_BG_0_MAC_TRUNC_FRAME_L 0x9680 | ||
660 | #define MPS_STAT_RX_BG_0_MAC_TRUNC_FRAME_H 0x9684 | ||
661 | #define MPS_STAT_RX_BG_1_MAC_TRUNC_FRAME_L 0x9688 | ||
662 | #define MPS_STAT_RX_BG_1_MAC_TRUNC_FRAME_H 0x968c | ||
663 | #define MPS_STAT_RX_BG_2_MAC_TRUNC_FRAME_L 0x9690 | ||
664 | #define MPS_STAT_RX_BG_2_MAC_TRUNC_FRAME_H 0x9694 | ||
665 | #define MPS_STAT_RX_BG_3_MAC_TRUNC_FRAME_L 0x9698 | ||
666 | #define MPS_STAT_RX_BG_3_MAC_TRUNC_FRAME_H 0x969c | ||
667 | #define MPS_STAT_RX_BG_0_LB_TRUNC_FRAME_L 0x96a0 | ||
668 | #define MPS_STAT_RX_BG_0_LB_TRUNC_FRAME_H 0x96a4 | ||
669 | #define MPS_STAT_RX_BG_1_LB_TRUNC_FRAME_L 0x96a8 | ||
670 | #define MPS_STAT_RX_BG_1_LB_TRUNC_FRAME_H 0x96ac | ||
671 | #define MPS_STAT_RX_BG_2_LB_TRUNC_FRAME_L 0x96b0 | ||
672 | #define MPS_STAT_RX_BG_2_LB_TRUNC_FRAME_H 0x96b4 | ||
673 | #define MPS_STAT_RX_BG_3_LB_TRUNC_FRAME_L 0x96b8 | ||
674 | #define MPS_STAT_RX_BG_3_LB_TRUNC_FRAME_H 0x96bc | ||
675 | #define MPS_TRC_CFG 0x9800 | ||
676 | #define TRCFIFOEMPTY 0x00000010U | ||
677 | #define TRCIGNOREDROPINPUT 0x00000008U | ||
678 | #define TRCKEEPDUPLICATES 0x00000004U | ||
679 | #define TRCEN 0x00000002U | ||
680 | #define TRCMULTIFILTER 0x00000001U | ||
681 | |||
682 | #define MPS_TRC_RSS_CONTROL 0x9808 | ||
683 | #define RSSCONTROL_MASK 0x00ff0000U | ||
684 | #define RSSCONTROL_SHIFT 16 | ||
685 | #define RSSCONTROL(x) ((x) << RSSCONTROL_SHIFT) | ||
686 | #define QUEUENUMBER_MASK 0x0000ffffU | ||
687 | #define QUEUENUMBER_SHIFT 0 | ||
688 | #define QUEUENUMBER(x) ((x) << QUEUENUMBER_SHIFT) | ||
689 | |||
690 | #define MPS_TRC_FILTER_MATCH_CTL_A 0x9810 | ||
691 | #define TFINVERTMATCH 0x01000000U | ||
692 | #define TFPKTTOOLARGE 0x00800000U | ||
693 | #define TFEN 0x00400000U | ||
694 | #define TFPORT_MASK 0x003c0000U | ||
695 | #define TFPORT_SHIFT 18 | ||
696 | #define TFPORT(x) ((x) << TFPORT_SHIFT) | ||
697 | #define TFPORT_GET(x) (((x) & TFPORT_MASK) >> TFPORT_SHIFT) | ||
698 | #define TFDROP 0x00020000U | ||
699 | #define TFSOPEOPERR 0x00010000U | ||
700 | #define TFLENGTH_MASK 0x00001f00U | ||
701 | #define TFLENGTH_SHIFT 8 | ||
702 | #define TFLENGTH(x) ((x) << TFLENGTH_SHIFT) | ||
703 | #define TFLENGTH_GET(x) (((x) & TFLENGTH_MASK) >> TFLENGTH_SHIFT) | ||
704 | #define TFOFFSET_MASK 0x0000001fU | ||
705 | #define TFOFFSET_SHIFT 0 | ||
706 | #define TFOFFSET(x) ((x) << TFOFFSET_SHIFT) | ||
707 | #define TFOFFSET_GET(x) (((x) & TFOFFSET_MASK) >> TFOFFSET_SHIFT) | ||
708 | |||
709 | #define MPS_TRC_FILTER_MATCH_CTL_B 0x9820 | ||
710 | #define TFMINPKTSIZE_MASK 0x01ff0000U | ||
711 | #define TFMINPKTSIZE_SHIFT 16 | ||
712 | #define TFMINPKTSIZE(x) ((x) << TFMINPKTSIZE_SHIFT) | ||
713 | #define TFMINPKTSIZE_GET(x) (((x) & TFMINPKTSIZE_MASK) >> TFMINPKTSIZE_SHIFT) | ||
714 | #define TFCAPTUREMAX_MASK 0x00003fffU | ||
715 | #define TFCAPTUREMAX_SHIFT 0 | ||
716 | #define TFCAPTUREMAX(x) ((x) << TFCAPTUREMAX_SHIFT) | ||
717 | #define TFCAPTUREMAX_GET(x) (((x) & TFCAPTUREMAX_MASK) >> TFCAPTUREMAX_SHIFT) | ||
718 | |||
719 | #define MPS_TRC_INT_CAUSE 0x985c | ||
720 | #define MISCPERR 0x00000100U | ||
721 | #define PKTFIFO 0x000000f0U | ||
722 | #define FILTMEM 0x0000000fU | ||
723 | |||
724 | #define MPS_TRC_FILTER0_MATCH 0x9c00 | ||
725 | #define MPS_TRC_FILTER0_DONT_CARE 0x9c80 | ||
726 | #define MPS_TRC_FILTER1_MATCH 0x9d00 | ||
727 | #define MPS_CLS_INT_CAUSE 0xd028 | ||
728 | #define PLERRENB 0x00000008U | ||
729 | #define HASHSRAM 0x00000004U | ||
730 | #define MATCHTCAM 0x00000002U | ||
731 | #define MATCHSRAM 0x00000001U | ||
732 | |||
733 | #define MPS_RX_PERR_INT_CAUSE 0x11074 | ||
734 | |||
735 | #define CPL_INTR_CAUSE 0x19054 | ||
736 | #define CIM_OP_MAP_PERR 0x00000020U | ||
737 | #define CIM_OVFL_ERROR 0x00000010U | ||
738 | #define TP_FRAMING_ERROR 0x00000008U | ||
739 | #define SGE_FRAMING_ERROR 0x00000004U | ||
740 | #define CIM_FRAMING_ERROR 0x00000002U | ||
741 | #define ZERO_SWITCH_ERROR 0x00000001U | ||
742 | |||
743 | #define SMB_INT_CAUSE 0x19090 | ||
744 | #define MSTTXFIFOPARINT 0x00200000U | ||
745 | #define MSTRXFIFOPARINT 0x00100000U | ||
746 | #define SLVFIFOPARINT 0x00080000U | ||
747 | |||
748 | #define ULP_RX_INT_CAUSE 0x19158 | ||
749 | #define ULP_RX_ISCSI_TAGMASK 0x19164 | ||
750 | #define ULP_RX_ISCSI_PSZ 0x19168 | ||
751 | #define HPZ3_MASK 0x0f000000U | ||
752 | #define HPZ3_SHIFT 24 | ||
753 | #define HPZ3(x) ((x) << HPZ3_SHIFT) | ||
754 | #define HPZ2_MASK 0x000f0000U | ||
755 | #define HPZ2_SHIFT 16 | ||
756 | #define HPZ2(x) ((x) << HPZ2_SHIFT) | ||
757 | #define HPZ1_MASK 0x00000f00U | ||
758 | #define HPZ1_SHIFT 8 | ||
759 | #define HPZ1(x) ((x) << HPZ1_SHIFT) | ||
760 | #define HPZ0_MASK 0x0000000fU | ||
761 | #define HPZ0_SHIFT 0 | ||
762 | #define HPZ0(x) ((x) << HPZ0_SHIFT) | ||
763 | |||
764 | #define ULP_RX_TDDP_PSZ 0x19178 | ||
765 | |||
766 | #define SF_DATA 0x193f8 | ||
767 | #define SF_OP 0x193fc | ||
768 | #define BUSY 0x80000000U | ||
769 | #define SF_LOCK 0x00000010U | ||
770 | #define SF_CONT 0x00000008U | ||
771 | #define BYTECNT_MASK 0x00000006U | ||
772 | #define BYTECNT_SHIFT 1 | ||
773 | #define BYTECNT(x) ((x) << BYTECNT_SHIFT) | ||
774 | #define OP_WR 0x00000001U | ||
775 | |||
776 | #define PL_PF_INT_CAUSE 0x3c0 | ||
777 | #define PFSW 0x00000008U | ||
778 | #define PFSGE 0x00000004U | ||
779 | #define PFCIM 0x00000002U | ||
780 | #define PFMPS 0x00000001U | ||
781 | |||
782 | #define PL_PF_INT_ENABLE 0x3c4 | ||
783 | #define PL_PF_CTL 0x3c8 | ||
784 | #define SWINT 0x00000001U | ||
785 | |||
786 | #define PL_WHOAMI 0x19400 | ||
787 | #define SOURCEPF_MASK 0x00000700U | ||
788 | #define SOURCEPF_SHIFT 8 | ||
789 | #define SOURCEPF(x) ((x) << SOURCEPF_SHIFT) | ||
790 | #define SOURCEPF_GET(x) (((x) & SOURCEPF_MASK) >> SOURCEPF_SHIFT) | ||
791 | #define ISVF 0x00000080U | ||
792 | #define VFID_MASK 0x0000007fU | ||
793 | #define VFID_SHIFT 0 | ||
794 | #define VFID(x) ((x) << VFID_SHIFT) | ||
795 | #define VFID_GET(x) (((x) & VFID_MASK) >> VFID_SHIFT) | ||
796 | |||
797 | #define PL_INT_CAUSE 0x1940c | ||
798 | #define ULP_TX 0x08000000U | ||
799 | #define SGE 0x04000000U | ||
800 | #define HMA 0x02000000U | ||
801 | #define CPL_SWITCH 0x01000000U | ||
802 | #define ULP_RX 0x00800000U | ||
803 | #define PM_RX 0x00400000U | ||
804 | #define PM_TX 0x00200000U | ||
805 | #define MA 0x00100000U | ||
806 | #define TP 0x00080000U | ||
807 | #define LE 0x00040000U | ||
808 | #define EDC1 0x00020000U | ||
809 | #define EDC0 0x00010000U | ||
810 | #define MC 0x00008000U | ||
811 | #define PCIE 0x00004000U | ||
812 | #define PMU 0x00002000U | ||
813 | #define XGMAC_KR1 0x00001000U | ||
814 | #define XGMAC_KR0 0x00000800U | ||
815 | #define XGMAC1 0x00000400U | ||
816 | #define XGMAC0 0x00000200U | ||
817 | #define SMB 0x00000100U | ||
818 | #define SF 0x00000080U | ||
819 | #define PL 0x00000040U | ||
820 | #define NCSI 0x00000020U | ||
821 | #define MPS 0x00000010U | ||
822 | #define MI 0x00000008U | ||
823 | #define DBG 0x00000004U | ||
824 | #define I2CM 0x00000002U | ||
825 | #define CIM 0x00000001U | ||
826 | |||
827 | #define PL_INT_MAP0 0x19414 | ||
828 | #define PL_RST 0x19428 | ||
829 | #define PIORST 0x00000002U | ||
830 | #define PIORSTMODE 0x00000001U | ||
831 | |||
832 | #define PL_PL_INT_CAUSE 0x19430 | ||
833 | #define FATALPERR 0x00000010U | ||
834 | #define PERRVFID 0x00000001U | ||
835 | |||
836 | #define PL_REV 0x1943c | ||
837 | |||
838 | #define LE_DB_CONFIG 0x19c04 | ||
839 | #define HASHEN 0x00100000U | ||
840 | |||
841 | #define LE_DB_SERVER_INDEX 0x19c18 | ||
842 | #define LE_DB_ACT_CNT_IPV4 0x19c20 | ||
843 | #define LE_DB_ACT_CNT_IPV6 0x19c24 | ||
844 | |||
845 | #define LE_DB_INT_CAUSE 0x19c3c | ||
846 | #define REQQPARERR 0x00010000U | ||
847 | #define UNKNOWNCMD 0x00008000U | ||
848 | #define PARITYERR 0x00000040U | ||
849 | #define LIPMISS 0x00000020U | ||
850 | #define LIP0 0x00000010U | ||
851 | |||
852 | #define LE_DB_TID_HASHBASE 0x19df8 | ||
853 | |||
854 | #define NCSI_INT_CAUSE 0x1a0d8 | ||
855 | #define CIM_DM_PRTY_ERR 0x00000100U | ||
856 | #define MPS_DM_PRTY_ERR 0x00000080U | ||
857 | #define TXFIFO_PRTY_ERR 0x00000002U | ||
858 | #define RXFIFO_PRTY_ERR 0x00000001U | ||
859 | |||
860 | #define XGMAC_PORT_CFG2 0x1018 | ||
861 | #define PATEN 0x00040000U | ||
862 | #define MAGICEN 0x00020000U | ||
863 | |||
864 | #define XGMAC_PORT_MAGIC_MACID_LO 0x1024 | ||
865 | #define XGMAC_PORT_MAGIC_MACID_HI 0x1028 | ||
866 | |||
867 | #define XGMAC_PORT_EPIO_DATA0 0x10c0 | ||
868 | #define XGMAC_PORT_EPIO_DATA1 0x10c4 | ||
869 | #define XGMAC_PORT_EPIO_DATA2 0x10c8 | ||
870 | #define XGMAC_PORT_EPIO_DATA3 0x10cc | ||
871 | #define XGMAC_PORT_EPIO_OP 0x10d0 | ||
872 | #define EPIOWR 0x00000100U | ||
873 | #define ADDRESS_MASK 0x000000ffU | ||
874 | #define ADDRESS_SHIFT 0 | ||
875 | #define ADDRESS(x) ((x) << ADDRESS_SHIFT) | ||
876 | |||
877 | #define XGMAC_PORT_INT_CAUSE 0x10dc | ||
878 | #endif /* __T4_REGS_H */ | ||
diff --git a/drivers/net/cxgb4/t4fw_api.h b/drivers/net/cxgb4/t4fw_api.h new file mode 100644 index 000000000000..3393d05a388a --- /dev/null +++ b/drivers/net/cxgb4/t4fw_api.h | |||
@@ -0,0 +1,1580 @@ | |||
1 | /* | ||
2 | * This file is part of the Chelsio T4 Ethernet driver for Linux. | ||
3 | * | ||
4 | * Copyright (c) 2009-2010 Chelsio Communications, Inc. All rights reserved. | ||
5 | * | ||
6 | * This software is available to you under a choice of one of two | ||
7 | * licenses. You may choose to be licensed under the terms of the GNU | ||
8 | * General Public License (GPL) Version 2, available from the file | ||
9 | * COPYING in the main directory of this source tree, or the | ||
10 | * OpenIB.org BSD license below: | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or | ||
13 | * without modification, are permitted provided that the following | ||
14 | * conditions are met: | ||
15 | * | ||
16 | * - Redistributions of source code must retain the above | ||
17 | * copyright notice, this list of conditions and the following | ||
18 | * disclaimer. | ||
19 | * | ||
20 | * - Redistributions in binary form must reproduce the above | ||
21 | * copyright notice, this list of conditions and the following | ||
22 | * disclaimer in the documentation and/or other materials | ||
23 | * provided with the distribution. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
26 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
28 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
29 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
30 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
32 | * SOFTWARE. | ||
33 | */ | ||
34 | |||
35 | #ifndef _T4FW_INTERFACE_H_ | ||
36 | #define _T4FW_INTERFACE_H_ | ||
37 | |||
38 | #define FW_T4VF_SGE_BASE_ADDR 0x0000 | ||
39 | #define FW_T4VF_MPS_BASE_ADDR 0x0100 | ||
40 | #define FW_T4VF_PL_BASE_ADDR 0x0200 | ||
41 | #define FW_T4VF_MBDATA_BASE_ADDR 0x0240 | ||
42 | #define FW_T4VF_CIM_BASE_ADDR 0x0300 | ||
43 | |||
44 | enum fw_wr_opcodes { | ||
45 | FW_FILTER_WR = 0x02, | ||
46 | FW_ULPTX_WR = 0x04, | ||
47 | FW_TP_WR = 0x05, | ||
48 | FW_ETH_TX_PKT_WR = 0x08, | ||
49 | FW_FLOWC_WR = 0x0a, | ||
50 | FW_OFLD_TX_DATA_WR = 0x0b, | ||
51 | FW_CMD_WR = 0x10, | ||
52 | FW_ETH_TX_PKT_VM_WR = 0x11, | ||
53 | FW_RI_RES_WR = 0x0c, | ||
54 | FW_RI_INIT_WR = 0x0d, | ||
55 | FW_RI_RDMA_WRITE_WR = 0x14, | ||
56 | FW_RI_SEND_WR = 0x15, | ||
57 | FW_RI_RDMA_READ_WR = 0x16, | ||
58 | FW_RI_RECV_WR = 0x17, | ||
59 | FW_RI_BIND_MW_WR = 0x18, | ||
60 | FW_RI_FR_NSMR_WR = 0x19, | ||
61 | FW_RI_INV_LSTAG_WR = 0x1a, | ||
62 | FW_LASTC2E_WR = 0x40 | ||
63 | }; | ||
64 | |||
65 | struct fw_wr_hdr { | ||
66 | __be32 hi; | ||
67 | __be32 lo; | ||
68 | }; | ||
69 | |||
70 | #define FW_WR_OP(x) ((x) << 24) | ||
71 | #define FW_WR_ATOMIC(x) ((x) << 23) | ||
72 | #define FW_WR_FLUSH(x) ((x) << 22) | ||
73 | #define FW_WR_COMPL(x) ((x) << 21) | ||
74 | #define FW_WR_IMMDLEN(x) ((x) << 0) | ||
75 | |||
76 | #define FW_WR_EQUIQ (1U << 31) | ||
77 | #define FW_WR_EQUEQ (1U << 30) | ||
78 | #define FW_WR_FLOWID(x) ((x) << 8) | ||
79 | #define FW_WR_LEN16(x) ((x) << 0) | ||
80 | |||
81 | struct fw_ulptx_wr { | ||
82 | __be32 op_to_compl; | ||
83 | __be32 flowid_len16; | ||
84 | u64 cookie; | ||
85 | }; | ||
86 | |||
87 | struct fw_tp_wr { | ||
88 | __be32 op_to_immdlen; | ||
89 | __be32 flowid_len16; | ||
90 | u64 cookie; | ||
91 | }; | ||
92 | |||
93 | struct fw_eth_tx_pkt_wr { | ||
94 | __be32 op_immdlen; | ||
95 | __be32 equiq_to_len16; | ||
96 | __be64 r3; | ||
97 | }; | ||
98 | |||
99 | enum fw_flowc_mnem { | ||
100 | FW_FLOWC_MNEM_PFNVFN, /* PFN [15:8] VFN [7:0] */ | ||
101 | FW_FLOWC_MNEM_CH, | ||
102 | FW_FLOWC_MNEM_PORT, | ||
103 | FW_FLOWC_MNEM_IQID, | ||
104 | FW_FLOWC_MNEM_SNDNXT, | ||
105 | FW_FLOWC_MNEM_RCVNXT, | ||
106 | FW_FLOWC_MNEM_SNDBUF, | ||
107 | FW_FLOWC_MNEM_MSS, | ||
108 | }; | ||
109 | |||
110 | struct fw_flowc_mnemval { | ||
111 | u8 mnemonic; | ||
112 | u8 r4[3]; | ||
113 | __be32 val; | ||
114 | }; | ||
115 | |||
116 | struct fw_flowc_wr { | ||
117 | __be32 op_to_nparams; | ||
118 | #define FW_FLOWC_WR_NPARAMS(x) ((x) << 0) | ||
119 | __be32 flowid_len16; | ||
120 | struct fw_flowc_mnemval mnemval[0]; | ||
121 | }; | ||
122 | |||
123 | struct fw_ofld_tx_data_wr { | ||
124 | __be32 op_to_immdlen; | ||
125 | __be32 flowid_len16; | ||
126 | __be32 plen; | ||
127 | __be32 tunnel_to_proxy; | ||
128 | #define FW_OFLD_TX_DATA_WR_TUNNEL(x) ((x) << 19) | ||
129 | #define FW_OFLD_TX_DATA_WR_SAVE(x) ((x) << 18) | ||
130 | #define FW_OFLD_TX_DATA_WR_FLUSH(x) ((x) << 17) | ||
131 | #define FW_OFLD_TX_DATA_WR_URGENT(x) ((x) << 16) | ||
132 | #define FW_OFLD_TX_DATA_WR_MORE(x) ((x) << 15) | ||
133 | #define FW_OFLD_TX_DATA_WR_SHOVE(x) ((x) << 14) | ||
134 | #define FW_OFLD_TX_DATA_WR_ULPMODE(x) ((x) << 10) | ||
135 | #define FW_OFLD_TX_DATA_WR_ULPSUBMODE(x) ((x) << 6) | ||
136 | }; | ||
137 | |||
138 | struct fw_cmd_wr { | ||
139 | __be32 op_dma; | ||
140 | #define FW_CMD_WR_DMA (1U << 17) | ||
141 | __be32 len16_pkd; | ||
142 | __be64 cookie_daddr; | ||
143 | }; | ||
144 | |||
145 | struct fw_eth_tx_pkt_vm_wr { | ||
146 | __be32 op_immdlen; | ||
147 | __be32 equiq_to_len16; | ||
148 | __be32 r3[2]; | ||
149 | u8 ethmacdst[6]; | ||
150 | u8 ethmacsrc[6]; | ||
151 | __be16 ethtype; | ||
152 | __be16 vlantci; | ||
153 | }; | ||
154 | |||
155 | #define FW_CMD_MAX_TIMEOUT 3000 | ||
156 | |||
157 | enum fw_cmd_opcodes { | ||
158 | FW_LDST_CMD = 0x01, | ||
159 | FW_RESET_CMD = 0x03, | ||
160 | FW_HELLO_CMD = 0x04, | ||
161 | FW_BYE_CMD = 0x05, | ||
162 | FW_INITIALIZE_CMD = 0x06, | ||
163 | FW_CAPS_CONFIG_CMD = 0x07, | ||
164 | FW_PARAMS_CMD = 0x08, | ||
165 | FW_PFVF_CMD = 0x09, | ||
166 | FW_IQ_CMD = 0x10, | ||
167 | FW_EQ_MNGT_CMD = 0x11, | ||
168 | FW_EQ_ETH_CMD = 0x12, | ||
169 | FW_EQ_CTRL_CMD = 0x13, | ||
170 | FW_EQ_OFLD_CMD = 0x21, | ||
171 | FW_VI_CMD = 0x14, | ||
172 | FW_VI_MAC_CMD = 0x15, | ||
173 | FW_VI_RXMODE_CMD = 0x16, | ||
174 | FW_VI_ENABLE_CMD = 0x17, | ||
175 | FW_ACL_MAC_CMD = 0x18, | ||
176 | FW_ACL_VLAN_CMD = 0x19, | ||
177 | FW_VI_STATS_CMD = 0x1a, | ||
178 | FW_PORT_CMD = 0x1b, | ||
179 | FW_PORT_STATS_CMD = 0x1c, | ||
180 | FW_PORT_LB_STATS_CMD = 0x1d, | ||
181 | FW_PORT_TRACE_CMD = 0x1e, | ||
182 | FW_PORT_TRACE_MMAP_CMD = 0x1f, | ||
183 | FW_RSS_IND_TBL_CMD = 0x20, | ||
184 | FW_RSS_GLB_CONFIG_CMD = 0x22, | ||
185 | FW_RSS_VI_CONFIG_CMD = 0x23, | ||
186 | FW_LASTC2E_CMD = 0x40, | ||
187 | FW_ERROR_CMD = 0x80, | ||
188 | FW_DEBUG_CMD = 0x81, | ||
189 | }; | ||
190 | |||
191 | enum fw_cmd_cap { | ||
192 | FW_CMD_CAP_PF = 0x01, | ||
193 | FW_CMD_CAP_DMAQ = 0x02, | ||
194 | FW_CMD_CAP_PORT = 0x04, | ||
195 | FW_CMD_CAP_PORTPROMISC = 0x08, | ||
196 | FW_CMD_CAP_PORTSTATS = 0x10, | ||
197 | FW_CMD_CAP_VF = 0x80, | ||
198 | }; | ||
199 | |||
200 | /* | ||
201 | * Generic command header flit0 | ||
202 | */ | ||
203 | struct fw_cmd_hdr { | ||
204 | __be32 hi; | ||
205 | __be32 lo; | ||
206 | }; | ||
207 | |||
208 | #define FW_CMD_OP(x) ((x) << 24) | ||
209 | #define FW_CMD_OP_GET(x) (((x) >> 24) & 0xff) | ||
210 | #define FW_CMD_REQUEST (1U << 23) | ||
211 | #define FW_CMD_READ (1U << 22) | ||
212 | #define FW_CMD_WRITE (1U << 21) | ||
213 | #define FW_CMD_EXEC (1U << 20) | ||
214 | #define FW_CMD_RAMASK(x) ((x) << 20) | ||
215 | #define FW_CMD_RETVAL(x) ((x) << 8) | ||
216 | #define FW_CMD_RETVAL_GET(x) (((x) >> 8) & 0xff) | ||
217 | #define FW_CMD_LEN16(x) ((x) << 0) | ||
218 | |||
219 | enum fw_ldst_addrspc { | ||
220 | FW_LDST_ADDRSPC_FIRMWARE = 0x0001, | ||
221 | FW_LDST_ADDRSPC_SGE_EGRC = 0x0008, | ||
222 | FW_LDST_ADDRSPC_SGE_INGC = 0x0009, | ||
223 | FW_LDST_ADDRSPC_SGE_FLMC = 0x000a, | ||
224 | FW_LDST_ADDRSPC_SGE_CONMC = 0x000b, | ||
225 | FW_LDST_ADDRSPC_TP_PIO = 0x0010, | ||
226 | FW_LDST_ADDRSPC_TP_TM_PIO = 0x0011, | ||
227 | FW_LDST_ADDRSPC_TP_MIB = 0x0012, | ||
228 | FW_LDST_ADDRSPC_MDIO = 0x0018, | ||
229 | FW_LDST_ADDRSPC_MPS = 0x0020, | ||
230 | FW_LDST_ADDRSPC_FUNC = 0x0028 | ||
231 | }; | ||
232 | |||
233 | enum fw_ldst_mps_fid { | ||
234 | FW_LDST_MPS_ATRB, | ||
235 | FW_LDST_MPS_RPLC | ||
236 | }; | ||
237 | |||
238 | enum fw_ldst_func_access_ctl { | ||
239 | FW_LDST_FUNC_ACC_CTL_VIID, | ||
240 | FW_LDST_FUNC_ACC_CTL_FID | ||
241 | }; | ||
242 | |||
243 | enum fw_ldst_func_mod_index { | ||
244 | FW_LDST_FUNC_MPS | ||
245 | }; | ||
246 | |||
247 | struct fw_ldst_cmd { | ||
248 | __be32 op_to_addrspace; | ||
249 | #define FW_LDST_CMD_ADDRSPACE(x) ((x) << 0) | ||
250 | __be32 cycles_to_len16; | ||
251 | union fw_ldst { | ||
252 | struct fw_ldst_addrval { | ||
253 | __be32 addr; | ||
254 | __be32 val; | ||
255 | } addrval; | ||
256 | struct fw_ldst_idctxt { | ||
257 | __be32 physid; | ||
258 | __be32 msg_pkd; | ||
259 | __be32 ctxt_data7; | ||
260 | __be32 ctxt_data6; | ||
261 | __be32 ctxt_data5; | ||
262 | __be32 ctxt_data4; | ||
263 | __be32 ctxt_data3; | ||
264 | __be32 ctxt_data2; | ||
265 | __be32 ctxt_data1; | ||
266 | __be32 ctxt_data0; | ||
267 | } idctxt; | ||
268 | struct fw_ldst_mdio { | ||
269 | __be16 paddr_mmd; | ||
270 | __be16 raddr; | ||
271 | __be16 vctl; | ||
272 | __be16 rval; | ||
273 | } mdio; | ||
274 | struct fw_ldst_mps { | ||
275 | __be16 fid_ctl; | ||
276 | __be16 rplcpf_pkd; | ||
277 | __be32 rplc127_96; | ||
278 | __be32 rplc95_64; | ||
279 | __be32 rplc63_32; | ||
280 | __be32 rplc31_0; | ||
281 | __be32 atrb; | ||
282 | __be16 vlan[16]; | ||
283 | } mps; | ||
284 | struct fw_ldst_func { | ||
285 | u8 access_ctl; | ||
286 | u8 mod_index; | ||
287 | __be16 ctl_id; | ||
288 | __be32 offset; | ||
289 | __be64 data0; | ||
290 | __be64 data1; | ||
291 | } func; | ||
292 | } u; | ||
293 | }; | ||
294 | |||
295 | #define FW_LDST_CMD_MSG(x) ((x) << 31) | ||
296 | #define FW_LDST_CMD_PADDR(x) ((x) << 8) | ||
297 | #define FW_LDST_CMD_MMD(x) ((x) << 0) | ||
298 | #define FW_LDST_CMD_FID(x) ((x) << 15) | ||
299 | #define FW_LDST_CMD_CTL(x) ((x) << 0) | ||
300 | #define FW_LDST_CMD_RPLCPF(x) ((x) << 0) | ||
301 | |||
302 | struct fw_reset_cmd { | ||
303 | __be32 op_to_write; | ||
304 | __be32 retval_len16; | ||
305 | __be32 val; | ||
306 | __be32 r3; | ||
307 | }; | ||
308 | |||
309 | struct fw_hello_cmd { | ||
310 | __be32 op_to_write; | ||
311 | __be32 retval_len16; | ||
312 | __be32 err_to_mbasyncnot; | ||
313 | #define FW_HELLO_CMD_ERR (1U << 31) | ||
314 | #define FW_HELLO_CMD_INIT (1U << 30) | ||
315 | #define FW_HELLO_CMD_MASTERDIS(x) ((x) << 29) | ||
316 | #define FW_HELLO_CMD_MASTERFORCE(x) ((x) << 28) | ||
317 | #define FW_HELLO_CMD_MBMASTER(x) ((x) << 24) | ||
318 | #define FW_HELLO_CMD_MBASYNCNOT(x) ((x) << 20) | ||
319 | __be32 fwrev; | ||
320 | }; | ||
321 | |||
322 | struct fw_bye_cmd { | ||
323 | __be32 op_to_write; | ||
324 | __be32 retval_len16; | ||
325 | __be64 r3; | ||
326 | }; | ||
327 | |||
328 | struct fw_initialize_cmd { | ||
329 | __be32 op_to_write; | ||
330 | __be32 retval_len16; | ||
331 | __be64 r3; | ||
332 | }; | ||
333 | |||
334 | enum fw_caps_config_hm { | ||
335 | FW_CAPS_CONFIG_HM_PCIE = 0x00000001, | ||
336 | FW_CAPS_CONFIG_HM_PL = 0x00000002, | ||
337 | FW_CAPS_CONFIG_HM_SGE = 0x00000004, | ||
338 | FW_CAPS_CONFIG_HM_CIM = 0x00000008, | ||
339 | FW_CAPS_CONFIG_HM_ULPTX = 0x00000010, | ||
340 | FW_CAPS_CONFIG_HM_TP = 0x00000020, | ||
341 | FW_CAPS_CONFIG_HM_ULPRX = 0x00000040, | ||
342 | FW_CAPS_CONFIG_HM_PMRX = 0x00000080, | ||
343 | FW_CAPS_CONFIG_HM_PMTX = 0x00000100, | ||
344 | FW_CAPS_CONFIG_HM_MC = 0x00000200, | ||
345 | FW_CAPS_CONFIG_HM_LE = 0x00000400, | ||
346 | FW_CAPS_CONFIG_HM_MPS = 0x00000800, | ||
347 | FW_CAPS_CONFIG_HM_XGMAC = 0x00001000, | ||
348 | FW_CAPS_CONFIG_HM_CPLSWITCH = 0x00002000, | ||
349 | FW_CAPS_CONFIG_HM_T4DBG = 0x00004000, | ||
350 | FW_CAPS_CONFIG_HM_MI = 0x00008000, | ||
351 | FW_CAPS_CONFIG_HM_I2CM = 0x00010000, | ||
352 | FW_CAPS_CONFIG_HM_NCSI = 0x00020000, | ||
353 | FW_CAPS_CONFIG_HM_SMB = 0x00040000, | ||
354 | FW_CAPS_CONFIG_HM_MA = 0x00080000, | ||
355 | FW_CAPS_CONFIG_HM_EDRAM = 0x00100000, | ||
356 | FW_CAPS_CONFIG_HM_PMU = 0x00200000, | ||
357 | FW_CAPS_CONFIG_HM_UART = 0x00400000, | ||
358 | FW_CAPS_CONFIG_HM_SF = 0x00800000, | ||
359 | }; | ||
360 | |||
361 | enum fw_caps_config_nbm { | ||
362 | FW_CAPS_CONFIG_NBM_IPMI = 0x00000001, | ||
363 | FW_CAPS_CONFIG_NBM_NCSI = 0x00000002, | ||
364 | }; | ||
365 | |||
366 | enum fw_caps_config_link { | ||
367 | FW_CAPS_CONFIG_LINK_PPP = 0x00000001, | ||
368 | FW_CAPS_CONFIG_LINK_QFC = 0x00000002, | ||
369 | FW_CAPS_CONFIG_LINK_DCBX = 0x00000004, | ||
370 | }; | ||
371 | |||
372 | enum fw_caps_config_switch { | ||
373 | FW_CAPS_CONFIG_SWITCH_INGRESS = 0x00000001, | ||
374 | FW_CAPS_CONFIG_SWITCH_EGRESS = 0x00000002, | ||
375 | }; | ||
376 | |||
377 | enum fw_caps_config_nic { | ||
378 | FW_CAPS_CONFIG_NIC = 0x00000001, | ||
379 | FW_CAPS_CONFIG_NIC_VM = 0x00000002, | ||
380 | }; | ||
381 | |||
382 | enum fw_caps_config_ofld { | ||
383 | FW_CAPS_CONFIG_OFLD = 0x00000001, | ||
384 | }; | ||
385 | |||
386 | enum fw_caps_config_rdma { | ||
387 | FW_CAPS_CONFIG_RDMA_RDDP = 0x00000001, | ||
388 | FW_CAPS_CONFIG_RDMA_RDMAC = 0x00000002, | ||
389 | }; | ||
390 | |||
391 | enum fw_caps_config_iscsi { | ||
392 | FW_CAPS_CONFIG_ISCSI_INITIATOR_PDU = 0x00000001, | ||
393 | FW_CAPS_CONFIG_ISCSI_TARGET_PDU = 0x00000002, | ||
394 | FW_CAPS_CONFIG_ISCSI_INITIATOR_CNXOFLD = 0x00000004, | ||
395 | FW_CAPS_CONFIG_ISCSI_TARGET_CNXOFLD = 0x00000008, | ||
396 | }; | ||
397 | |||
398 | enum fw_caps_config_fcoe { | ||
399 | FW_CAPS_CONFIG_FCOE_INITIATOR = 0x00000001, | ||
400 | FW_CAPS_CONFIG_FCOE_TARGET = 0x00000002, | ||
401 | }; | ||
402 | |||
403 | struct fw_caps_config_cmd { | ||
404 | __be32 op_to_write; | ||
405 | __be32 retval_len16; | ||
406 | __be32 r2; | ||
407 | __be32 hwmbitmap; | ||
408 | __be16 nbmcaps; | ||
409 | __be16 linkcaps; | ||
410 | __be16 switchcaps; | ||
411 | __be16 r3; | ||
412 | __be16 niccaps; | ||
413 | __be16 ofldcaps; | ||
414 | __be16 rdmacaps; | ||
415 | __be16 r4; | ||
416 | __be16 iscsicaps; | ||
417 | __be16 fcoecaps; | ||
418 | __be32 r5; | ||
419 | __be64 r6; | ||
420 | }; | ||
421 | |||
422 | /* | ||
423 | * params command mnemonics | ||
424 | */ | ||
425 | enum fw_params_mnem { | ||
426 | FW_PARAMS_MNEM_DEV = 1, /* device params */ | ||
427 | FW_PARAMS_MNEM_PFVF = 2, /* function params */ | ||
428 | FW_PARAMS_MNEM_REG = 3, /* limited register access */ | ||
429 | FW_PARAMS_MNEM_DMAQ = 4, /* dma queue params */ | ||
430 | FW_PARAMS_MNEM_LAST | ||
431 | }; | ||
432 | |||
433 | /* | ||
434 | * device parameters | ||
435 | */ | ||
436 | enum fw_params_param_dev { | ||
437 | FW_PARAMS_PARAM_DEV_CCLK = 0x00, /* chip core clock in khz */ | ||
438 | FW_PARAMS_PARAM_DEV_PORTVEC = 0x01, /* the port vector */ | ||
439 | FW_PARAMS_PARAM_DEV_NTID = 0x02, /* reads the number of TIDs | ||
440 | * allocated by the device's | ||
441 | * Lookup Engine | ||
442 | */ | ||
443 | FW_PARAMS_PARAM_DEV_FLOWC_BUFFIFO_SZ = 0x03, | ||
444 | FW_PARAMS_PARAM_DEV_INTVER_NIC = 0x04, | ||
445 | FW_PARAMS_PARAM_DEV_INTVER_VNIC = 0x05, | ||
446 | FW_PARAMS_PARAM_DEV_INTVER_OFLD = 0x06, | ||
447 | FW_PARAMS_PARAM_DEV_INTVER_RI = 0x07, | ||
448 | FW_PARAMS_PARAM_DEV_INTVER_ISCSIPDU = 0x08, | ||
449 | FW_PARAMS_PARAM_DEV_INTVER_ISCSI = 0x09, | ||
450 | FW_PARAMS_PARAM_DEV_INTVER_FCOE = 0x0A | ||
451 | }; | ||
452 | |||
453 | /* | ||
454 | * physical and virtual function parameters | ||
455 | */ | ||
456 | enum fw_params_param_pfvf { | ||
457 | FW_PARAMS_PARAM_PFVF_RWXCAPS = 0x00, | ||
458 | FW_PARAMS_PARAM_PFVF_ROUTE_START = 0x01, | ||
459 | FW_PARAMS_PARAM_PFVF_ROUTE_END = 0x02, | ||
460 | FW_PARAMS_PARAM_PFVF_CLIP_START = 0x03, | ||
461 | FW_PARAMS_PARAM_PFVF_CLIP_END = 0x04, | ||
462 | FW_PARAMS_PARAM_PFVF_FILTER_START = 0x05, | ||
463 | FW_PARAMS_PARAM_PFVF_FILTER_END = 0x06, | ||
464 | FW_PARAMS_PARAM_PFVF_SERVER_START = 0x07, | ||
465 | FW_PARAMS_PARAM_PFVF_SERVER_END = 0x08, | ||
466 | FW_PARAMS_PARAM_PFVF_TDDP_START = 0x09, | ||
467 | FW_PARAMS_PARAM_PFVF_TDDP_END = 0x0A, | ||
468 | FW_PARAMS_PARAM_PFVF_ISCSI_START = 0x0B, | ||
469 | FW_PARAMS_PARAM_PFVF_ISCSI_END = 0x0C, | ||
470 | FW_PARAMS_PARAM_PFVF_STAG_START = 0x0D, | ||
471 | FW_PARAMS_PARAM_PFVF_STAG_END = 0x0E, | ||
472 | FW_PARAMS_PARAM_PFVF_RQ_START = 0x1F, | ||
473 | FW_PARAMS_PARAM_PFVF_RQ_END = 0x10, | ||
474 | FW_PARAMS_PARAM_PFVF_PBL_START = 0x11, | ||
475 | FW_PARAMS_PARAM_PFVF_PBL_END = 0x12, | ||
476 | FW_PARAMS_PARAM_PFVF_L2T_START = 0x13, | ||
477 | FW_PARAMS_PARAM_PFVF_L2T_END = 0x14, | ||
478 | FW_PARAMS_PARAM_PFVF_SCHEDCLASS_ETH = 0x20, | ||
479 | }; | ||
480 | |||
481 | /* | ||
482 | * dma queue parameters | ||
483 | */ | ||
484 | enum fw_params_param_dmaq { | ||
485 | FW_PARAMS_PARAM_DMAQ_IQ_DCAEN_DCACPU = 0x00, | ||
486 | FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH = 0x01, | ||
487 | FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_MNGT = 0x10, | ||
488 | FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_CTRL = 0x11, | ||
489 | FW_PARAMS_PARAM_DMAQ_EQ_SCHEDCLASS_ETH = 0x12, | ||
490 | }; | ||
491 | |||
492 | #define FW_PARAMS_MNEM(x) ((x) << 24) | ||
493 | #define FW_PARAMS_PARAM_X(x) ((x) << 16) | ||
494 | #define FW_PARAMS_PARAM_Y(x) ((x) << 8) | ||
495 | #define FW_PARAMS_PARAM_Z(x) ((x) << 0) | ||
496 | #define FW_PARAMS_PARAM_XYZ(x) ((x) << 0) | ||
497 | #define FW_PARAMS_PARAM_YZ(x) ((x) << 0) | ||
498 | |||
499 | struct fw_params_cmd { | ||
500 | __be32 op_to_vfn; | ||
501 | __be32 retval_len16; | ||
502 | struct fw_params_param { | ||
503 | __be32 mnem; | ||
504 | __be32 val; | ||
505 | } param[7]; | ||
506 | }; | ||
507 | |||
508 | #define FW_PARAMS_CMD_PFN(x) ((x) << 8) | ||
509 | #define FW_PARAMS_CMD_VFN(x) ((x) << 0) | ||
510 | |||
511 | struct fw_pfvf_cmd { | ||
512 | __be32 op_to_vfn; | ||
513 | __be32 retval_len16; | ||
514 | __be32 niqflint_niq; | ||
515 | __be32 cmask_to_neq; | ||
516 | __be32 tc_to_nexactf; | ||
517 | __be32 r_caps_to_nethctrl; | ||
518 | __be16 nricq; | ||
519 | __be16 nriqp; | ||
520 | __be32 r4; | ||
521 | }; | ||
522 | |||
523 | #define FW_PFVF_CMD_PFN(x) ((x) << 8) | ||
524 | #define FW_PFVF_CMD_VFN(x) ((x) << 0) | ||
525 | |||
526 | #define FW_PFVF_CMD_NIQFLINT(x) ((x) << 20) | ||
527 | #define FW_PFVF_CMD_NIQFLINT_GET(x) (((x) >> 20) & 0xfff) | ||
528 | |||
529 | #define FW_PFVF_CMD_NIQ(x) ((x) << 0) | ||
530 | #define FW_PFVF_CMD_NIQ_GET(x) (((x) >> 0) & 0xfffff) | ||
531 | |||
532 | #define FW_PFVF_CMD_CMASK(x) ((x) << 24) | ||
533 | #define FW_PFVF_CMD_CMASK_GET(x) (((x) >> 24) & 0xf) | ||
534 | |||
535 | #define FW_PFVF_CMD_PMASK(x) ((x) << 20) | ||
536 | #define FW_PFVF_CMD_PMASK_GET(x) (((x) >> 20) & 0xf) | ||
537 | |||
538 | #define FW_PFVF_CMD_NEQ(x) ((x) << 0) | ||
539 | #define FW_PFVF_CMD_NEQ_GET(x) (((x) >> 0) & 0xfffff) | ||
540 | |||
541 | #define FW_PFVF_CMD_TC(x) ((x) << 24) | ||
542 | #define FW_PFVF_CMD_TC_GET(x) (((x) >> 24) & 0xff) | ||
543 | |||
544 | #define FW_PFVF_CMD_NVI(x) ((x) << 16) | ||
545 | #define FW_PFVF_CMD_NVI_GET(x) (((x) >> 16) & 0xff) | ||
546 | |||
547 | #define FW_PFVF_CMD_NEXACTF(x) ((x) << 0) | ||
548 | #define FW_PFVF_CMD_NEXACTF_GET(x) (((x) >> 0) & 0xffff) | ||
549 | |||
550 | #define FW_PFVF_CMD_R_CAPS(x) ((x) << 24) | ||
551 | #define FW_PFVF_CMD_R_CAPS_GET(x) (((x) >> 24) & 0xff) | ||
552 | |||
553 | #define FW_PFVF_CMD_WX_CAPS(x) ((x) << 16) | ||
554 | #define FW_PFVF_CMD_WX_CAPS_GET(x) (((x) >> 16) & 0xff) | ||
555 | |||
556 | #define FW_PFVF_CMD_NETHCTRL(x) ((x) << 0) | ||
557 | #define FW_PFVF_CMD_NETHCTRL_GET(x) (((x) >> 0) & 0xffff) | ||
558 | |||
559 | enum fw_iq_type { | ||
560 | FW_IQ_TYPE_FL_INT_CAP, | ||
561 | FW_IQ_TYPE_NO_FL_INT_CAP | ||
562 | }; | ||
563 | |||
564 | struct fw_iq_cmd { | ||
565 | __be32 op_to_vfn; | ||
566 | __be32 alloc_to_len16; | ||
567 | __be16 physiqid; | ||
568 | __be16 iqid; | ||
569 | __be16 fl0id; | ||
570 | __be16 fl1id; | ||
571 | __be32 type_to_iqandstindex; | ||
572 | __be16 iqdroprss_to_iqesize; | ||
573 | __be16 iqsize; | ||
574 | __be64 iqaddr; | ||
575 | __be32 iqns_to_fl0congen; | ||
576 | __be16 fl0dcaen_to_fl0cidxfthresh; | ||
577 | __be16 fl0size; | ||
578 | __be64 fl0addr; | ||
579 | __be32 fl1cngchmap_to_fl1congen; | ||
580 | __be16 fl1dcaen_to_fl1cidxfthresh; | ||
581 | __be16 fl1size; | ||
582 | __be64 fl1addr; | ||
583 | }; | ||
584 | |||
585 | #define FW_IQ_CMD_PFN(x) ((x) << 8) | ||
586 | #define FW_IQ_CMD_VFN(x) ((x) << 0) | ||
587 | |||
588 | #define FW_IQ_CMD_ALLOC (1U << 31) | ||
589 | #define FW_IQ_CMD_FREE (1U << 30) | ||
590 | #define FW_IQ_CMD_MODIFY (1U << 29) | ||
591 | #define FW_IQ_CMD_IQSTART(x) ((x) << 28) | ||
592 | #define FW_IQ_CMD_IQSTOP(x) ((x) << 27) | ||
593 | |||
594 | #define FW_IQ_CMD_TYPE(x) ((x) << 29) | ||
595 | #define FW_IQ_CMD_IQASYNCH(x) ((x) << 28) | ||
596 | #define FW_IQ_CMD_VIID(x) ((x) << 16) | ||
597 | #define FW_IQ_CMD_IQANDST(x) ((x) << 15) | ||
598 | #define FW_IQ_CMD_IQANUS(x) ((x) << 14) | ||
599 | #define FW_IQ_CMD_IQANUD(x) ((x) << 12) | ||
600 | #define FW_IQ_CMD_IQANDSTINDEX(x) ((x) << 0) | ||
601 | |||
602 | #define FW_IQ_CMD_IQDROPRSS (1U << 15) | ||
603 | #define FW_IQ_CMD_IQGTSMODE (1U << 14) | ||
604 | #define FW_IQ_CMD_IQPCIECH(x) ((x) << 12) | ||
605 | #define FW_IQ_CMD_IQDCAEN(x) ((x) << 11) | ||
606 | #define FW_IQ_CMD_IQDCACPU(x) ((x) << 6) | ||
607 | #define FW_IQ_CMD_IQINTCNTTHRESH(x) ((x) << 4) | ||
608 | #define FW_IQ_CMD_IQO (1U << 3) | ||
609 | #define FW_IQ_CMD_IQCPRIO(x) ((x) << 2) | ||
610 | #define FW_IQ_CMD_IQESIZE(x) ((x) << 0) | ||
611 | |||
612 | #define FW_IQ_CMD_IQNS(x) ((x) << 31) | ||
613 | #define FW_IQ_CMD_IQRO(x) ((x) << 30) | ||
614 | #define FW_IQ_CMD_IQFLINTIQHSEN(x) ((x) << 28) | ||
615 | #define FW_IQ_CMD_IQFLINTCONGEN(x) ((x) << 27) | ||
616 | #define FW_IQ_CMD_IQFLINTISCSIC(x) ((x) << 26) | ||
617 | #define FW_IQ_CMD_FL0CNGCHMAP(x) ((x) << 20) | ||
618 | #define FW_IQ_CMD_FL0CACHELOCK(x) ((x) << 15) | ||
619 | #define FW_IQ_CMD_FL0DBP(x) ((x) << 14) | ||
620 | #define FW_IQ_CMD_FL0DATANS(x) ((x) << 13) | ||
621 | #define FW_IQ_CMD_FL0DATARO(x) ((x) << 12) | ||
622 | #define FW_IQ_CMD_FL0CONGCIF(x) ((x) << 11) | ||
623 | #define FW_IQ_CMD_FL0ONCHIP(x) ((x) << 10) | ||
624 | #define FW_IQ_CMD_FL0STATUSPGNS(x) ((x) << 9) | ||
625 | #define FW_IQ_CMD_FL0STATUSPGRO(x) ((x) << 8) | ||
626 | #define FW_IQ_CMD_FL0FETCHNS(x) ((x) << 7) | ||
627 | #define FW_IQ_CMD_FL0FETCHRO(x) ((x) << 6) | ||
628 | #define FW_IQ_CMD_FL0HOSTFCMODE(x) ((x) << 4) | ||
629 | #define FW_IQ_CMD_FL0CPRIO(x) ((x) << 3) | ||
630 | #define FW_IQ_CMD_FL0PADEN (1U << 2) | ||
631 | #define FW_IQ_CMD_FL0PACKEN (1U << 1) | ||
632 | #define FW_IQ_CMD_FL0CONGEN (1U << 0) | ||
633 | |||
634 | #define FW_IQ_CMD_FL0DCAEN(x) ((x) << 15) | ||
635 | #define FW_IQ_CMD_FL0DCACPU(x) ((x) << 10) | ||
636 | #define FW_IQ_CMD_FL0FBMIN(x) ((x) << 7) | ||
637 | #define FW_IQ_CMD_FL0FBMAX(x) ((x) << 4) | ||
638 | #define FW_IQ_CMD_FL0CIDXFTHRESHO (1U << 3) | ||
639 | #define FW_IQ_CMD_FL0CIDXFTHRESH(x) ((x) << 0) | ||
640 | |||
641 | #define FW_IQ_CMD_FL1CNGCHMAP(x) ((x) << 20) | ||
642 | #define FW_IQ_CMD_FL1CACHELOCK(x) ((x) << 15) | ||
643 | #define FW_IQ_CMD_FL1DBP(x) ((x) << 14) | ||
644 | #define FW_IQ_CMD_FL1DATANS(x) ((x) << 13) | ||
645 | #define FW_IQ_CMD_FL1DATARO(x) ((x) << 12) | ||
646 | #define FW_IQ_CMD_FL1CONGCIF(x) ((x) << 11) | ||
647 | #define FW_IQ_CMD_FL1ONCHIP(x) ((x) << 10) | ||
648 | #define FW_IQ_CMD_FL1STATUSPGNS(x) ((x) << 9) | ||
649 | #define FW_IQ_CMD_FL1STATUSPGRO(x) ((x) << 8) | ||
650 | #define FW_IQ_CMD_FL1FETCHNS(x) ((x) << 7) | ||
651 | #define FW_IQ_CMD_FL1FETCHRO(x) ((x) << 6) | ||
652 | #define FW_IQ_CMD_FL1HOSTFCMODE(x) ((x) << 4) | ||
653 | #define FW_IQ_CMD_FL1CPRIO(x) ((x) << 3) | ||
654 | #define FW_IQ_CMD_FL1PADEN (1U << 2) | ||
655 | #define FW_IQ_CMD_FL1PACKEN (1U << 1) | ||
656 | #define FW_IQ_CMD_FL1CONGEN (1U << 0) | ||
657 | |||
658 | #define FW_IQ_CMD_FL1DCAEN(x) ((x) << 15) | ||
659 | #define FW_IQ_CMD_FL1DCACPU(x) ((x) << 10) | ||
660 | #define FW_IQ_CMD_FL1FBMIN(x) ((x) << 7) | ||
661 | #define FW_IQ_CMD_FL1FBMAX(x) ((x) << 4) | ||
662 | #define FW_IQ_CMD_FL1CIDXFTHRESHO (1U << 3) | ||
663 | #define FW_IQ_CMD_FL1CIDXFTHRESH(x) ((x) << 0) | ||
664 | |||
665 | struct fw_eq_eth_cmd { | ||
666 | __be32 op_to_vfn; | ||
667 | __be32 alloc_to_len16; | ||
668 | __be32 eqid_pkd; | ||
669 | __be32 physeqid_pkd; | ||
670 | __be32 fetchszm_to_iqid; | ||
671 | __be32 dcaen_to_eqsize; | ||
672 | __be64 eqaddr; | ||
673 | __be32 viid_pkd; | ||
674 | __be32 r8_lo; | ||
675 | __be64 r9; | ||
676 | }; | ||
677 | |||
678 | #define FW_EQ_ETH_CMD_PFN(x) ((x) << 8) | ||
679 | #define FW_EQ_ETH_CMD_VFN(x) ((x) << 0) | ||
680 | #define FW_EQ_ETH_CMD_ALLOC (1U << 31) | ||
681 | #define FW_EQ_ETH_CMD_FREE (1U << 30) | ||
682 | #define FW_EQ_ETH_CMD_MODIFY (1U << 29) | ||
683 | #define FW_EQ_ETH_CMD_EQSTART (1U << 28) | ||
684 | #define FW_EQ_ETH_CMD_EQSTOP (1U << 27) | ||
685 | |||
686 | #define FW_EQ_ETH_CMD_EQID(x) ((x) << 0) | ||
687 | #define FW_EQ_ETH_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff) | ||
688 | #define FW_EQ_ETH_CMD_PHYSEQID(x) ((x) << 0) | ||
689 | |||
690 | #define FW_EQ_ETH_CMD_FETCHSZM(x) ((x) << 26) | ||
691 | #define FW_EQ_ETH_CMD_STATUSPGNS(x) ((x) << 25) | ||
692 | #define FW_EQ_ETH_CMD_STATUSPGRO(x) ((x) << 24) | ||
693 | #define FW_EQ_ETH_CMD_FETCHNS(x) ((x) << 23) | ||
694 | #define FW_EQ_ETH_CMD_FETCHRO(x) ((x) << 22) | ||
695 | #define FW_EQ_ETH_CMD_HOSTFCMODE(x) ((x) << 20) | ||
696 | #define FW_EQ_ETH_CMD_CPRIO(x) ((x) << 19) | ||
697 | #define FW_EQ_ETH_CMD_ONCHIP(x) ((x) << 18) | ||
698 | #define FW_EQ_ETH_CMD_PCIECHN(x) ((x) << 16) | ||
699 | #define FW_EQ_ETH_CMD_IQID(x) ((x) << 0) | ||
700 | |||
701 | #define FW_EQ_ETH_CMD_DCAEN(x) ((x) << 31) | ||
702 | #define FW_EQ_ETH_CMD_DCACPU(x) ((x) << 26) | ||
703 | #define FW_EQ_ETH_CMD_FBMIN(x) ((x) << 23) | ||
704 | #define FW_EQ_ETH_CMD_FBMAX(x) ((x) << 20) | ||
705 | #define FW_EQ_ETH_CMD_CIDXFTHRESHO(x) ((x) << 19) | ||
706 | #define FW_EQ_ETH_CMD_CIDXFTHRESH(x) ((x) << 16) | ||
707 | #define FW_EQ_ETH_CMD_EQSIZE(x) ((x) << 0) | ||
708 | |||
709 | #define FW_EQ_ETH_CMD_VIID(x) ((x) << 16) | ||
710 | |||
711 | struct fw_eq_ctrl_cmd { | ||
712 | __be32 op_to_vfn; | ||
713 | __be32 alloc_to_len16; | ||
714 | __be32 cmpliqid_eqid; | ||
715 | __be32 physeqid_pkd; | ||
716 | __be32 fetchszm_to_iqid; | ||
717 | __be32 dcaen_to_eqsize; | ||
718 | __be64 eqaddr; | ||
719 | }; | ||
720 | |||
721 | #define FW_EQ_CTRL_CMD_PFN(x) ((x) << 8) | ||
722 | #define FW_EQ_CTRL_CMD_VFN(x) ((x) << 0) | ||
723 | |||
724 | #define FW_EQ_CTRL_CMD_ALLOC (1U << 31) | ||
725 | #define FW_EQ_CTRL_CMD_FREE (1U << 30) | ||
726 | #define FW_EQ_CTRL_CMD_MODIFY (1U << 29) | ||
727 | #define FW_EQ_CTRL_CMD_EQSTART (1U << 28) | ||
728 | #define FW_EQ_CTRL_CMD_EQSTOP (1U << 27) | ||
729 | |||
730 | #define FW_EQ_CTRL_CMD_CMPLIQID(x) ((x) << 20) | ||
731 | #define FW_EQ_CTRL_CMD_EQID(x) ((x) << 0) | ||
732 | #define FW_EQ_CTRL_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff) | ||
733 | #define FW_EQ_CTRL_CMD_PHYSEQID_GET(x) (((x) >> 0) & 0xfffff) | ||
734 | |||
735 | #define FW_EQ_CTRL_CMD_FETCHSZM (1U << 26) | ||
736 | #define FW_EQ_CTRL_CMD_STATUSPGNS (1U << 25) | ||
737 | #define FW_EQ_CTRL_CMD_STATUSPGRO (1U << 24) | ||
738 | #define FW_EQ_CTRL_CMD_FETCHNS (1U << 23) | ||
739 | #define FW_EQ_CTRL_CMD_FETCHRO (1U << 22) | ||
740 | #define FW_EQ_CTRL_CMD_HOSTFCMODE(x) ((x) << 20) | ||
741 | #define FW_EQ_CTRL_CMD_CPRIO(x) ((x) << 19) | ||
742 | #define FW_EQ_CTRL_CMD_ONCHIP(x) ((x) << 18) | ||
743 | #define FW_EQ_CTRL_CMD_PCIECHN(x) ((x) << 16) | ||
744 | #define FW_EQ_CTRL_CMD_IQID(x) ((x) << 0) | ||
745 | |||
746 | #define FW_EQ_CTRL_CMD_DCAEN(x) ((x) << 31) | ||
747 | #define FW_EQ_CTRL_CMD_DCACPU(x) ((x) << 26) | ||
748 | #define FW_EQ_CTRL_CMD_FBMIN(x) ((x) << 23) | ||
749 | #define FW_EQ_CTRL_CMD_FBMAX(x) ((x) << 20) | ||
750 | #define FW_EQ_CTRL_CMD_CIDXFTHRESHO(x) ((x) << 19) | ||
751 | #define FW_EQ_CTRL_CMD_CIDXFTHRESH(x) ((x) << 16) | ||
752 | #define FW_EQ_CTRL_CMD_EQSIZE(x) ((x) << 0) | ||
753 | |||
754 | struct fw_eq_ofld_cmd { | ||
755 | __be32 op_to_vfn; | ||
756 | __be32 alloc_to_len16; | ||
757 | __be32 eqid_pkd; | ||
758 | __be32 physeqid_pkd; | ||
759 | __be32 fetchszm_to_iqid; | ||
760 | __be32 dcaen_to_eqsize; | ||
761 | __be64 eqaddr; | ||
762 | }; | ||
763 | |||
764 | #define FW_EQ_OFLD_CMD_PFN(x) ((x) << 8) | ||
765 | #define FW_EQ_OFLD_CMD_VFN(x) ((x) << 0) | ||
766 | |||
767 | #define FW_EQ_OFLD_CMD_ALLOC (1U << 31) | ||
768 | #define FW_EQ_OFLD_CMD_FREE (1U << 30) | ||
769 | #define FW_EQ_OFLD_CMD_MODIFY (1U << 29) | ||
770 | #define FW_EQ_OFLD_CMD_EQSTART (1U << 28) | ||
771 | #define FW_EQ_OFLD_CMD_EQSTOP (1U << 27) | ||
772 | |||
773 | #define FW_EQ_OFLD_CMD_EQID(x) ((x) << 0) | ||
774 | #define FW_EQ_OFLD_CMD_EQID_GET(x) (((x) >> 0) & 0xfffff) | ||
775 | #define FW_EQ_OFLD_CMD_PHYSEQID_GET(x) (((x) >> 0) & 0xfffff) | ||
776 | |||
777 | #define FW_EQ_OFLD_CMD_FETCHSZM(x) ((x) << 26) | ||
778 | #define FW_EQ_OFLD_CMD_STATUSPGNS(x) ((x) << 25) | ||
779 | #define FW_EQ_OFLD_CMD_STATUSPGRO(x) ((x) << 24) | ||
780 | #define FW_EQ_OFLD_CMD_FETCHNS(x) ((x) << 23) | ||
781 | #define FW_EQ_OFLD_CMD_FETCHRO(x) ((x) << 22) | ||
782 | #define FW_EQ_OFLD_CMD_HOSTFCMODE(x) ((x) << 20) | ||
783 | #define FW_EQ_OFLD_CMD_CPRIO(x) ((x) << 19) | ||
784 | #define FW_EQ_OFLD_CMD_ONCHIP(x) ((x) << 18) | ||
785 | #define FW_EQ_OFLD_CMD_PCIECHN(x) ((x) << 16) | ||
786 | #define FW_EQ_OFLD_CMD_IQID(x) ((x) << 0) | ||
787 | |||
788 | #define FW_EQ_OFLD_CMD_DCAEN(x) ((x) << 31) | ||
789 | #define FW_EQ_OFLD_CMD_DCACPU(x) ((x) << 26) | ||
790 | #define FW_EQ_OFLD_CMD_FBMIN(x) ((x) << 23) | ||
791 | #define FW_EQ_OFLD_CMD_FBMAX(x) ((x) << 20) | ||
792 | #define FW_EQ_OFLD_CMD_CIDXFTHRESHO(x) ((x) << 19) | ||
793 | #define FW_EQ_OFLD_CMD_CIDXFTHRESH(x) ((x) << 16) | ||
794 | #define FW_EQ_OFLD_CMD_EQSIZE(x) ((x) << 0) | ||
795 | |||
796 | /* | ||
797 | * Macros for VIID parsing: | ||
798 | * VIID - [10:8] PFN, [7] VI Valid, [6:0] VI number | ||
799 | */ | ||
800 | #define FW_VIID_PFN_GET(x) (((x) >> 8) & 0x7) | ||
801 | #define FW_VIID_VIVLD_GET(x) (((x) >> 7) & 0x1) | ||
802 | #define FW_VIID_VIN_GET(x) (((x) >> 0) & 0x7F) | ||
803 | |||
804 | struct fw_vi_cmd { | ||
805 | __be32 op_to_vfn; | ||
806 | __be32 alloc_to_len16; | ||
807 | __be16 viid_pkd; | ||
808 | u8 mac[6]; | ||
809 | u8 portid_pkd; | ||
810 | u8 nmac; | ||
811 | u8 nmac0[6]; | ||
812 | __be16 rsssize_pkd; | ||
813 | u8 nmac1[6]; | ||
814 | __be16 r7; | ||
815 | u8 nmac2[6]; | ||
816 | __be16 r8; | ||
817 | u8 nmac3[6]; | ||
818 | __be64 r9; | ||
819 | __be64 r10; | ||
820 | }; | ||
821 | |||
822 | #define FW_VI_CMD_PFN(x) ((x) << 8) | ||
823 | #define FW_VI_CMD_VFN(x) ((x) << 0) | ||
824 | #define FW_VI_CMD_ALLOC (1U << 31) | ||
825 | #define FW_VI_CMD_FREE (1U << 30) | ||
826 | #define FW_VI_CMD_VIID(x) ((x) << 0) | ||
827 | #define FW_VI_CMD_PORTID(x) ((x) << 4) | ||
828 | #define FW_VI_CMD_RSSSIZE_GET(x) (((x) >> 0) & 0x7ff) | ||
829 | |||
830 | /* Special VI_MAC command index ids */ | ||
831 | #define FW_VI_MAC_ADD_MAC 0x3FF | ||
832 | #define FW_VI_MAC_ADD_PERSIST_MAC 0x3FE | ||
833 | #define FW_VI_MAC_MAC_BASED_FREE 0x3FD | ||
834 | |||
835 | enum fw_vi_mac_smac { | ||
836 | FW_VI_MAC_MPS_TCAM_ENTRY, | ||
837 | FW_VI_MAC_MPS_TCAM_ONLY, | ||
838 | FW_VI_MAC_SMT_ONLY, | ||
839 | FW_VI_MAC_SMT_AND_MPSTCAM | ||
840 | }; | ||
841 | |||
842 | enum fw_vi_mac_result { | ||
843 | FW_VI_MAC_R_SUCCESS, | ||
844 | FW_VI_MAC_R_F_NONEXISTENT_NOMEM, | ||
845 | FW_VI_MAC_R_SMAC_FAIL, | ||
846 | FW_VI_MAC_R_F_ACL_CHECK | ||
847 | }; | ||
848 | |||
849 | struct fw_vi_mac_cmd { | ||
850 | __be32 op_to_viid; | ||
851 | __be32 freemacs_to_len16; | ||
852 | union fw_vi_mac { | ||
853 | struct fw_vi_mac_exact { | ||
854 | __be16 valid_to_idx; | ||
855 | u8 macaddr[6]; | ||
856 | } exact[7]; | ||
857 | struct fw_vi_mac_hash { | ||
858 | __be64 hashvec; | ||
859 | } hash; | ||
860 | } u; | ||
861 | }; | ||
862 | |||
863 | #define FW_VI_MAC_CMD_VIID(x) ((x) << 0) | ||
864 | #define FW_VI_MAC_CMD_FREEMACS(x) ((x) << 31) | ||
865 | #define FW_VI_MAC_CMD_HASHVECEN (1U << 23) | ||
866 | #define FW_VI_MAC_CMD_HASHUNIEN(x) ((x) << 22) | ||
867 | #define FW_VI_MAC_CMD_VALID (1U << 15) | ||
868 | #define FW_VI_MAC_CMD_PRIO(x) ((x) << 12) | ||
869 | #define FW_VI_MAC_CMD_SMAC_RESULT(x) ((x) << 10) | ||
870 | #define FW_VI_MAC_CMD_SMAC_RESULT_GET(x) (((x) >> 10) & 0x3) | ||
871 | #define FW_VI_MAC_CMD_IDX(x) ((x) << 0) | ||
872 | #define FW_VI_MAC_CMD_IDX_GET(x) (((x) >> 0) & 0x3ff) | ||
873 | |||
874 | #define FW_RXMODE_MTU_NO_CHG 65535 | ||
875 | |||
876 | struct fw_vi_rxmode_cmd { | ||
877 | __be32 op_to_viid; | ||
878 | __be32 retval_len16; | ||
879 | __be32 mtu_to_broadcasten; | ||
880 | __be32 r4_lo; | ||
881 | }; | ||
882 | |||
883 | #define FW_VI_RXMODE_CMD_VIID(x) ((x) << 0) | ||
884 | #define FW_VI_RXMODE_CMD_MTU(x) ((x) << 16) | ||
885 | #define FW_VI_RXMODE_CMD_PROMISCEN_MASK 0x3 | ||
886 | #define FW_VI_RXMODE_CMD_PROMISCEN(x) ((x) << 14) | ||
887 | #define FW_VI_RXMODE_CMD_ALLMULTIEN_MASK 0x3 | ||
888 | #define FW_VI_RXMODE_CMD_ALLMULTIEN(x) ((x) << 12) | ||
889 | #define FW_VI_RXMODE_CMD_BROADCASTEN_MASK 0x3 | ||
890 | #define FW_VI_RXMODE_CMD_BROADCASTEN(x) ((x) << 10) | ||
891 | |||
892 | struct fw_vi_enable_cmd { | ||
893 | __be32 op_to_viid; | ||
894 | __be32 ien_to_len16; | ||
895 | __be16 blinkdur; | ||
896 | __be16 r3; | ||
897 | __be32 r4; | ||
898 | }; | ||
899 | |||
900 | #define FW_VI_ENABLE_CMD_VIID(x) ((x) << 0) | ||
901 | #define FW_VI_ENABLE_CMD_IEN(x) ((x) << 31) | ||
902 | #define FW_VI_ENABLE_CMD_EEN(x) ((x) << 30) | ||
903 | #define FW_VI_ENABLE_CMD_LED (1U << 29) | ||
904 | |||
905 | /* VI VF stats offset definitions */ | ||
906 | #define VI_VF_NUM_STATS 16 | ||
907 | enum fw_vi_stats_vf_index { | ||
908 | FW_VI_VF_STAT_TX_BCAST_BYTES_IX, | ||
909 | FW_VI_VF_STAT_TX_BCAST_FRAMES_IX, | ||
910 | FW_VI_VF_STAT_TX_MCAST_BYTES_IX, | ||
911 | FW_VI_VF_STAT_TX_MCAST_FRAMES_IX, | ||
912 | FW_VI_VF_STAT_TX_UCAST_BYTES_IX, | ||
913 | FW_VI_VF_STAT_TX_UCAST_FRAMES_IX, | ||
914 | FW_VI_VF_STAT_TX_DROP_FRAMES_IX, | ||
915 | FW_VI_VF_STAT_TX_OFLD_BYTES_IX, | ||
916 | FW_VI_VF_STAT_TX_OFLD_FRAMES_IX, | ||
917 | FW_VI_VF_STAT_RX_BCAST_BYTES_IX, | ||
918 | FW_VI_VF_STAT_RX_BCAST_FRAMES_IX, | ||
919 | FW_VI_VF_STAT_RX_MCAST_BYTES_IX, | ||
920 | FW_VI_VF_STAT_RX_MCAST_FRAMES_IX, | ||
921 | FW_VI_VF_STAT_RX_UCAST_BYTES_IX, | ||
922 | FW_VI_VF_STAT_RX_UCAST_FRAMES_IX, | ||
923 | FW_VI_VF_STAT_RX_ERR_FRAMES_IX | ||
924 | }; | ||
925 | |||
926 | /* VI PF stats offset definitions */ | ||
927 | #define VI_PF_NUM_STATS 17 | ||
928 | enum fw_vi_stats_pf_index { | ||
929 | FW_VI_PF_STAT_TX_BCAST_BYTES_IX, | ||
930 | FW_VI_PF_STAT_TX_BCAST_FRAMES_IX, | ||
931 | FW_VI_PF_STAT_TX_MCAST_BYTES_IX, | ||
932 | FW_VI_PF_STAT_TX_MCAST_FRAMES_IX, | ||
933 | FW_VI_PF_STAT_TX_UCAST_BYTES_IX, | ||
934 | FW_VI_PF_STAT_TX_UCAST_FRAMES_IX, | ||
935 | FW_VI_PF_STAT_TX_OFLD_BYTES_IX, | ||
936 | FW_VI_PF_STAT_TX_OFLD_FRAMES_IX, | ||
937 | FW_VI_PF_STAT_RX_BYTES_IX, | ||
938 | FW_VI_PF_STAT_RX_FRAMES_IX, | ||
939 | FW_VI_PF_STAT_RX_BCAST_BYTES_IX, | ||
940 | FW_VI_PF_STAT_RX_BCAST_FRAMES_IX, | ||
941 | FW_VI_PF_STAT_RX_MCAST_BYTES_IX, | ||
942 | FW_VI_PF_STAT_RX_MCAST_FRAMES_IX, | ||
943 | FW_VI_PF_STAT_RX_UCAST_BYTES_IX, | ||
944 | FW_VI_PF_STAT_RX_UCAST_FRAMES_IX, | ||
945 | FW_VI_PF_STAT_RX_ERR_FRAMES_IX | ||
946 | }; | ||
947 | |||
948 | struct fw_vi_stats_cmd { | ||
949 | __be32 op_to_viid; | ||
950 | __be32 retval_len16; | ||
951 | union fw_vi_stats { | ||
952 | struct fw_vi_stats_ctl { | ||
953 | __be16 nstats_ix; | ||
954 | __be16 r6; | ||
955 | __be32 r7; | ||
956 | __be64 stat0; | ||
957 | __be64 stat1; | ||
958 | __be64 stat2; | ||
959 | __be64 stat3; | ||
960 | __be64 stat4; | ||
961 | __be64 stat5; | ||
962 | } ctl; | ||
963 | struct fw_vi_stats_pf { | ||
964 | __be64 tx_bcast_bytes; | ||
965 | __be64 tx_bcast_frames; | ||
966 | __be64 tx_mcast_bytes; | ||
967 | __be64 tx_mcast_frames; | ||
968 | __be64 tx_ucast_bytes; | ||
969 | __be64 tx_ucast_frames; | ||
970 | __be64 tx_offload_bytes; | ||
971 | __be64 tx_offload_frames; | ||
972 | __be64 rx_pf_bytes; | ||
973 | __be64 rx_pf_frames; | ||
974 | __be64 rx_bcast_bytes; | ||
975 | __be64 rx_bcast_frames; | ||
976 | __be64 rx_mcast_bytes; | ||
977 | __be64 rx_mcast_frames; | ||
978 | __be64 rx_ucast_bytes; | ||
979 | __be64 rx_ucast_frames; | ||
980 | __be64 rx_err_frames; | ||
981 | } pf; | ||
982 | struct fw_vi_stats_vf { | ||
983 | __be64 tx_bcast_bytes; | ||
984 | __be64 tx_bcast_frames; | ||
985 | __be64 tx_mcast_bytes; | ||
986 | __be64 tx_mcast_frames; | ||
987 | __be64 tx_ucast_bytes; | ||
988 | __be64 tx_ucast_frames; | ||
989 | __be64 tx_drop_frames; | ||
990 | __be64 tx_offload_bytes; | ||
991 | __be64 tx_offload_frames; | ||
992 | __be64 rx_bcast_bytes; | ||
993 | __be64 rx_bcast_frames; | ||
994 | __be64 rx_mcast_bytes; | ||
995 | __be64 rx_mcast_frames; | ||
996 | __be64 rx_ucast_bytes; | ||
997 | __be64 rx_ucast_frames; | ||
998 | __be64 rx_err_frames; | ||
999 | } vf; | ||
1000 | } u; | ||
1001 | }; | ||
1002 | |||
1003 | #define FW_VI_STATS_CMD_VIID(x) ((x) << 0) | ||
1004 | #define FW_VI_STATS_CMD_NSTATS(x) ((x) << 12) | ||
1005 | #define FW_VI_STATS_CMD_IX(x) ((x) << 0) | ||
1006 | |||
1007 | struct fw_acl_mac_cmd { | ||
1008 | __be32 op_to_vfn; | ||
1009 | __be32 en_to_len16; | ||
1010 | u8 nmac; | ||
1011 | u8 r3[7]; | ||
1012 | __be16 r4; | ||
1013 | u8 macaddr0[6]; | ||
1014 | __be16 r5; | ||
1015 | u8 macaddr1[6]; | ||
1016 | __be16 r6; | ||
1017 | u8 macaddr2[6]; | ||
1018 | __be16 r7; | ||
1019 | u8 macaddr3[6]; | ||
1020 | }; | ||
1021 | |||
1022 | #define FW_ACL_MAC_CMD_PFN(x) ((x) << 8) | ||
1023 | #define FW_ACL_MAC_CMD_VFN(x) ((x) << 0) | ||
1024 | #define FW_ACL_MAC_CMD_EN(x) ((x) << 31) | ||
1025 | |||
1026 | struct fw_acl_vlan_cmd { | ||
1027 | __be32 op_to_vfn; | ||
1028 | __be32 en_to_len16; | ||
1029 | u8 nvlan; | ||
1030 | u8 dropnovlan_fm; | ||
1031 | u8 r3_lo[6]; | ||
1032 | __be16 vlanid[16]; | ||
1033 | }; | ||
1034 | |||
1035 | #define FW_ACL_VLAN_CMD_PFN(x) ((x) << 8) | ||
1036 | #define FW_ACL_VLAN_CMD_VFN(x) ((x) << 0) | ||
1037 | #define FW_ACL_VLAN_CMD_EN(x) ((x) << 31) | ||
1038 | #define FW_ACL_VLAN_CMD_DROPNOVLAN(x) ((x) << 7) | ||
1039 | #define FW_ACL_VLAN_CMD_FM(x) ((x) << 6) | ||
1040 | |||
1041 | enum fw_port_cap { | ||
1042 | FW_PORT_CAP_SPEED_100M = 0x0001, | ||
1043 | FW_PORT_CAP_SPEED_1G = 0x0002, | ||
1044 | FW_PORT_CAP_SPEED_2_5G = 0x0004, | ||
1045 | FW_PORT_CAP_SPEED_10G = 0x0008, | ||
1046 | FW_PORT_CAP_SPEED_40G = 0x0010, | ||
1047 | FW_PORT_CAP_SPEED_100G = 0x0020, | ||
1048 | FW_PORT_CAP_FC_RX = 0x0040, | ||
1049 | FW_PORT_CAP_FC_TX = 0x0080, | ||
1050 | FW_PORT_CAP_ANEG = 0x0100, | ||
1051 | FW_PORT_CAP_MDI_0 = 0x0200, | ||
1052 | FW_PORT_CAP_MDI_1 = 0x0400, | ||
1053 | FW_PORT_CAP_BEAN = 0x0800, | ||
1054 | FW_PORT_CAP_PMA_LPBK = 0x1000, | ||
1055 | FW_PORT_CAP_PCS_LPBK = 0x2000, | ||
1056 | FW_PORT_CAP_PHYXS_LPBK = 0x4000, | ||
1057 | FW_PORT_CAP_FAR_END_LPBK = 0x8000, | ||
1058 | }; | ||
1059 | |||
1060 | enum fw_port_mdi { | ||
1061 | FW_PORT_MDI_UNCHANGED, | ||
1062 | FW_PORT_MDI_AUTO, | ||
1063 | FW_PORT_MDI_F_STRAIGHT, | ||
1064 | FW_PORT_MDI_F_CROSSOVER | ||
1065 | }; | ||
1066 | |||
1067 | #define FW_PORT_MDI(x) ((x) << 9) | ||
1068 | |||
1069 | enum fw_port_action { | ||
1070 | FW_PORT_ACTION_L1_CFG = 0x0001, | ||
1071 | FW_PORT_ACTION_L2_CFG = 0x0002, | ||
1072 | FW_PORT_ACTION_GET_PORT_INFO = 0x0003, | ||
1073 | FW_PORT_ACTION_L2_PPP_CFG = 0x0004, | ||
1074 | FW_PORT_ACTION_L2_DCB_CFG = 0x0005, | ||
1075 | FW_PORT_ACTION_LOW_PWR_TO_NORMAL = 0x0010, | ||
1076 | FW_PORT_ACTION_L1_LOW_PWR_EN = 0x0011, | ||
1077 | FW_PORT_ACTION_L2_WOL_MODE_EN = 0x0012, | ||
1078 | FW_PORT_ACTION_LPBK_TO_NORMAL = 0x0020, | ||
1079 | FW_PORT_ACTION_L1_LPBK = 0x0021, | ||
1080 | FW_PORT_ACTION_L1_PMA_LPBK = 0x0022, | ||
1081 | FW_PORT_ACTION_L1_PCS_LPBK = 0x0023, | ||
1082 | FW_PORT_ACTION_L1_PHYXS_CSIDE_LPBK = 0x0024, | ||
1083 | FW_PORT_ACTION_L1_PHYXS_ESIDE_LPBK = 0x0025, | ||
1084 | FW_PORT_ACTION_PHY_RESET = 0x0040, | ||
1085 | FW_PORT_ACTION_PMA_RESET = 0x0041, | ||
1086 | FW_PORT_ACTION_PCS_RESET = 0x0042, | ||
1087 | FW_PORT_ACTION_PHYXS_RESET = 0x0043, | ||
1088 | FW_PORT_ACTION_DTEXS_REEST = 0x0044, | ||
1089 | FW_PORT_ACTION_AN_RESET = 0x0045 | ||
1090 | }; | ||
1091 | |||
1092 | enum fw_port_l2cfg_ctlbf { | ||
1093 | FW_PORT_L2_CTLBF_OVLAN0 = 0x01, | ||
1094 | FW_PORT_L2_CTLBF_OVLAN1 = 0x02, | ||
1095 | FW_PORT_L2_CTLBF_OVLAN2 = 0x04, | ||
1096 | FW_PORT_L2_CTLBF_OVLAN3 = 0x08, | ||
1097 | FW_PORT_L2_CTLBF_IVLAN = 0x10, | ||
1098 | FW_PORT_L2_CTLBF_TXIPG = 0x20 | ||
1099 | }; | ||
1100 | |||
1101 | enum fw_port_dcb_cfg { | ||
1102 | FW_PORT_DCB_CFG_PG = 0x01, | ||
1103 | FW_PORT_DCB_CFG_PFC = 0x02, | ||
1104 | FW_PORT_DCB_CFG_APPL = 0x04 | ||
1105 | }; | ||
1106 | |||
1107 | enum fw_port_dcb_cfg_rc { | ||
1108 | FW_PORT_DCB_CFG_SUCCESS = 0x0, | ||
1109 | FW_PORT_DCB_CFG_ERROR = 0x1 | ||
1110 | }; | ||
1111 | |||
1112 | struct fw_port_cmd { | ||
1113 | __be32 op_to_portid; | ||
1114 | __be32 action_to_len16; | ||
1115 | union fw_port { | ||
1116 | struct fw_port_l1cfg { | ||
1117 | __be32 rcap; | ||
1118 | __be32 r; | ||
1119 | } l1cfg; | ||
1120 | struct fw_port_l2cfg { | ||
1121 | __be16 ctlbf_to_ivlan0; | ||
1122 | __be16 ivlantype; | ||
1123 | __be32 txipg_pkd; | ||
1124 | __be16 ovlan0mask; | ||
1125 | __be16 ovlan0type; | ||
1126 | __be16 ovlan1mask; | ||
1127 | __be16 ovlan1type; | ||
1128 | __be16 ovlan2mask; | ||
1129 | __be16 ovlan2type; | ||
1130 | __be16 ovlan3mask; | ||
1131 | __be16 ovlan3type; | ||
1132 | } l2cfg; | ||
1133 | struct fw_port_info { | ||
1134 | __be32 lstatus_to_modtype; | ||
1135 | __be16 pcap; | ||
1136 | __be16 acap; | ||
1137 | } info; | ||
1138 | struct fw_port_ppp { | ||
1139 | __be32 pppen_to_ncsich; | ||
1140 | __be32 r11; | ||
1141 | } ppp; | ||
1142 | struct fw_port_dcb { | ||
1143 | __be16 cfg; | ||
1144 | u8 up_map; | ||
1145 | u8 sf_cfgrc; | ||
1146 | __be16 prot_ix; | ||
1147 | u8 pe7_to_pe0; | ||
1148 | u8 numTCPFCs; | ||
1149 | __be32 pgid0_to_pgid7; | ||
1150 | __be32 numTCs_oui; | ||
1151 | u8 pgpc[8]; | ||
1152 | } dcb; | ||
1153 | } u; | ||
1154 | }; | ||
1155 | |||
1156 | #define FW_PORT_CMD_READ (1U << 22) | ||
1157 | |||
1158 | #define FW_PORT_CMD_PORTID(x) ((x) << 0) | ||
1159 | #define FW_PORT_CMD_PORTID_GET(x) (((x) >> 0) & 0xf) | ||
1160 | |||
1161 | #define FW_PORT_CMD_ACTION(x) ((x) << 16) | ||
1162 | |||
1163 | #define FW_PORT_CMD_CTLBF(x) ((x) << 10) | ||
1164 | #define FW_PORT_CMD_OVLAN3(x) ((x) << 7) | ||
1165 | #define FW_PORT_CMD_OVLAN2(x) ((x) << 6) | ||
1166 | #define FW_PORT_CMD_OVLAN1(x) ((x) << 5) | ||
1167 | #define FW_PORT_CMD_OVLAN0(x) ((x) << 4) | ||
1168 | #define FW_PORT_CMD_IVLAN0(x) ((x) << 3) | ||
1169 | |||
1170 | #define FW_PORT_CMD_TXIPG(x) ((x) << 19) | ||
1171 | |||
1172 | #define FW_PORT_CMD_LSTATUS (1U << 31) | ||
1173 | #define FW_PORT_CMD_LSPEED(x) ((x) << 24) | ||
1174 | #define FW_PORT_CMD_LSPEED_GET(x) (((x) >> 24) & 0x3f) | ||
1175 | #define FW_PORT_CMD_TXPAUSE (1U << 23) | ||
1176 | #define FW_PORT_CMD_RXPAUSE (1U << 22) | ||
1177 | #define FW_PORT_CMD_MDIOCAP (1U << 21) | ||
1178 | #define FW_PORT_CMD_MDIOADDR_GET(x) (((x) >> 16) & 0x1f) | ||
1179 | #define FW_PORT_CMD_LPTXPAUSE (1U << 15) | ||
1180 | #define FW_PORT_CMD_LPRXPAUSE (1U << 14) | ||
1181 | #define FW_PORT_CMD_PTYPE_MASK 0x1f | ||
1182 | #define FW_PORT_CMD_PTYPE_GET(x) (((x) >> 8) & FW_PORT_CMD_PTYPE_MASK) | ||
1183 | #define FW_PORT_CMD_MODTYPE_MASK 0x1f | ||
1184 | #define FW_PORT_CMD_MODTYPE_GET(x) (((x) >> 0) & FW_PORT_CMD_MODTYPE_MASK) | ||
1185 | |||
1186 | #define FW_PORT_CMD_PPPEN(x) ((x) << 31) | ||
1187 | #define FW_PORT_CMD_TPSRC(x) ((x) << 28) | ||
1188 | #define FW_PORT_CMD_NCSISRC(x) ((x) << 24) | ||
1189 | |||
1190 | #define FW_PORT_CMD_CH0(x) ((x) << 20) | ||
1191 | #define FW_PORT_CMD_CH1(x) ((x) << 16) | ||
1192 | #define FW_PORT_CMD_CH2(x) ((x) << 12) | ||
1193 | #define FW_PORT_CMD_CH3(x) ((x) << 8) | ||
1194 | #define FW_PORT_CMD_NCSICH(x) ((x) << 4) | ||
1195 | |||
1196 | enum fw_port_type { | ||
1197 | FW_PORT_TYPE_FIBER, | ||
1198 | FW_PORT_TYPE_KX4, | ||
1199 | FW_PORT_TYPE_BT_SGMII, | ||
1200 | FW_PORT_TYPE_KX, | ||
1201 | FW_PORT_TYPE_BT_XAUI, | ||
1202 | FW_PORT_TYPE_KR, | ||
1203 | FW_PORT_TYPE_CX4, | ||
1204 | FW_PORT_TYPE_TWINAX, | ||
1205 | |||
1206 | FW_PORT_TYPE_NONE = FW_PORT_CMD_PTYPE_MASK | ||
1207 | }; | ||
1208 | |||
1209 | enum fw_port_module_type { | ||
1210 | FW_PORT_MOD_TYPE_NA, | ||
1211 | FW_PORT_MOD_TYPE_LR, | ||
1212 | FW_PORT_MOD_TYPE_SR, | ||
1213 | FW_PORT_MOD_TYPE_ER, | ||
1214 | |||
1215 | FW_PORT_MOD_TYPE_NONE = FW_PORT_CMD_MODTYPE_MASK | ||
1216 | }; | ||
1217 | |||
1218 | /* port stats */ | ||
1219 | #define FW_NUM_PORT_STATS 50 | ||
1220 | #define FW_NUM_PORT_TX_STATS 23 | ||
1221 | #define FW_NUM_PORT_RX_STATS 27 | ||
1222 | |||
1223 | enum fw_port_stats_tx_index { | ||
1224 | FW_STAT_TX_PORT_BYTES_IX, | ||
1225 | FW_STAT_TX_PORT_FRAMES_IX, | ||
1226 | FW_STAT_TX_PORT_BCAST_IX, | ||
1227 | FW_STAT_TX_PORT_MCAST_IX, | ||
1228 | FW_STAT_TX_PORT_UCAST_IX, | ||
1229 | FW_STAT_TX_PORT_ERROR_IX, | ||
1230 | FW_STAT_TX_PORT_64B_IX, | ||
1231 | FW_STAT_TX_PORT_65B_127B_IX, | ||
1232 | FW_STAT_TX_PORT_128B_255B_IX, | ||
1233 | FW_STAT_TX_PORT_256B_511B_IX, | ||
1234 | FW_STAT_TX_PORT_512B_1023B_IX, | ||
1235 | FW_STAT_TX_PORT_1024B_1518B_IX, | ||
1236 | FW_STAT_TX_PORT_1519B_MAX_IX, | ||
1237 | FW_STAT_TX_PORT_DROP_IX, | ||
1238 | FW_STAT_TX_PORT_PAUSE_IX, | ||
1239 | FW_STAT_TX_PORT_PPP0_IX, | ||
1240 | FW_STAT_TX_PORT_PPP1_IX, | ||
1241 | FW_STAT_TX_PORT_PPP2_IX, | ||
1242 | FW_STAT_TX_PORT_PPP3_IX, | ||
1243 | FW_STAT_TX_PORT_PPP4_IX, | ||
1244 | FW_STAT_TX_PORT_PPP5_IX, | ||
1245 | FW_STAT_TX_PORT_PPP6_IX, | ||
1246 | FW_STAT_TX_PORT_PPP7_IX | ||
1247 | }; | ||
1248 | |||
1249 | enum fw_port_stat_rx_index { | ||
1250 | FW_STAT_RX_PORT_BYTES_IX, | ||
1251 | FW_STAT_RX_PORT_FRAMES_IX, | ||
1252 | FW_STAT_RX_PORT_BCAST_IX, | ||
1253 | FW_STAT_RX_PORT_MCAST_IX, | ||
1254 | FW_STAT_RX_PORT_UCAST_IX, | ||
1255 | FW_STAT_RX_PORT_MTU_ERROR_IX, | ||
1256 | FW_STAT_RX_PORT_MTU_CRC_ERROR_IX, | ||
1257 | FW_STAT_RX_PORT_CRC_ERROR_IX, | ||
1258 | FW_STAT_RX_PORT_LEN_ERROR_IX, | ||
1259 | FW_STAT_RX_PORT_SYM_ERROR_IX, | ||
1260 | FW_STAT_RX_PORT_64B_IX, | ||
1261 | FW_STAT_RX_PORT_65B_127B_IX, | ||
1262 | FW_STAT_RX_PORT_128B_255B_IX, | ||
1263 | FW_STAT_RX_PORT_256B_511B_IX, | ||
1264 | FW_STAT_RX_PORT_512B_1023B_IX, | ||
1265 | FW_STAT_RX_PORT_1024B_1518B_IX, | ||
1266 | FW_STAT_RX_PORT_1519B_MAX_IX, | ||
1267 | FW_STAT_RX_PORT_PAUSE_IX, | ||
1268 | FW_STAT_RX_PORT_PPP0_IX, | ||
1269 | FW_STAT_RX_PORT_PPP1_IX, | ||
1270 | FW_STAT_RX_PORT_PPP2_IX, | ||
1271 | FW_STAT_RX_PORT_PPP3_IX, | ||
1272 | FW_STAT_RX_PORT_PPP4_IX, | ||
1273 | FW_STAT_RX_PORT_PPP5_IX, | ||
1274 | FW_STAT_RX_PORT_PPP6_IX, | ||
1275 | FW_STAT_RX_PORT_PPP7_IX, | ||
1276 | FW_STAT_RX_PORT_LESS_64B_IX | ||
1277 | }; | ||
1278 | |||
1279 | struct fw_port_stats_cmd { | ||
1280 | __be32 op_to_portid; | ||
1281 | __be32 retval_len16; | ||
1282 | union fw_port_stats { | ||
1283 | struct fw_port_stats_ctl { | ||
1284 | u8 nstats_bg_bm; | ||
1285 | u8 tx_ix; | ||
1286 | __be16 r6; | ||
1287 | __be32 r7; | ||
1288 | __be64 stat0; | ||
1289 | __be64 stat1; | ||
1290 | __be64 stat2; | ||
1291 | __be64 stat3; | ||
1292 | __be64 stat4; | ||
1293 | __be64 stat5; | ||
1294 | } ctl; | ||
1295 | struct fw_port_stats_all { | ||
1296 | __be64 tx_bytes; | ||
1297 | __be64 tx_frames; | ||
1298 | __be64 tx_bcast; | ||
1299 | __be64 tx_mcast; | ||
1300 | __be64 tx_ucast; | ||
1301 | __be64 tx_error; | ||
1302 | __be64 tx_64b; | ||
1303 | __be64 tx_65b_127b; | ||
1304 | __be64 tx_128b_255b; | ||
1305 | __be64 tx_256b_511b; | ||
1306 | __be64 tx_512b_1023b; | ||
1307 | __be64 tx_1024b_1518b; | ||
1308 | __be64 tx_1519b_max; | ||
1309 | __be64 tx_drop; | ||
1310 | __be64 tx_pause; | ||
1311 | __be64 tx_ppp0; | ||
1312 | __be64 tx_ppp1; | ||
1313 | __be64 tx_ppp2; | ||
1314 | __be64 tx_ppp3; | ||
1315 | __be64 tx_ppp4; | ||
1316 | __be64 tx_ppp5; | ||
1317 | __be64 tx_ppp6; | ||
1318 | __be64 tx_ppp7; | ||
1319 | __be64 rx_bytes; | ||
1320 | __be64 rx_frames; | ||
1321 | __be64 rx_bcast; | ||
1322 | __be64 rx_mcast; | ||
1323 | __be64 rx_ucast; | ||
1324 | __be64 rx_mtu_error; | ||
1325 | __be64 rx_mtu_crc_error; | ||
1326 | __be64 rx_crc_error; | ||
1327 | __be64 rx_len_error; | ||
1328 | __be64 rx_sym_error; | ||
1329 | __be64 rx_64b; | ||
1330 | __be64 rx_65b_127b; | ||
1331 | __be64 rx_128b_255b; | ||
1332 | __be64 rx_256b_511b; | ||
1333 | __be64 rx_512b_1023b; | ||
1334 | __be64 rx_1024b_1518b; | ||
1335 | __be64 rx_1519b_max; | ||
1336 | __be64 rx_pause; | ||
1337 | __be64 rx_ppp0; | ||
1338 | __be64 rx_ppp1; | ||
1339 | __be64 rx_ppp2; | ||
1340 | __be64 rx_ppp3; | ||
1341 | __be64 rx_ppp4; | ||
1342 | __be64 rx_ppp5; | ||
1343 | __be64 rx_ppp6; | ||
1344 | __be64 rx_ppp7; | ||
1345 | __be64 rx_less_64b; | ||
1346 | __be64 rx_bg_drop; | ||
1347 | __be64 rx_bg_trunc; | ||
1348 | } all; | ||
1349 | } u; | ||
1350 | }; | ||
1351 | |||
1352 | #define FW_PORT_STATS_CMD_NSTATS(x) ((x) << 4) | ||
1353 | #define FW_PORT_STATS_CMD_BG_BM(x) ((x) << 0) | ||
1354 | #define FW_PORT_STATS_CMD_TX(x) ((x) << 7) | ||
1355 | #define FW_PORT_STATS_CMD_IX(x) ((x) << 0) | ||
1356 | |||
1357 | /* port loopback stats */ | ||
1358 | #define FW_NUM_LB_STATS 16 | ||
1359 | enum fw_port_lb_stats_index { | ||
1360 | FW_STAT_LB_PORT_BYTES_IX, | ||
1361 | FW_STAT_LB_PORT_FRAMES_IX, | ||
1362 | FW_STAT_LB_PORT_BCAST_IX, | ||
1363 | FW_STAT_LB_PORT_MCAST_IX, | ||
1364 | FW_STAT_LB_PORT_UCAST_IX, | ||
1365 | FW_STAT_LB_PORT_ERROR_IX, | ||
1366 | FW_STAT_LB_PORT_64B_IX, | ||
1367 | FW_STAT_LB_PORT_65B_127B_IX, | ||
1368 | FW_STAT_LB_PORT_128B_255B_IX, | ||
1369 | FW_STAT_LB_PORT_256B_511B_IX, | ||
1370 | FW_STAT_LB_PORT_512B_1023B_IX, | ||
1371 | FW_STAT_LB_PORT_1024B_1518B_IX, | ||
1372 | FW_STAT_LB_PORT_1519B_MAX_IX, | ||
1373 | FW_STAT_LB_PORT_DROP_FRAMES_IX | ||
1374 | }; | ||
1375 | |||
1376 | struct fw_port_lb_stats_cmd { | ||
1377 | __be32 op_to_lbport; | ||
1378 | __be32 retval_len16; | ||
1379 | union fw_port_lb_stats { | ||
1380 | struct fw_port_lb_stats_ctl { | ||
1381 | u8 nstats_bg_bm; | ||
1382 | u8 ix_pkd; | ||
1383 | __be16 r6; | ||
1384 | __be32 r7; | ||
1385 | __be64 stat0; | ||
1386 | __be64 stat1; | ||
1387 | __be64 stat2; | ||
1388 | __be64 stat3; | ||
1389 | __be64 stat4; | ||
1390 | __be64 stat5; | ||
1391 | } ctl; | ||
1392 | struct fw_port_lb_stats_all { | ||
1393 | __be64 tx_bytes; | ||
1394 | __be64 tx_frames; | ||
1395 | __be64 tx_bcast; | ||
1396 | __be64 tx_mcast; | ||
1397 | __be64 tx_ucast; | ||
1398 | __be64 tx_error; | ||
1399 | __be64 tx_64b; | ||
1400 | __be64 tx_65b_127b; | ||
1401 | __be64 tx_128b_255b; | ||
1402 | __be64 tx_256b_511b; | ||
1403 | __be64 tx_512b_1023b; | ||
1404 | __be64 tx_1024b_1518b; | ||
1405 | __be64 tx_1519b_max; | ||
1406 | __be64 rx_lb_drop; | ||
1407 | __be64 rx_lb_trunc; | ||
1408 | } all; | ||
1409 | } u; | ||
1410 | }; | ||
1411 | |||
1412 | #define FW_PORT_LB_STATS_CMD_LBPORT(x) ((x) << 0) | ||
1413 | #define FW_PORT_LB_STATS_CMD_NSTATS(x) ((x) << 4) | ||
1414 | #define FW_PORT_LB_STATS_CMD_BG_BM(x) ((x) << 0) | ||
1415 | #define FW_PORT_LB_STATS_CMD_IX(x) ((x) << 0) | ||
1416 | |||
1417 | struct fw_rss_ind_tbl_cmd { | ||
1418 | __be32 op_to_viid; | ||
1419 | #define FW_RSS_IND_TBL_CMD_VIID(x) ((x) << 0) | ||
1420 | __be32 retval_len16; | ||
1421 | __be16 niqid; | ||
1422 | __be16 startidx; | ||
1423 | __be32 r3; | ||
1424 | __be32 iq0_to_iq2; | ||
1425 | #define FW_RSS_IND_TBL_CMD_IQ0(x) ((x) << 20) | ||
1426 | #define FW_RSS_IND_TBL_CMD_IQ1(x) ((x) << 10) | ||
1427 | #define FW_RSS_IND_TBL_CMD_IQ2(x) ((x) << 0) | ||
1428 | __be32 iq3_to_iq5; | ||
1429 | __be32 iq6_to_iq8; | ||
1430 | __be32 iq9_to_iq11; | ||
1431 | __be32 iq12_to_iq14; | ||
1432 | __be32 iq15_to_iq17; | ||
1433 | __be32 iq18_to_iq20; | ||
1434 | __be32 iq21_to_iq23; | ||
1435 | __be32 iq24_to_iq26; | ||
1436 | __be32 iq27_to_iq29; | ||
1437 | __be32 iq30_iq31; | ||
1438 | __be32 r15_lo; | ||
1439 | }; | ||
1440 | |||
1441 | struct fw_rss_glb_config_cmd { | ||
1442 | __be32 op_to_write; | ||
1443 | __be32 retval_len16; | ||
1444 | union fw_rss_glb_config { | ||
1445 | struct fw_rss_glb_config_manual { | ||
1446 | __be32 mode_pkd; | ||
1447 | __be32 r3; | ||
1448 | __be64 r4; | ||
1449 | __be64 r5; | ||
1450 | } manual; | ||
1451 | struct fw_rss_glb_config_basicvirtual { | ||
1452 | __be32 mode_pkd; | ||
1453 | __be32 synmapen_to_hashtoeplitz; | ||
1454 | #define FW_RSS_GLB_CONFIG_CMD_SYNMAPEN (1U << 8) | ||
1455 | #define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6 (1U << 7) | ||
1456 | #define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6 (1U << 6) | ||
1457 | #define FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4 (1U << 5) | ||
1458 | #define FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4 (1U << 4) | ||
1459 | #define FW_RSS_GLB_CONFIG_CMD_OFDMAPEN (1U << 3) | ||
1460 | #define FW_RSS_GLB_CONFIG_CMD_TNLMAPEN (1U << 2) | ||
1461 | #define FW_RSS_GLB_CONFIG_CMD_TNLALLLKP (1U << 1) | ||
1462 | #define FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ (1U << 0) | ||
1463 | __be64 r8; | ||
1464 | __be64 r9; | ||
1465 | } basicvirtual; | ||
1466 | } u; | ||
1467 | }; | ||
1468 | |||
1469 | #define FW_RSS_GLB_CONFIG_CMD_MODE(x) ((x) << 28) | ||
1470 | |||
1471 | #define FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL 0 | ||
1472 | #define FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL 1 | ||
1473 | |||
1474 | struct fw_rss_vi_config_cmd { | ||
1475 | __be32 op_to_viid; | ||
1476 | #define FW_RSS_VI_CONFIG_CMD_VIID(x) ((x) << 0) | ||
1477 | __be32 retval_len16; | ||
1478 | union fw_rss_vi_config { | ||
1479 | struct fw_rss_vi_config_manual { | ||
1480 | __be64 r3; | ||
1481 | __be64 r4; | ||
1482 | __be64 r5; | ||
1483 | } manual; | ||
1484 | struct fw_rss_vi_config_basicvirtual { | ||
1485 | __be32 r6; | ||
1486 | __be32 defaultq_to_ip4udpen; | ||
1487 | #define FW_RSS_VI_CONFIG_CMD_DEFAULTQ(x) ((x) << 16) | ||
1488 | #define FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN (1U << 4) | ||
1489 | #define FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN (1U << 3) | ||
1490 | #define FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN (1U << 2) | ||
1491 | #define FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN (1U << 1) | ||
1492 | #define FW_RSS_VI_CONFIG_CMD_IP4UDPEN (1U << 0) | ||
1493 | __be64 r9; | ||
1494 | __be64 r10; | ||
1495 | } basicvirtual; | ||
1496 | } u; | ||
1497 | }; | ||
1498 | |||
1499 | enum fw_error_type { | ||
1500 | FW_ERROR_TYPE_EXCEPTION = 0x0, | ||
1501 | FW_ERROR_TYPE_HWMODULE = 0x1, | ||
1502 | FW_ERROR_TYPE_WR = 0x2, | ||
1503 | FW_ERROR_TYPE_ACL = 0x3, | ||
1504 | }; | ||
1505 | |||
1506 | struct fw_error_cmd { | ||
1507 | __be32 op_to_type; | ||
1508 | __be32 len16_pkd; | ||
1509 | union fw_error { | ||
1510 | struct fw_error_exception { | ||
1511 | __be32 info[6]; | ||
1512 | } exception; | ||
1513 | struct fw_error_hwmodule { | ||
1514 | __be32 regaddr; | ||
1515 | __be32 regval; | ||
1516 | } hwmodule; | ||
1517 | struct fw_error_wr { | ||
1518 | __be16 cidx; | ||
1519 | __be16 pfn_vfn; | ||
1520 | __be32 eqid; | ||
1521 | u8 wrhdr[16]; | ||
1522 | } wr; | ||
1523 | struct fw_error_acl { | ||
1524 | __be16 cidx; | ||
1525 | __be16 pfn_vfn; | ||
1526 | __be32 eqid; | ||
1527 | __be16 mv_pkd; | ||
1528 | u8 val[6]; | ||
1529 | __be64 r4; | ||
1530 | } acl; | ||
1531 | } u; | ||
1532 | }; | ||
1533 | |||
1534 | struct fw_debug_cmd { | ||
1535 | __be32 op_type; | ||
1536 | #define FW_DEBUG_CMD_TYPE_GET(x) ((x) & 0xff) | ||
1537 | __be32 len16_pkd; | ||
1538 | union fw_debug { | ||
1539 | struct fw_debug_assert { | ||
1540 | __be32 fcid; | ||
1541 | __be32 line; | ||
1542 | __be32 x; | ||
1543 | __be32 y; | ||
1544 | u8 filename_0_7[8]; | ||
1545 | u8 filename_8_15[8]; | ||
1546 | __be64 r3; | ||
1547 | } assert; | ||
1548 | struct fw_debug_prt { | ||
1549 | __be16 dprtstridx; | ||
1550 | __be16 r3[3]; | ||
1551 | __be32 dprtstrparam0; | ||
1552 | __be32 dprtstrparam1; | ||
1553 | __be32 dprtstrparam2; | ||
1554 | __be32 dprtstrparam3; | ||
1555 | } prt; | ||
1556 | } u; | ||
1557 | }; | ||
1558 | |||
1559 | struct fw_hdr { | ||
1560 | u8 ver; | ||
1561 | u8 reserved1; | ||
1562 | __be16 len512; /* bin length in units of 512-bytes */ | ||
1563 | __be32 fw_ver; /* firmware version */ | ||
1564 | __be32 tp_microcode_ver; | ||
1565 | u8 intfver_nic; | ||
1566 | u8 intfver_vnic; | ||
1567 | u8 intfver_ofld; | ||
1568 | u8 intfver_ri; | ||
1569 | u8 intfver_iscsipdu; | ||
1570 | u8 intfver_iscsi; | ||
1571 | u8 intfver_fcoe; | ||
1572 | u8 reserved2; | ||
1573 | __be32 reserved3[27]; | ||
1574 | }; | ||
1575 | |||
1576 | #define FW_HDR_FW_VER_MAJOR_GET(x) (((x) >> 24) & 0xff) | ||
1577 | #define FW_HDR_FW_VER_MINOR_GET(x) (((x) >> 16) & 0xff) | ||
1578 | #define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff) | ||
1579 | #define FW_HDR_FW_VER_BUILD_GET(x) (((x) >> 0) & 0xff) | ||
1580 | #endif /* _T4FW_INTERFACE_H_ */ | ||
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 9902b33b7160..2f29c2131851 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h | |||
@@ -261,7 +261,6 @@ struct e1000_adapter { | |||
261 | /* TX */ | 261 | /* TX */ |
262 | struct e1000_tx_ring *tx_ring; /* One per active queue */ | 262 | struct e1000_tx_ring *tx_ring; /* One per active queue */ |
263 | unsigned int restart_queue; | 263 | unsigned int restart_queue; |
264 | unsigned long tx_queue_len; | ||
265 | u32 txd_cmd; | 264 | u32 txd_cmd; |
266 | u32 tx_int_delay; | 265 | u32 tx_int_delay; |
267 | u32 tx_abs_int_delay; | 266 | u32 tx_abs_int_delay; |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 41330349b07a..47da5fc1e9f4 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -383,8 +383,6 @@ static void e1000_configure(struct e1000_adapter *adapter) | |||
383 | adapter->alloc_rx_buf(adapter, ring, | 383 | adapter->alloc_rx_buf(adapter, ring, |
384 | E1000_DESC_UNUSED(ring)); | 384 | E1000_DESC_UNUSED(ring)); |
385 | } | 385 | } |
386 | |||
387 | adapter->tx_queue_len = netdev->tx_queue_len; | ||
388 | } | 386 | } |
389 | 387 | ||
390 | int e1000_up(struct e1000_adapter *adapter) | 388 | int e1000_up(struct e1000_adapter *adapter) |
@@ -503,7 +501,6 @@ void e1000_down(struct e1000_adapter *adapter) | |||
503 | del_timer_sync(&adapter->watchdog_timer); | 501 | del_timer_sync(&adapter->watchdog_timer); |
504 | del_timer_sync(&adapter->phy_info_timer); | 502 | del_timer_sync(&adapter->phy_info_timer); |
505 | 503 | ||
506 | netdev->tx_queue_len = adapter->tx_queue_len; | ||
507 | adapter->link_speed = 0; | 504 | adapter->link_speed = 0; |
508 | adapter->link_duplex = 0; | 505 | adapter->link_duplex = 0; |
509 | netif_carrier_off(netdev); | 506 | netif_carrier_off(netdev); |
@@ -2315,19 +2312,15 @@ static void e1000_watchdog(unsigned long data) | |||
2315 | E1000_CTRL_RFCE) ? "RX" : ((ctrl & | 2312 | E1000_CTRL_RFCE) ? "RX" : ((ctrl & |
2316 | E1000_CTRL_TFCE) ? "TX" : "None" ))); | 2313 | E1000_CTRL_TFCE) ? "TX" : "None" ))); |
2317 | 2314 | ||
2318 | /* tweak tx_queue_len according to speed/duplex | 2315 | /* adjust timeout factor according to speed/duplex */ |
2319 | * and adjust the timeout factor */ | ||
2320 | netdev->tx_queue_len = adapter->tx_queue_len; | ||
2321 | adapter->tx_timeout_factor = 1; | 2316 | adapter->tx_timeout_factor = 1; |
2322 | switch (adapter->link_speed) { | 2317 | switch (adapter->link_speed) { |
2323 | case SPEED_10: | 2318 | case SPEED_10: |
2324 | txb2b = false; | 2319 | txb2b = false; |
2325 | netdev->tx_queue_len = 10; | ||
2326 | adapter->tx_timeout_factor = 16; | 2320 | adapter->tx_timeout_factor = 16; |
2327 | break; | 2321 | break; |
2328 | case SPEED_100: | 2322 | case SPEED_100: |
2329 | txb2b = false; | 2323 | txb2b = false; |
2330 | netdev->tx_queue_len = 100; | ||
2331 | /* maybe add some timeout factor ? */ | 2324 | /* maybe add some timeout factor ? */ |
2332 | break; | 2325 | break; |
2333 | } | 2326 | } |
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 11e02e1f187c..12648a1cdb78 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
@@ -273,7 +273,6 @@ struct e1000_adapter { | |||
273 | 273 | ||
274 | struct napi_struct napi; | 274 | struct napi_struct napi; |
275 | 275 | ||
276 | unsigned long tx_queue_len; | ||
277 | unsigned int restart_queue; | 276 | unsigned int restart_queue; |
278 | u32 txd_cmd; | 277 | u32 txd_cmd; |
279 | 278 | ||
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 02f7d20f3c80..167b1aedfb42 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -2292,8 +2292,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) | |||
2292 | ew32(TCTL, tctl); | 2292 | ew32(TCTL, tctl); |
2293 | 2293 | ||
2294 | e1000e_config_collision_dist(hw); | 2294 | e1000e_config_collision_dist(hw); |
2295 | |||
2296 | adapter->tx_queue_len = adapter->netdev->tx_queue_len; | ||
2297 | } | 2295 | } |
2298 | 2296 | ||
2299 | /** | 2297 | /** |
@@ -2879,7 +2877,6 @@ void e1000e_down(struct e1000_adapter *adapter) | |||
2879 | del_timer_sync(&adapter->watchdog_timer); | 2877 | del_timer_sync(&adapter->watchdog_timer); |
2880 | del_timer_sync(&adapter->phy_info_timer); | 2878 | del_timer_sync(&adapter->phy_info_timer); |
2881 | 2879 | ||
2882 | netdev->tx_queue_len = adapter->tx_queue_len; | ||
2883 | netif_carrier_off(netdev); | 2880 | netif_carrier_off(netdev); |
2884 | adapter->link_speed = 0; | 2881 | adapter->link_speed = 0; |
2885 | adapter->link_duplex = 0; | 2882 | adapter->link_duplex = 0; |
@@ -3612,21 +3609,15 @@ static void e1000_watchdog_task(struct work_struct *work) | |||
3612 | "link gets many collisions.\n"); | 3609 | "link gets many collisions.\n"); |
3613 | } | 3610 | } |
3614 | 3611 | ||
3615 | /* | 3612 | /* adjust timeout factor according to speed/duplex */ |
3616 | * tweak tx_queue_len according to speed/duplex | ||
3617 | * and adjust the timeout factor | ||
3618 | */ | ||
3619 | netdev->tx_queue_len = adapter->tx_queue_len; | ||
3620 | adapter->tx_timeout_factor = 1; | 3613 | adapter->tx_timeout_factor = 1; |
3621 | switch (adapter->link_speed) { | 3614 | switch (adapter->link_speed) { |
3622 | case SPEED_10: | 3615 | case SPEED_10: |
3623 | txb2b = 0; | 3616 | txb2b = 0; |
3624 | netdev->tx_queue_len = 10; | ||
3625 | adapter->tx_timeout_factor = 16; | 3617 | adapter->tx_timeout_factor = 16; |
3626 | break; | 3618 | break; |
3627 | case SPEED_100: | 3619 | case SPEED_100: |
3628 | txb2b = 0; | 3620 | txb2b = 0; |
3629 | netdev->tx_queue_len = 100; | ||
3630 | adapter->tx_timeout_factor = 10; | 3621 | adapter->tx_timeout_factor = 10; |
3631 | break; | 3622 | break; |
3632 | } | 3623 | } |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index fdd26c2b1a2f..5175233f11f2 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -676,7 +676,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev) | |||
676 | priv->rx_queue[i] = NULL; | 676 | priv->rx_queue[i] = NULL; |
677 | 677 | ||
678 | for (i = 0; i < priv->num_tx_queues; i++) { | 678 | for (i = 0; i < priv->num_tx_queues; i++) { |
679 | priv->tx_queue[i] = (struct gfar_priv_tx_q *)kmalloc( | 679 | priv->tx_queue[i] = (struct gfar_priv_tx_q *)kzalloc( |
680 | sizeof (struct gfar_priv_tx_q), GFP_KERNEL); | 680 | sizeof (struct gfar_priv_tx_q), GFP_KERNEL); |
681 | if (!priv->tx_queue[i]) { | 681 | if (!priv->tx_queue[i]) { |
682 | err = -ENOMEM; | 682 | err = -ENOMEM; |
@@ -689,7 +689,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev) | |||
689 | } | 689 | } |
690 | 690 | ||
691 | for (i = 0; i < priv->num_rx_queues; i++) { | 691 | for (i = 0; i < priv->num_rx_queues; i++) { |
692 | priv->rx_queue[i] = (struct gfar_priv_rx_q *)kmalloc( | 692 | priv->rx_queue[i] = (struct gfar_priv_rx_q *)kzalloc( |
693 | sizeof (struct gfar_priv_rx_q), GFP_KERNEL); | 693 | sizeof (struct gfar_priv_rx_q), GFP_KERNEL); |
694 | if (!priv->rx_queue[i]) { | 694 | if (!priv->rx_queue[i]) { |
695 | err = -ENOMEM; | 695 | err = -ENOMEM; |
@@ -1120,10 +1120,10 @@ static int gfar_probe(struct of_device *ofdev, | |||
1120 | /* provided which set of benchmarks. */ | 1120 | /* provided which set of benchmarks. */ |
1121 | printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name); | 1121 | printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name); |
1122 | for (i = 0; i < priv->num_rx_queues; i++) | 1122 | for (i = 0; i < priv->num_rx_queues; i++) |
1123 | printk(KERN_INFO "%s: :RX BD ring size for Q[%d]: %d\n", | 1123 | printk(KERN_INFO "%s: RX BD ring size for Q[%d]: %d\n", |
1124 | dev->name, i, priv->rx_queue[i]->rx_ring_size); | 1124 | dev->name, i, priv->rx_queue[i]->rx_ring_size); |
1125 | for(i = 0; i < priv->num_tx_queues; i++) | 1125 | for(i = 0; i < priv->num_tx_queues; i++) |
1126 | printk(KERN_INFO "%s:TX BD ring size for Q[%d]: %d\n", | 1126 | printk(KERN_INFO "%s: TX BD ring size for Q[%d]: %d\n", |
1127 | dev->name, i, priv->tx_queue[i]->tx_ring_size); | 1127 | dev->name, i, priv->tx_queue[i]->tx_ring_size); |
1128 | 1128 | ||
1129 | return 0; | 1129 | return 0; |
@@ -1638,13 +1638,13 @@ static void free_skb_resources(struct gfar_private *priv) | |||
1638 | /* Go through all the buffer descriptors and free their data buffers */ | 1638 | /* Go through all the buffer descriptors and free their data buffers */ |
1639 | for (i = 0; i < priv->num_tx_queues; i++) { | 1639 | for (i = 0; i < priv->num_tx_queues; i++) { |
1640 | tx_queue = priv->tx_queue[i]; | 1640 | tx_queue = priv->tx_queue[i]; |
1641 | if(!tx_queue->tx_skbuff) | 1641 | if(tx_queue->tx_skbuff) |
1642 | free_skb_tx_queue(tx_queue); | 1642 | free_skb_tx_queue(tx_queue); |
1643 | } | 1643 | } |
1644 | 1644 | ||
1645 | for (i = 0; i < priv->num_rx_queues; i++) { | 1645 | for (i = 0; i < priv->num_rx_queues; i++) { |
1646 | rx_queue = priv->rx_queue[i]; | 1646 | rx_queue = priv->rx_queue[i]; |
1647 | if(!rx_queue->rx_skbuff) | 1647 | if(rx_queue->rx_skbuff) |
1648 | free_skb_rx_queue(rx_queue); | 1648 | free_skb_rx_queue(rx_queue); |
1649 | } | 1649 | } |
1650 | 1650 | ||
@@ -2393,6 +2393,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev) | |||
2393 | * as many bytes as needed to align the data properly | 2393 | * as many bytes as needed to align the data properly |
2394 | */ | 2394 | */ |
2395 | skb_reserve(skb, alignamount); | 2395 | skb_reserve(skb, alignamount); |
2396 | GFAR_CB(skb)->alignamount = alignamount; | ||
2396 | 2397 | ||
2397 | return skb; | 2398 | return skb; |
2398 | } | 2399 | } |
@@ -2533,13 +2534,13 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | |||
2533 | newskb = skb; | 2534 | newskb = skb; |
2534 | else if (skb) { | 2535 | else if (skb) { |
2535 | /* | 2536 | /* |
2536 | * We need to reset ->data to what it | 2537 | * We need to un-reserve() the skb to what it |
2537 | * was before gfar_new_skb() re-aligned | 2538 | * was before gfar_new_skb() re-aligned |
2538 | * it to an RXBUF_ALIGNMENT boundary | 2539 | * it to an RXBUF_ALIGNMENT boundary |
2539 | * before we put the skb back on the | 2540 | * before we put the skb back on the |
2540 | * recycle list. | 2541 | * recycle list. |
2541 | */ | 2542 | */ |
2542 | skb->data = skb->head + NET_SKB_PAD; | 2543 | skb_reserve(skb, -GFAR_CB(skb)->alignamount); |
2543 | __skb_queue_head(&priv->rx_recycle, skb); | 2544 | __skb_queue_head(&priv->rx_recycle, skb); |
2544 | } | 2545 | } |
2545 | } else { | 2546 | } else { |
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 3d72dc43dca5..17d25e714236 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
@@ -566,6 +566,12 @@ struct rxfcb { | |||
566 | u16 vlctl; /* VLAN control word */ | 566 | u16 vlctl; /* VLAN control word */ |
567 | }; | 567 | }; |
568 | 568 | ||
569 | struct gianfar_skb_cb { | ||
570 | int alignamount; | ||
571 | }; | ||
572 | |||
573 | #define GFAR_CB(skb) ((struct gianfar_skb_cb *)((skb)->cb)) | ||
574 | |||
569 | struct rmon_mib | 575 | struct rmon_mib |
570 | { | 576 | { |
571 | u32 tr64; /* 0x.680 - Transmit and Receive 64-byte Frame Counter */ | 577 | u32 tr64; /* 0x.680 - Transmit and Receive 64-byte Frame Counter */ |
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c index 2a8a886b37eb..be8d010e4021 100644 --- a/drivers/net/igb/e1000_mac.c +++ b/drivers/net/igb/e1000_mac.c | |||
@@ -1367,7 +1367,8 @@ out: | |||
1367 | * igb_enable_mng_pass_thru - Enable processing of ARP's | 1367 | * igb_enable_mng_pass_thru - Enable processing of ARP's |
1368 | * @hw: pointer to the HW structure | 1368 | * @hw: pointer to the HW structure |
1369 | * | 1369 | * |
1370 | * Verifies the hardware needs to allow ARPs to be processed by the host. | 1370 | * Verifies the hardware needs to leave interface enabled so that frames can |
1371 | * be directed to and from the management interface. | ||
1371 | **/ | 1372 | **/ |
1372 | bool igb_enable_mng_pass_thru(struct e1000_hw *hw) | 1373 | bool igb_enable_mng_pass_thru(struct e1000_hw *hw) |
1373 | { | 1374 | { |
@@ -1380,8 +1381,7 @@ bool igb_enable_mng_pass_thru(struct e1000_hw *hw) | |||
1380 | 1381 | ||
1381 | manc = rd32(E1000_MANC); | 1382 | manc = rd32(E1000_MANC); |
1382 | 1383 | ||
1383 | if (!(manc & E1000_MANC_RCV_TCO_EN) || | 1384 | if (!(manc & E1000_MANC_RCV_TCO_EN)) |
1384 | !(manc & E1000_MANC_EN_MAC_ADDR_FILTER)) | ||
1385 | goto out; | 1385 | goto out; |
1386 | 1386 | ||
1387 | if (hw->mac.arc_subsystem_valid) { | 1387 | if (hw->mac.arc_subsystem_valid) { |
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 4f69b6d951b3..7d288ccca1ca 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h | |||
@@ -268,7 +268,6 @@ struct igb_adapter { | |||
268 | 268 | ||
269 | /* TX */ | 269 | /* TX */ |
270 | struct igb_ring *tx_ring[16]; | 270 | struct igb_ring *tx_ring[16]; |
271 | unsigned long tx_queue_len; | ||
272 | u32 tx_timeout_count; | 271 | u32 tx_timeout_count; |
273 | 272 | ||
274 | /* RX */ | 273 | /* RX */ |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 78cc742e233f..2745e17fd021 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -1086,9 +1086,6 @@ static void igb_configure(struct igb_adapter *adapter) | |||
1086 | struct igb_ring *ring = adapter->rx_ring[i]; | 1086 | struct igb_ring *ring = adapter->rx_ring[i]; |
1087 | igb_alloc_rx_buffers_adv(ring, igb_desc_unused(ring)); | 1087 | igb_alloc_rx_buffers_adv(ring, igb_desc_unused(ring)); |
1088 | } | 1088 | } |
1089 | |||
1090 | |||
1091 | adapter->tx_queue_len = netdev->tx_queue_len; | ||
1092 | } | 1089 | } |
1093 | 1090 | ||
1094 | /** | 1091 | /** |
@@ -1194,7 +1191,6 @@ void igb_down(struct igb_adapter *adapter) | |||
1194 | del_timer_sync(&adapter->watchdog_timer); | 1191 | del_timer_sync(&adapter->watchdog_timer); |
1195 | del_timer_sync(&adapter->phy_info_timer); | 1192 | del_timer_sync(&adapter->phy_info_timer); |
1196 | 1193 | ||
1197 | netdev->tx_queue_len = adapter->tx_queue_len; | ||
1198 | netif_carrier_off(netdev); | 1194 | netif_carrier_off(netdev); |
1199 | 1195 | ||
1200 | /* record the stats before reset*/ | 1196 | /* record the stats before reset*/ |
@@ -3092,17 +3088,13 @@ static void igb_watchdog_task(struct work_struct *work) | |||
3092 | ((ctrl & E1000_CTRL_RFCE) ? "RX" : | 3088 | ((ctrl & E1000_CTRL_RFCE) ? "RX" : |
3093 | ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None"))); | 3089 | ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None"))); |
3094 | 3090 | ||
3095 | /* tweak tx_queue_len according to speed/duplex and | 3091 | /* adjust timeout factor according to speed/duplex */ |
3096 | * adjust the timeout factor */ | ||
3097 | netdev->tx_queue_len = adapter->tx_queue_len; | ||
3098 | adapter->tx_timeout_factor = 1; | 3092 | adapter->tx_timeout_factor = 1; |
3099 | switch (adapter->link_speed) { | 3093 | switch (adapter->link_speed) { |
3100 | case SPEED_10: | 3094 | case SPEED_10: |
3101 | netdev->tx_queue_len = 10; | ||
3102 | adapter->tx_timeout_factor = 14; | 3095 | adapter->tx_timeout_factor = 14; |
3103 | break; | 3096 | break; |
3104 | case SPEED_100: | 3097 | case SPEED_100: |
3105 | netdev->tx_queue_len = 100; | ||
3106 | /* maybe add some timeout factor ? */ | 3098 | /* maybe add some timeout factor ? */ |
3107 | break; | 3099 | break; |
3108 | } | 3100 | } |
@@ -3960,7 +3952,7 @@ void igb_update_stats(struct igb_adapter *adapter) | |||
3960 | struct net_device_stats *net_stats = igb_get_stats(adapter->netdev); | 3952 | struct net_device_stats *net_stats = igb_get_stats(adapter->netdev); |
3961 | struct e1000_hw *hw = &adapter->hw; | 3953 | struct e1000_hw *hw = &adapter->hw; |
3962 | struct pci_dev *pdev = adapter->pdev; | 3954 | struct pci_dev *pdev = adapter->pdev; |
3963 | u32 rnbc, reg; | 3955 | u32 reg, mpc; |
3964 | u16 phy_tmp; | 3956 | u16 phy_tmp; |
3965 | int i; | 3957 | int i; |
3966 | u64 bytes, packets; | 3958 | u64 bytes, packets; |
@@ -4018,7 +4010,9 @@ void igb_update_stats(struct igb_adapter *adapter) | |||
4018 | adapter->stats.symerrs += rd32(E1000_SYMERRS); | 4010 | adapter->stats.symerrs += rd32(E1000_SYMERRS); |
4019 | adapter->stats.sec += rd32(E1000_SEC); | 4011 | adapter->stats.sec += rd32(E1000_SEC); |
4020 | 4012 | ||
4021 | adapter->stats.mpc += rd32(E1000_MPC); | 4013 | mpc = rd32(E1000_MPC); |
4014 | adapter->stats.mpc += mpc; | ||
4015 | net_stats->rx_fifo_errors += mpc; | ||
4022 | adapter->stats.scc += rd32(E1000_SCC); | 4016 | adapter->stats.scc += rd32(E1000_SCC); |
4023 | adapter->stats.ecol += rd32(E1000_ECOL); | 4017 | adapter->stats.ecol += rd32(E1000_ECOL); |
4024 | adapter->stats.mcc += rd32(E1000_MCC); | 4018 | adapter->stats.mcc += rd32(E1000_MCC); |
@@ -4033,9 +4027,7 @@ void igb_update_stats(struct igb_adapter *adapter) | |||
4033 | adapter->stats.gptc += rd32(E1000_GPTC); | 4027 | adapter->stats.gptc += rd32(E1000_GPTC); |
4034 | adapter->stats.gotc += rd32(E1000_GOTCL); | 4028 | adapter->stats.gotc += rd32(E1000_GOTCL); |
4035 | rd32(E1000_GOTCH); /* clear GOTCL */ | 4029 | rd32(E1000_GOTCH); /* clear GOTCL */ |
4036 | rnbc = rd32(E1000_RNBC); | 4030 | adapter->stats.rnbc += rd32(E1000_RNBC); |
4037 | adapter->stats.rnbc += rnbc; | ||
4038 | net_stats->rx_fifo_errors += rnbc; | ||
4039 | adapter->stats.ruc += rd32(E1000_RUC); | 4031 | adapter->stats.ruc += rd32(E1000_RUC); |
4040 | adapter->stats.rfc += rd32(E1000_RFC); | 4032 | adapter->stats.rfc += rd32(E1000_RFC); |
4041 | adapter->stats.rjc += rd32(E1000_RJC); | 4033 | adapter->stats.rjc += rd32(E1000_RJC); |
@@ -5107,7 +5099,7 @@ static void igb_receive_skb(struct igb_q_vector *q_vector, | |||
5107 | { | 5099 | { |
5108 | struct igb_adapter *adapter = q_vector->adapter; | 5100 | struct igb_adapter *adapter = q_vector->adapter; |
5109 | 5101 | ||
5110 | if (vlan_tag) | 5102 | if (vlan_tag && adapter->vlgrp) |
5111 | vlan_gro_receive(&q_vector->napi, adapter->vlgrp, | 5103 | vlan_gro_receive(&q_vector->napi, adapter->vlgrp, |
5112 | vlan_tag, skb); | 5104 | vlan_tag, skb); |
5113 | else | 5105 | else |
diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h index a1774b29d222..debeee2dc717 100644 --- a/drivers/net/igbvf/igbvf.h +++ b/drivers/net/igbvf/igbvf.h | |||
@@ -198,7 +198,6 @@ struct igbvf_adapter { | |||
198 | struct igbvf_ring *tx_ring /* One per active queue */ | 198 | struct igbvf_ring *tx_ring /* One per active queue */ |
199 | ____cacheline_aligned_in_smp; | 199 | ____cacheline_aligned_in_smp; |
200 | 200 | ||
201 | unsigned long tx_queue_len; | ||
202 | unsigned int restart_queue; | 201 | unsigned int restart_queue; |
203 | u32 txd_cmd; | 202 | u32 txd_cmd; |
204 | 203 | ||
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index ea8abf5c1ef2..868855078ebc 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c | |||
@@ -1304,8 +1304,6 @@ static void igbvf_configure_tx(struct igbvf_adapter *adapter) | |||
1304 | 1304 | ||
1305 | /* enable Report Status bit */ | 1305 | /* enable Report Status bit */ |
1306 | adapter->txd_cmd |= E1000_ADVTXD_DCMD_RS; | 1306 | adapter->txd_cmd |= E1000_ADVTXD_DCMD_RS; |
1307 | |||
1308 | adapter->tx_queue_len = adapter->netdev->tx_queue_len; | ||
1309 | } | 1307 | } |
1310 | 1308 | ||
1311 | /** | 1309 | /** |
@@ -1524,7 +1522,6 @@ void igbvf_down(struct igbvf_adapter *adapter) | |||
1524 | 1522 | ||
1525 | del_timer_sync(&adapter->watchdog_timer); | 1523 | del_timer_sync(&adapter->watchdog_timer); |
1526 | 1524 | ||
1527 | netdev->tx_queue_len = adapter->tx_queue_len; | ||
1528 | netif_carrier_off(netdev); | 1525 | netif_carrier_off(netdev); |
1529 | 1526 | ||
1530 | /* record the stats before reset*/ | 1527 | /* record the stats before reset*/ |
@@ -1857,21 +1854,15 @@ static void igbvf_watchdog_task(struct work_struct *work) | |||
1857 | &adapter->link_duplex); | 1854 | &adapter->link_duplex); |
1858 | igbvf_print_link_info(adapter); | 1855 | igbvf_print_link_info(adapter); |
1859 | 1856 | ||
1860 | /* | 1857 | /* adjust timeout factor according to speed/duplex */ |
1861 | * tweak tx_queue_len according to speed/duplex | ||
1862 | * and adjust the timeout factor | ||
1863 | */ | ||
1864 | netdev->tx_queue_len = adapter->tx_queue_len; | ||
1865 | adapter->tx_timeout_factor = 1; | 1858 | adapter->tx_timeout_factor = 1; |
1866 | switch (adapter->link_speed) { | 1859 | switch (adapter->link_speed) { |
1867 | case SPEED_10: | 1860 | case SPEED_10: |
1868 | txb2b = 0; | 1861 | txb2b = 0; |
1869 | netdev->tx_queue_len = 10; | ||
1870 | adapter->tx_timeout_factor = 16; | 1862 | adapter->tx_timeout_factor = 16; |
1871 | break; | 1863 | break; |
1872 | case SPEED_100: | 1864 | case SPEED_100: |
1873 | txb2b = 0; | 1865 | txb2b = 0; |
1874 | netdev->tx_queue_len = 100; | ||
1875 | /* maybe add some timeout factor ? */ | 1866 | /* maybe add some timeout factor ? */ |
1876 | break; | 1867 | break; |
1877 | } | 1868 | } |
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 19e94ee155a2..79c35ae3718c 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
@@ -204,14 +204,17 @@ enum ixgbe_ring_f_enum { | |||
204 | #define IXGBE_MAX_FDIR_INDICES 64 | 204 | #define IXGBE_MAX_FDIR_INDICES 64 |
205 | #ifdef IXGBE_FCOE | 205 | #ifdef IXGBE_FCOE |
206 | #define IXGBE_MAX_FCOE_INDICES 8 | 206 | #define IXGBE_MAX_FCOE_INDICES 8 |
207 | #define MAX_RX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES) | ||
208 | #define MAX_TX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES) | ||
209 | #else | ||
210 | #define MAX_RX_QUEUES IXGBE_MAX_FDIR_INDICES | ||
211 | #define MAX_TX_QUEUES IXGBE_MAX_FDIR_INDICES | ||
207 | #endif /* IXGBE_FCOE */ | 212 | #endif /* IXGBE_FCOE */ |
208 | struct ixgbe_ring_feature { | 213 | struct ixgbe_ring_feature { |
209 | int indices; | 214 | int indices; |
210 | int mask; | 215 | int mask; |
211 | } ____cacheline_internodealigned_in_smp; | 216 | } ____cacheline_internodealigned_in_smp; |
212 | 217 | ||
213 | #define MAX_RX_QUEUES 128 | ||
214 | #define MAX_TX_QUEUES 128 | ||
215 | 218 | ||
216 | #define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \ | 219 | #define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \ |
217 | ? 8 : 1) | 220 | ? 8 : 1) |
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 7949a446e4c7..1959ef76c962 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c | |||
@@ -1853,6 +1853,26 @@ static void ixgbe_diag_test(struct net_device *netdev, | |||
1853 | if (ixgbe_link_test(adapter, &data[4])) | 1853 | if (ixgbe_link_test(adapter, &data[4])) |
1854 | eth_test->flags |= ETH_TEST_FL_FAILED; | 1854 | eth_test->flags |= ETH_TEST_FL_FAILED; |
1855 | 1855 | ||
1856 | if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { | ||
1857 | int i; | ||
1858 | for (i = 0; i < adapter->num_vfs; i++) { | ||
1859 | if (adapter->vfinfo[i].clear_to_send) { | ||
1860 | netdev_warn(netdev, "%s", | ||
1861 | "offline diagnostic is not " | ||
1862 | "supported when VFs are " | ||
1863 | "present\n"); | ||
1864 | data[0] = 1; | ||
1865 | data[1] = 1; | ||
1866 | data[2] = 1; | ||
1867 | data[3] = 1; | ||
1868 | eth_test->flags |= ETH_TEST_FL_FAILED; | ||
1869 | clear_bit(__IXGBE_TESTING, | ||
1870 | &adapter->state); | ||
1871 | goto skip_ol_tests; | ||
1872 | } | ||
1873 | } | ||
1874 | } | ||
1875 | |||
1856 | if (if_running) | 1876 | if (if_running) |
1857 | /* indicate we're in test mode */ | 1877 | /* indicate we're in test mode */ |
1858 | dev_close(netdev); | 1878 | dev_close(netdev); |
@@ -1908,6 +1928,7 @@ skip_loopback: | |||
1908 | 1928 | ||
1909 | clear_bit(__IXGBE_TESTING, &adapter->state); | 1929 | clear_bit(__IXGBE_TESTING, &adapter->state); |
1910 | } | 1930 | } |
1931 | skip_ol_tests: | ||
1911 | msleep_interruptible(4 * 1000); | 1932 | msleep_interruptible(4 * 1000); |
1912 | } | 1933 | } |
1913 | 1934 | ||
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 700cfc0aa1b9..9276d5965b0d 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c | |||
@@ -202,6 +202,15 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, | |||
202 | addr = sg_dma_address(sg); | 202 | addr = sg_dma_address(sg); |
203 | len = sg_dma_len(sg); | 203 | len = sg_dma_len(sg); |
204 | while (len) { | 204 | while (len) { |
205 | /* max number of buffers allowed in one DDP context */ | ||
206 | if (j >= IXGBE_BUFFCNT_MAX) { | ||
207 | netif_err(adapter, drv, adapter->netdev, | ||
208 | "xid=%x:%d,%d,%d:addr=%llx " | ||
209 | "not enough descriptors\n", | ||
210 | xid, i, j, dmacount, (u64)addr); | ||
211 | goto out_noddp_free; | ||
212 | } | ||
213 | |||
205 | /* get the offset of length of current buffer */ | 214 | /* get the offset of length of current buffer */ |
206 | thisoff = addr & ((dma_addr_t)bufflen - 1); | 215 | thisoff = addr & ((dma_addr_t)bufflen - 1); |
207 | thislen = min((bufflen - thisoff), len); | 216 | thislen = min((bufflen - thisoff), len); |
@@ -227,20 +236,13 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, | |||
227 | len -= thislen; | 236 | len -= thislen; |
228 | addr += thislen; | 237 | addr += thislen; |
229 | j++; | 238 | j++; |
230 | /* max number of buffers allowed in one DDP context */ | ||
231 | if (j > IXGBE_BUFFCNT_MAX) { | ||
232 | DPRINTK(DRV, ERR, "xid=%x:%d,%d,%d:addr=%llx " | ||
233 | "not enough descriptors\n", | ||
234 | xid, i, j, dmacount, (u64)addr); | ||
235 | goto out_noddp_free; | ||
236 | } | ||
237 | } | 239 | } |
238 | } | 240 | } |
239 | /* only the last buffer may have non-full bufflen */ | 241 | /* only the last buffer may have non-full bufflen */ |
240 | lastsize = thisoff + thislen; | 242 | lastsize = thisoff + thislen; |
241 | 243 | ||
242 | fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); | 244 | fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); |
243 | fcbuff |= (j << IXGBE_FCBUFF_BUFFCNT_SHIFT); | 245 | fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); |
244 | fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); | 246 | fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); |
245 | fcbuff |= (IXGBE_FCBUFF_VALID); | 247 | fcbuff |= (IXGBE_FCBUFF_VALID); |
246 | 248 | ||
@@ -520,6 +522,9 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) | |||
520 | /* Enable L2 eth type filter for FCoE */ | 522 | /* Enable L2 eth type filter for FCoE */ |
521 | IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE), | 523 | IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE), |
522 | (ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN)); | 524 | (ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN)); |
525 | /* Enable L2 eth type filter for FIP */ | ||
526 | IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FIP), | ||
527 | (ETH_P_FIP | IXGBE_ETQF_FILTER_EN)); | ||
523 | if (adapter->ring_feature[RING_F_FCOE].indices) { | 528 | if (adapter->ring_feature[RING_F_FCOE].indices) { |
524 | /* Use multiple rx queues for FCoE by redirection table */ | 529 | /* Use multiple rx queues for FCoE by redirection table */ |
525 | for (i = 0; i < IXGBE_FCRETA_SIZE; i++) { | 530 | for (i = 0; i < IXGBE_FCRETA_SIZE; i++) { |
@@ -530,6 +535,12 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) | |||
530 | } | 535 | } |
531 | IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA); | 536 | IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA); |
532 | IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0); | 537 | IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0); |
538 | fcoe_i = f->mask; | ||
539 | fcoe_i &= IXGBE_FCRETA_ENTRY_MASK; | ||
540 | fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx; | ||
541 | IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP), | ||
542 | IXGBE_ETQS_QUEUE_EN | | ||
543 | (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT)); | ||
533 | } else { | 544 | } else { |
534 | /* Use single rx queue for FCoE */ | 545 | /* Use single rx queue for FCoE */ |
535 | fcoe_i = f->mask; | 546 | fcoe_i = f->mask; |
@@ -539,6 +550,12 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) | |||
539 | IXGBE_ETQS_QUEUE_EN | | 550 | IXGBE_ETQS_QUEUE_EN | |
540 | (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT)); | 551 | (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT)); |
541 | } | 552 | } |
553 | /* send FIP frames to the first FCoE queue */ | ||
554 | fcoe_i = f->mask; | ||
555 | fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx; | ||
556 | IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP), | ||
557 | IXGBE_ETQS_QUEUE_EN | | ||
558 | (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT)); | ||
542 | 559 | ||
543 | IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL, | 560 | IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL, |
544 | IXGBE_FCRXCTRL_FCOELLI | | 561 | IXGBE_FCRXCTRL_FCOELLI | |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 6effa2ca157d..7216db218442 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -3036,6 +3036,14 @@ void ixgbe_reinit_locked(struct ixgbe_adapter *adapter) | |||
3036 | while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) | 3036 | while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) |
3037 | msleep(1); | 3037 | msleep(1); |
3038 | ixgbe_down(adapter); | 3038 | ixgbe_down(adapter); |
3039 | /* | ||
3040 | * If SR-IOV enabled then wait a bit before bringing the adapter | ||
3041 | * back up to give the VFs time to respond to the reset. The | ||
3042 | * two second wait is based upon the watchdog timer cycle in | ||
3043 | * the VF driver. | ||
3044 | */ | ||
3045 | if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) | ||
3046 | msleep(2000); | ||
3039 | ixgbe_up(adapter); | 3047 | ixgbe_up(adapter); |
3040 | clear_bit(__IXGBE_RESETTING, &adapter->state); | 3048 | clear_bit(__IXGBE_RESETTING, &adapter->state); |
3041 | } | 3049 | } |
@@ -3216,13 +3224,15 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
3216 | 3224 | ||
3217 | /* disable receive for all VFs and wait one second */ | 3225 | /* disable receive for all VFs and wait one second */ |
3218 | if (adapter->num_vfs) { | 3226 | if (adapter->num_vfs) { |
3219 | for (i = 0 ; i < adapter->num_vfs; i++) | ||
3220 | adapter->vfinfo[i].clear_to_send = 0; | ||
3221 | |||
3222 | /* ping all the active vfs to let them know we are going down */ | 3227 | /* ping all the active vfs to let them know we are going down */ |
3223 | ixgbe_ping_all_vfs(adapter); | 3228 | ixgbe_ping_all_vfs(adapter); |
3229 | |||
3224 | /* Disable all VFTE/VFRE TX/RX */ | 3230 | /* Disable all VFTE/VFRE TX/RX */ |
3225 | ixgbe_disable_tx_rx(adapter); | 3231 | ixgbe_disable_tx_rx(adapter); |
3232 | |||
3233 | /* Mark all the VFs as inactive */ | ||
3234 | for (i = 0 ; i < adapter->num_vfs; i++) | ||
3235 | adapter->vfinfo[i].clear_to_send = 0; | ||
3226 | } | 3236 | } |
3227 | 3237 | ||
3228 | /* disable receives */ | 3238 | /* disable receives */ |
@@ -5618,7 +5628,8 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) | |||
5618 | 5628 | ||
5619 | #ifdef IXGBE_FCOE | 5629 | #ifdef IXGBE_FCOE |
5620 | if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && | 5630 | if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && |
5621 | (skb->protocol == htons(ETH_P_FCOE))) { | 5631 | ((skb->protocol == htons(ETH_P_FCOE)) || |
5632 | (skb->protocol == htons(ETH_P_FIP)))) { | ||
5622 | txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1); | 5633 | txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1); |
5623 | txq += adapter->ring_feature[RING_F_FCOE].mask; | 5634 | txq += adapter->ring_feature[RING_F_FCOE].mask; |
5624 | return txq; | 5635 | return txq; |
@@ -5665,18 +5676,25 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, | |||
5665 | 5676 | ||
5666 | tx_ring = adapter->tx_ring[skb->queue_mapping]; | 5677 | tx_ring = adapter->tx_ring[skb->queue_mapping]; |
5667 | 5678 | ||
5668 | if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && | ||
5669 | (skb->protocol == htons(ETH_P_FCOE))) { | ||
5670 | tx_flags |= IXGBE_TX_FLAGS_FCOE; | ||
5671 | #ifdef IXGBE_FCOE | 5679 | #ifdef IXGBE_FCOE |
5680 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { | ||
5672 | #ifdef CONFIG_IXGBE_DCB | 5681 | #ifdef CONFIG_IXGBE_DCB |
5673 | tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK | 5682 | /* for FCoE with DCB, we force the priority to what |
5674 | << IXGBE_TX_FLAGS_VLAN_SHIFT); | 5683 | * was specified by the switch */ |
5675 | tx_flags |= ((adapter->fcoe.up << 13) | 5684 | if ((skb->protocol == htons(ETH_P_FCOE)) || |
5676 | << IXGBE_TX_FLAGS_VLAN_SHIFT); | 5685 | (skb->protocol == htons(ETH_P_FIP))) { |
5677 | #endif | 5686 | tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK |
5687 | << IXGBE_TX_FLAGS_VLAN_SHIFT); | ||
5688 | tx_flags |= ((adapter->fcoe.up << 13) | ||
5689 | << IXGBE_TX_FLAGS_VLAN_SHIFT); | ||
5690 | } | ||
5678 | #endif | 5691 | #endif |
5692 | /* flag for FCoE offloads */ | ||
5693 | if (skb->protocol == htons(ETH_P_FCOE)) | ||
5694 | tx_flags |= IXGBE_TX_FLAGS_FCOE; | ||
5679 | } | 5695 | } |
5696 | #endif | ||
5697 | |||
5680 | /* four things can cause us to need a context descriptor */ | 5698 | /* four things can cause us to need a context descriptor */ |
5681 | if (skb_is_gso(skb) || | 5699 | if (skb_is_gso(skb) || |
5682 | (skb->ip_summed == CHECKSUM_PARTIAL) || | 5700 | (skb->ip_summed == CHECKSUM_PARTIAL) || |
@@ -6031,7 +6049,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
6031 | indices += min_t(unsigned int, num_possible_cpus(), | 6049 | indices += min_t(unsigned int, num_possible_cpus(), |
6032 | IXGBE_MAX_FCOE_INDICES); | 6050 | IXGBE_MAX_FCOE_INDICES); |
6033 | #endif | 6051 | #endif |
6034 | indices = min_t(unsigned int, indices, MAX_TX_QUEUES); | ||
6035 | netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices); | 6052 | netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices); |
6036 | if (!netdev) { | 6053 | if (!netdev) { |
6037 | err = -ENOMEM; | 6054 | err = -ENOMEM; |
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index c574d0a68f2a..aed4ed665648 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h | |||
@@ -1298,6 +1298,7 @@ | |||
1298 | #define IXGBE_ETQF_FILTER_BCN 1 | 1298 | #define IXGBE_ETQF_FILTER_BCN 1 |
1299 | #define IXGBE_ETQF_FILTER_FCOE 2 | 1299 | #define IXGBE_ETQF_FILTER_FCOE 2 |
1300 | #define IXGBE_ETQF_FILTER_1588 3 | 1300 | #define IXGBE_ETQF_FILTER_1588 3 |
1301 | #define IXGBE_ETQF_FILTER_FIP 4 | ||
1301 | /* VLAN Control Bit Masks */ | 1302 | /* VLAN Control Bit Masks */ |
1302 | #define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */ | 1303 | #define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */ |
1303 | #define IXGBE_VLNCTRL_CFI 0x10000000 /* bit 28 */ | 1304 | #define IXGBE_VLNCTRL_CFI 0x10000000 /* bit 28 */ |
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 6ced5efc0e07..65cb133a6a1f 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c | |||
@@ -2921,9 +2921,10 @@ static int ixgbevf_tx_map(struct ixgbevf_adapter *adapter, | |||
2921 | struct ixgbevf_tx_buffer *tx_buffer_info; | 2921 | struct ixgbevf_tx_buffer *tx_buffer_info; |
2922 | unsigned int len; | 2922 | unsigned int len; |
2923 | unsigned int total = skb->len; | 2923 | unsigned int total = skb->len; |
2924 | unsigned int offset = 0, size, count = 0, i; | 2924 | unsigned int offset = 0, size, count = 0; |
2925 | unsigned int nr_frags = skb_shinfo(skb)->nr_frags; | 2925 | unsigned int nr_frags = skb_shinfo(skb)->nr_frags; |
2926 | unsigned int f; | 2926 | unsigned int f; |
2927 | int i; | ||
2927 | 2928 | ||
2928 | i = tx_ring->next_to_use; | 2929 | i = tx_ring->next_to_use; |
2929 | 2930 | ||
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index 348769521615..097796423b52 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c | |||
@@ -6318,7 +6318,7 @@ static int netdev_set_eeprom(struct net_device *dev, | |||
6318 | int len; | 6318 | int len; |
6319 | 6319 | ||
6320 | if (eeprom->magic != EEPROM_MAGIC) | 6320 | if (eeprom->magic != EEPROM_MAGIC) |
6321 | return 1; | 6321 | return -EINVAL; |
6322 | 6322 | ||
6323 | len = (eeprom->offset + eeprom->len + 1) / 2; | 6323 | len = (eeprom->offset + eeprom->len + 1) / 2; |
6324 | for (i = eeprom->offset / 2; i < len; i++) | 6324 | for (i = eeprom->offset / 2; i < len; i++) |
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 8f6e816a7395..b402a95c87c7 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c | |||
@@ -1023,6 +1023,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) | |||
1023 | info->port_attr.attr.mode = S_IRUGO | S_IWUSR; | 1023 | info->port_attr.attr.mode = S_IRUGO | S_IWUSR; |
1024 | info->port_attr.show = show_port_type; | 1024 | info->port_attr.show = show_port_type; |
1025 | info->port_attr.store = set_port_type; | 1025 | info->port_attr.store = set_port_type; |
1026 | sysfs_attr_init(&info->port_attr.attr); | ||
1026 | 1027 | ||
1027 | err = device_create_file(&dev->pdev->dev, &info->port_attr); | 1028 | err = device_create_file(&dev->pdev->dev, &info->port_attr); |
1028 | if (err) { | 1029 | if (err) { |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 33ae5e13b608..174ac8ef82fa 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -53,8 +53,8 @@ | |||
53 | 53 | ||
54 | #define _NETXEN_NIC_LINUX_MAJOR 4 | 54 | #define _NETXEN_NIC_LINUX_MAJOR 4 |
55 | #define _NETXEN_NIC_LINUX_MINOR 0 | 55 | #define _NETXEN_NIC_LINUX_MINOR 0 |
56 | #define _NETXEN_NIC_LINUX_SUBVERSION 72 | 56 | #define _NETXEN_NIC_LINUX_SUBVERSION 73 |
57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.72" | 57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.73" |
58 | 58 | ||
59 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) | 59 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) |
60 | #define _major(v) (((v) >> 24) & 0xff) | 60 | #define _major(v) (((v) >> 24) & 0xff) |
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 2a8ef5fc9663..f26e54716c88 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c | |||
@@ -669,13 +669,15 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | |||
669 | } | 669 | } |
670 | sds_ring->desc_head = (struct status_desc *)addr; | 670 | sds_ring->desc_head = (struct status_desc *)addr; |
671 | 671 | ||
672 | sds_ring->crb_sts_consumer = | 672 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { |
673 | netxen_get_ioaddr(adapter, | 673 | sds_ring->crb_sts_consumer = |
674 | recv_crb_registers[port].crb_sts_consumer[ring]); | 674 | netxen_get_ioaddr(adapter, |
675 | recv_crb_registers[port].crb_sts_consumer[ring]); | ||
675 | 676 | ||
676 | sds_ring->crb_intr_mask = | 677 | sds_ring->crb_intr_mask = |
677 | netxen_get_ioaddr(adapter, | 678 | netxen_get_ioaddr(adapter, |
678 | recv_crb_registers[port].sw_int_mask[ring]); | 679 | recv_crb_registers[port].sw_int_mask[ring]); |
680 | } | ||
679 | } | 681 | } |
680 | 682 | ||
681 | 683 | ||
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 439f3e859693..ecb6eed1d8e2 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -891,7 +891,7 @@ nx_get_bios_version(struct netxen_adapter *adapter) | |||
891 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) { | 891 | if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) { |
892 | bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) | 892 | bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) |
893 | + NX_UNI_BIOS_VERSION_OFF)); | 893 | + NX_UNI_BIOS_VERSION_OFF)); |
894 | return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) + | 894 | return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + |
895 | (bios_ver >> 24); | 895 | (bios_ver >> 24); |
896 | } else | 896 | } else |
897 | return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); | 897 | return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index f1daa9a8be07..9e82061c0235 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -604,16 +604,14 @@ netxen_cleanup_pci_map(struct netxen_adapter *adapter) | |||
604 | static int | 604 | static int |
605 | netxen_setup_pci_map(struct netxen_adapter *adapter) | 605 | netxen_setup_pci_map(struct netxen_adapter *adapter) |
606 | { | 606 | { |
607 | void __iomem *mem_ptr0 = NULL; | ||
608 | void __iomem *mem_ptr1 = NULL; | ||
609 | void __iomem *mem_ptr2 = NULL; | ||
610 | void __iomem *db_ptr = NULL; | 607 | void __iomem *db_ptr = NULL; |
611 | 608 | ||
612 | resource_size_t mem_base, db_base; | 609 | resource_size_t mem_base, db_base; |
613 | unsigned long mem_len, db_len = 0, pci_len0 = 0; | 610 | unsigned long mem_len, db_len = 0; |
614 | 611 | ||
615 | struct pci_dev *pdev = adapter->pdev; | 612 | struct pci_dev *pdev = adapter->pdev; |
616 | int pci_func = adapter->ahw.pci_func; | 613 | int pci_func = adapter->ahw.pci_func; |
614 | struct netxen_hardware_context *ahw = &adapter->ahw; | ||
617 | 615 | ||
618 | int err = 0; | 616 | int err = 0; |
619 | 617 | ||
@@ -630,24 +628,40 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) | |||
630 | 628 | ||
631 | /* 128 Meg of memory */ | 629 | /* 128 Meg of memory */ |
632 | if (mem_len == NETXEN_PCI_128MB_SIZE) { | 630 | if (mem_len == NETXEN_PCI_128MB_SIZE) { |
633 | mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); | 631 | |
634 | mem_ptr1 = ioremap(mem_base + SECOND_PAGE_GROUP_START, | 632 | ahw->pci_base0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); |
633 | ahw->pci_base1 = ioremap(mem_base + SECOND_PAGE_GROUP_START, | ||
635 | SECOND_PAGE_GROUP_SIZE); | 634 | SECOND_PAGE_GROUP_SIZE); |
636 | mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START, | 635 | ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START, |
637 | THIRD_PAGE_GROUP_SIZE); | 636 | THIRD_PAGE_GROUP_SIZE); |
638 | pci_len0 = FIRST_PAGE_GROUP_SIZE; | 637 | if (ahw->pci_base0 == NULL || ahw->pci_base1 == NULL || |
638 | ahw->pci_base2 == NULL) { | ||
639 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); | ||
640 | err = -EIO; | ||
641 | goto err_out; | ||
642 | } | ||
643 | |||
644 | ahw->pci_len0 = FIRST_PAGE_GROUP_SIZE; | ||
645 | |||
639 | } else if (mem_len == NETXEN_PCI_32MB_SIZE) { | 646 | } else if (mem_len == NETXEN_PCI_32MB_SIZE) { |
640 | mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE); | 647 | |
641 | mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START - | 648 | ahw->pci_base1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE); |
649 | ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START - | ||
642 | SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); | 650 | SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); |
651 | if (ahw->pci_base1 == NULL || ahw->pci_base2 == NULL) { | ||
652 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); | ||
653 | err = -EIO; | ||
654 | goto err_out; | ||
655 | } | ||
656 | |||
643 | } else if (mem_len == NETXEN_PCI_2MB_SIZE) { | 657 | } else if (mem_len == NETXEN_PCI_2MB_SIZE) { |
644 | 658 | ||
645 | mem_ptr0 = pci_ioremap_bar(pdev, 0); | 659 | ahw->pci_base0 = pci_ioremap_bar(pdev, 0); |
646 | if (mem_ptr0 == NULL) { | 660 | if (ahw->pci_base0 == NULL) { |
647 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); | 661 | dev_err(&pdev->dev, "failed to map PCI bar 0\n"); |
648 | return -EIO; | 662 | return -EIO; |
649 | } | 663 | } |
650 | pci_len0 = mem_len; | 664 | ahw->pci_len0 = mem_len; |
651 | } else { | 665 | } else { |
652 | return -EIO; | 666 | return -EIO; |
653 | } | 667 | } |
@@ -656,11 +670,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) | |||
656 | 670 | ||
657 | dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); | 671 | dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); |
658 | 672 | ||
659 | adapter->ahw.pci_base0 = mem_ptr0; | ||
660 | adapter->ahw.pci_len0 = pci_len0; | ||
661 | adapter->ahw.pci_base1 = mem_ptr1; | ||
662 | adapter->ahw.pci_base2 = mem_ptr2; | ||
663 | |||
664 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) { | 673 | if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) { |
665 | adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter, | 674 | adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter, |
666 | NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func))); | 675 | NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func))); |
@@ -1253,8 +1262,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1253 | int pci_func_id = PCI_FUNC(pdev->devfn); | 1262 | int pci_func_id = PCI_FUNC(pdev->devfn); |
1254 | uint8_t revision_id; | 1263 | uint8_t revision_id; |
1255 | 1264 | ||
1256 | if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) { | 1265 | if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) { |
1257 | pr_warning("%s: chip revisions between 0x%x-0x%x" | 1266 | pr_warning("%s: chip revisions between 0x%x-0x%x " |
1258 | "will not be enabled.\n", | 1267 | "will not be enabled.\n", |
1259 | module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1); | 1268 | module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1); |
1260 | return -ENODEV; | 1269 | return -ENODEV; |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 776cad2f5715..1028fcb91a28 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -1549,6 +1549,7 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1549 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101), | 1549 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101), |
1550 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab), | 1550 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab), |
1551 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), | 1551 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), |
1552 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e), | ||
1552 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), | 1553 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), |
1553 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), | 1554 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), |
1554 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), | 1555 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), |
@@ -1740,7 +1741,7 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1740 | PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"), | 1741 | PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"), |
1741 | PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"), | 1742 | PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"), |
1742 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"), | 1743 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"), |
1743 | PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"), | 1744 | PCMCIA_DEVICE_CIS_PROD_ID12("Allied Telesis,K.K", "Ethernet LAN Card", 0x2ad62f3c, 0x9fd2f0a2, "cis/LA-PCM.cis"), |
1744 | PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"), | 1745 | PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"), |
1745 | PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"), | 1746 | PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"), |
1746 | PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"), | 1747 | PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"), |
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index f45c626003a4..ad2267646187 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c | |||
@@ -493,13 +493,14 @@ static int pcmcia_get_versmac(struct pcmcia_device *p_dev, | |||
493 | { | 493 | { |
494 | struct net_device *dev = priv; | 494 | struct net_device *dev = priv; |
495 | cisparse_t parse; | 495 | cisparse_t parse; |
496 | u8 *buf; | ||
496 | 497 | ||
497 | if (pcmcia_parse_tuple(tuple, &parse)) | 498 | if (pcmcia_parse_tuple(tuple, &parse)) |
498 | return -EINVAL; | 499 | return -EINVAL; |
499 | 500 | ||
500 | if ((parse.version_1.ns > 3) && | 501 | buf = parse.version_1.str + parse.version_1.ofs[3]; |
501 | (cvt_ascii_address(dev, | 502 | |
502 | (parse.version_1.str + parse.version_1.ofs[3])))) | 503 | if ((parse.version_1.ns > 3) && (cvt_ascii_address(dev, buf) == 0)) |
503 | return 0; | 504 | return 0; |
504 | 505 | ||
505 | return -EINVAL; | 506 | return -EINVAL; |
@@ -528,7 +529,7 @@ static int mhz_setup(struct pcmcia_device *link) | |||
528 | len = pcmcia_get_tuple(link, 0x81, &buf); | 529 | len = pcmcia_get_tuple(link, 0x81, &buf); |
529 | if (buf && len >= 13) { | 530 | if (buf && len >= 13) { |
530 | buf[12] = '\0'; | 531 | buf[12] = '\0'; |
531 | if (cvt_ascii_address(dev, buf)) | 532 | if (cvt_ascii_address(dev, buf) == 0) |
532 | rc = 0; | 533 | rc = 0; |
533 | } | 534 | } |
534 | kfree(buf); | 535 | kfree(buf); |
@@ -910,7 +911,7 @@ static int smc91c92_config(struct pcmcia_device *link) | |||
910 | 911 | ||
911 | if (i != 0) { | 912 | if (i != 0) { |
912 | printk(KERN_NOTICE "smc91c92_cs: Unable to find hardware address.\n"); | 913 | printk(KERN_NOTICE "smc91c92_cs: Unable to find hardware address.\n"); |
913 | goto config_undo; | 914 | goto config_failed; |
914 | } | 915 | } |
915 | 916 | ||
916 | smc->duplex = 0; | 917 | smc->duplex = 0; |
@@ -998,6 +999,7 @@ config_undo: | |||
998 | unregister_netdev(dev); | 999 | unregister_netdev(dev); |
999 | config_failed: | 1000 | config_failed: |
1000 | smc91c92_release(link); | 1001 | smc91c92_release(link); |
1002 | free_netdev(dev); | ||
1001 | return -ENODEV; | 1003 | return -ENODEV; |
1002 | } /* smc91c92_config */ | 1004 | } /* smc91c92_config */ |
1003 | 1005 | ||
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 64cd250f642d..340da3915b96 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -187,8 +187,13 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { | |||
187 | 187 | ||
188 | MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); | 188 | MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); |
189 | 189 | ||
190 | static int rx_copybreak = 200; | 190 | /* |
191 | static int use_dac = -1; | 191 | * we set our copybreak very high so that we don't have |
192 | * to allocate 16k frames all the time (see note in | ||
193 | * rtl8169_open() | ||
194 | */ | ||
195 | static int rx_copybreak = 16383; | ||
196 | static int use_dac; | ||
192 | static struct { | 197 | static struct { |
193 | u32 msg_enable; | 198 | u32 msg_enable; |
194 | } debug = { -1 }; | 199 | } debug = { -1 }; |
@@ -513,8 +518,7 @@ MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); | |||
513 | module_param(rx_copybreak, int, 0); | 518 | module_param(rx_copybreak, int, 0); |
514 | MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); | 519 | MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); |
515 | module_param(use_dac, int, 0); | 520 | module_param(use_dac, int, 0); |
516 | MODULE_PARM_DESC(use_dac, "Enable PCI DAC. -1 defaults on for PCI Express only." | 521 | MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); |
517 | " Unsafe on 32 bit PCI slot."); | ||
518 | module_param_named(debug, debug.msg_enable, int, 0); | 522 | module_param_named(debug, debug.msg_enable, int, 0); |
519 | MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); | 523 | MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); |
520 | MODULE_LICENSE("GPL"); | 524 | MODULE_LICENSE("GPL"); |
@@ -2837,8 +2841,8 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) | |||
2837 | spin_lock_irq(&tp->lock); | 2841 | spin_lock_irq(&tp->lock); |
2838 | 2842 | ||
2839 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 2843 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
2840 | RTL_W32(MAC0, low); | ||
2841 | RTL_W32(MAC4, high); | 2844 | RTL_W32(MAC4, high); |
2845 | RTL_W32(MAC0, low); | ||
2842 | RTL_W8(Cfg9346, Cfg9346_Lock); | 2846 | RTL_W8(Cfg9346, Cfg9346_Lock); |
2843 | 2847 | ||
2844 | spin_unlock_irq(&tp->lock); | 2848 | spin_unlock_irq(&tp->lock); |
@@ -2990,7 +2994,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2990 | void __iomem *ioaddr; | 2994 | void __iomem *ioaddr; |
2991 | unsigned int i; | 2995 | unsigned int i; |
2992 | int rc; | 2996 | int rc; |
2993 | int this_use_dac = use_dac; | ||
2994 | 2997 | ||
2995 | if (netif_msg_drv(&debug)) { | 2998 | if (netif_msg_drv(&debug)) { |
2996 | printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", | 2999 | printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", |
@@ -3056,17 +3059,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3056 | 3059 | ||
3057 | tp->cp_cmd = PCIMulRW | RxChkSum; | 3060 | tp->cp_cmd = PCIMulRW | RxChkSum; |
3058 | 3061 | ||
3059 | tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); | ||
3060 | if (!tp->pcie_cap) | ||
3061 | netif_info(tp, probe, dev, "no PCI Express capability\n"); | ||
3062 | |||
3063 | if (this_use_dac < 0) | ||
3064 | this_use_dac = tp->pcie_cap != 0; | ||
3065 | |||
3066 | if ((sizeof(dma_addr_t) > 4) && | 3062 | if ((sizeof(dma_addr_t) > 4) && |
3067 | this_use_dac && | 3063 | !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) { |
3068 | !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { | ||
3069 | netif_info(tp, probe, dev, "using 64-bit DMA\n"); | ||
3070 | tp->cp_cmd |= PCIDAC; | 3064 | tp->cp_cmd |= PCIDAC; |
3071 | dev->features |= NETIF_F_HIGHDMA; | 3065 | dev->features |= NETIF_F_HIGHDMA; |
3072 | } else { | 3066 | } else { |
@@ -3085,6 +3079,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3085 | goto err_out_free_res_4; | 3079 | goto err_out_free_res_4; |
3086 | } | 3080 | } |
3087 | 3081 | ||
3082 | tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); | ||
3083 | if (!tp->pcie_cap) | ||
3084 | netif_info(tp, probe, dev, "no PCI Express capability\n"); | ||
3085 | |||
3088 | RTL_W16(IntrMask, 0x0000); | 3086 | RTL_W16(IntrMask, 0x0000); |
3089 | 3087 | ||
3090 | /* Soft reset the chip. */ | 3088 | /* Soft reset the chip. */ |
@@ -3254,9 +3252,13 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) | |||
3254 | } | 3252 | } |
3255 | 3253 | ||
3256 | static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, | 3254 | static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, |
3257 | struct net_device *dev) | 3255 | unsigned int mtu) |
3258 | { | 3256 | { |
3259 | unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; | 3257 | unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; |
3258 | |||
3259 | if (max_frame != 16383) | ||
3260 | printk(KERN_WARNING PFX "WARNING! Changing of MTU on this " | ||
3261 | "NIC may lead to frame reception errors!\n"); | ||
3260 | 3262 | ||
3261 | tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE; | 3263 | tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE; |
3262 | } | 3264 | } |
@@ -3269,7 +3271,17 @@ static int rtl8169_open(struct net_device *dev) | |||
3269 | 3271 | ||
3270 | pm_runtime_get_sync(&pdev->dev); | 3272 | pm_runtime_get_sync(&pdev->dev); |
3271 | 3273 | ||
3272 | rtl8169_set_rxbufsize(tp, dev); | 3274 | /* |
3275 | * Note that we use a magic value here, its wierd I know | ||
3276 | * its done because, some subset of rtl8169 hardware suffers from | ||
3277 | * a problem in which frames received that are longer than | ||
3278 | * the size set in RxMaxSize register return garbage sizes | ||
3279 | * when received. To avoid this we need to turn off filtering, | ||
3280 | * which is done by setting a value of 16383 in the RxMaxSize register | ||
3281 | * and allocating 16k frames to handle the largest possible rx value | ||
3282 | * thats what the magic math below does. | ||
3283 | */ | ||
3284 | rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN); | ||
3273 | 3285 | ||
3274 | /* | 3286 | /* |
3275 | * Rx and Tx desscriptors needs 256 bytes alignment. | 3287 | * Rx and Tx desscriptors needs 256 bytes alignment. |
@@ -3929,7 +3941,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) | |||
3929 | 3941 | ||
3930 | rtl8169_down(dev); | 3942 | rtl8169_down(dev); |
3931 | 3943 | ||
3932 | rtl8169_set_rxbufsize(tp, dev); | 3944 | rtl8169_set_rxbufsize(tp, dev->mtu); |
3933 | 3945 | ||
3934 | ret = rtl8169_init_ring(dev); | 3946 | ret = rtl8169_init_ring(dev); |
3935 | if (ret < 0) | 3947 | if (ret < 0) |
@@ -4808,8 +4820,8 @@ static void rtl_set_rx_mode(struct net_device *dev) | |||
4808 | mc_filter[1] = swab32(data); | 4820 | mc_filter[1] = swab32(data); |
4809 | } | 4821 | } |
4810 | 4822 | ||
4811 | RTL_W32(MAR0 + 0, mc_filter[0]); | ||
4812 | RTL_W32(MAR0 + 4, mc_filter[1]); | 4823 | RTL_W32(MAR0 + 4, mc_filter[1]); |
4824 | RTL_W32(MAR0 + 0, mc_filter[0]); | ||
4813 | 4825 | ||
4814 | RTL_W32(RxConfig, tmp); | 4826 | RTL_W32(RxConfig, tmp); |
4815 | 4827 | ||
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index ed999d31f1fa..37f6a00cde17 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c | |||
@@ -592,8 +592,10 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
592 | /* Setup... */ | 592 | /* Setup... */ |
593 | len = skb->len; | 593 | len = skb->len; |
594 | if (len < ETH_ZLEN) { | 594 | if (len < ETH_ZLEN) { |
595 | if (skb_padto(skb, ETH_ZLEN)) | 595 | if (skb_padto(skb, ETH_ZLEN)) { |
596 | spin_unlock_irqrestore(&sp->tx_lock, flags); | ||
596 | return NETDEV_TX_OK; | 597 | return NETDEV_TX_OK; |
598 | } | ||
597 | len = ETH_ZLEN; | 599 | len = ETH_ZLEN; |
598 | } | 600 | } |
599 | 601 | ||
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig index fb287649a305..eb63d44748a7 100644 --- a/drivers/net/stmmac/Kconfig +++ b/drivers/net/stmmac/Kconfig | |||
@@ -2,6 +2,7 @@ config STMMAC_ETH | |||
2 | tristate "STMicroelectronics 10/100/1000 Ethernet driver" | 2 | tristate "STMicroelectronics 10/100/1000 Ethernet driver" |
3 | select MII | 3 | select MII |
4 | select PHYLIB | 4 | select PHYLIB |
5 | select CRC32 | ||
5 | depends on NETDEVICES && CPU_SUBTYPE_ST40 | 6 | depends on NETDEVICES && CPU_SUBTYPE_ST40 |
6 | help | 7 | help |
7 | This is the driver for the Ethernet IPs are built around a | 8 | This is the driver for the Ethernet IPs are built around a |
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index b79d908fe34e..7063f56640c3 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c | |||
@@ -851,13 +851,15 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info | |||
851 | 851 | ||
852 | if ( !(rdes0 & 0x8000) || | 852 | if ( !(rdes0 & 0x8000) || |
853 | ((db->cr6_data & CR6_PM) && (rxlen>6)) ) { | 853 | ((db->cr6_data & CR6_PM) && (rxlen>6)) ) { |
854 | struct sk_buff *new_skb = NULL; | ||
855 | |||
854 | skb = rxptr->rx_skb_ptr; | 856 | skb = rxptr->rx_skb_ptr; |
855 | 857 | ||
856 | /* Good packet, send to upper layer */ | 858 | /* Good packet, send to upper layer */ |
857 | /* Shorst packet used new SKB */ | 859 | /* Shorst packet used new SKB */ |
858 | if ( (rxlen < RX_COPY_SIZE) && | 860 | if ((rxlen < RX_COPY_SIZE) && |
859 | ( (skb = dev_alloc_skb(rxlen + 2) ) | 861 | (((new_skb = dev_alloc_skb(rxlen + 2)) != NULL))) { |
860 | != NULL) ) { | 862 | skb = new_skb; |
861 | /* size less than COPY_SIZE, allocate a rxlen SKB */ | 863 | /* size less than COPY_SIZE, allocate a rxlen SKB */ |
862 | skb_reserve(skb, 2); /* 16byte align */ | 864 | skb_reserve(skb, 2); /* 16byte align */ |
863 | memcpy(skb_put(skb, rxlen), | 865 | memcpy(skb_put(skb, rxlen), |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 078903f10f02..616f8c92b745 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -812,7 +812,7 @@ static void set_mii_flow_control(struct velocity_info *vptr) | |||
812 | 812 | ||
813 | case FLOW_CNTL_TX_RX: | 813 | case FLOW_CNTL_TX_RX: |
814 | MII_REG_BITS_ON(ADVERTISE_PAUSE_CAP, MII_ADVERTISE, vptr->mac_regs); | 814 | MII_REG_BITS_ON(ADVERTISE_PAUSE_CAP, MII_ADVERTISE, vptr->mac_regs); |
815 | MII_REG_BITS_ON(ADVERTISE_PAUSE_ASYM, MII_ADVERTISE, vptr->mac_regs); | 815 | MII_REG_BITS_OFF(ADVERTISE_PAUSE_ASYM, MII_ADVERTISE, vptr->mac_regs); |
816 | break; | 816 | break; |
817 | 817 | ||
818 | case FLOW_CNTL_DISABLE: | 818 | case FLOW_CNTL_DISABLE: |
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index 4e30197afff6..6b1cb706e410 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c | |||
@@ -94,6 +94,8 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
94 | { USB_DEVICE(0x04bb, 0x093f) }, | 94 | { USB_DEVICE(0x04bb, 0x093f) }, |
95 | /* AVM FRITZ!WLAN USB Stick N */ | 95 | /* AVM FRITZ!WLAN USB Stick N */ |
96 | { USB_DEVICE(0x057C, 0x8401) }, | 96 | { USB_DEVICE(0x057C, 0x8401) }, |
97 | /* NEC WL300NU-G */ | ||
98 | { USB_DEVICE(0x0409, 0x0249) }, | ||
97 | /* AVM FRITZ!WLAN USB Stick N 2.4 */ | 99 | /* AVM FRITZ!WLAN USB Stick N 2.4 */ |
98 | { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY }, | 100 | { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY }, |
99 | 101 | ||
@@ -416,7 +418,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, | |||
416 | spin_unlock_irqrestore(&aru->common.cmdlock, flags); | 418 | spin_unlock_irqrestore(&aru->common.cmdlock, flags); |
417 | 419 | ||
418 | usb_fill_int_urb(urb, aru->udev, | 420 | usb_fill_int_urb(urb, aru->udev, |
419 | usb_sndbulkpipe(aru->udev, AR9170_EP_CMD), | 421 | usb_sndintpipe(aru->udev, AR9170_EP_CMD), |
420 | aru->common.cmdbuf, plen + 4, | 422 | aru->common.cmdbuf, plen + 4, |
421 | ar9170_usb_tx_urb_complete, NULL, 1); | 423 | ar9170_usb_tx_urb_complete, NULL, 1); |
422 | 424 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 3949133d9ee2..3297fc7b80bf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -2047,16 +2047,14 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2047 | tx_resp->failure_frame); | 2047 | tx_resp->failure_frame); |
2048 | 2048 | ||
2049 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 2049 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
2050 | if (qc && likely(sta_id != IWL_INVALID_STATION)) | 2050 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
2051 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | ||
2052 | 2051 | ||
2053 | if (priv->mac80211_registered && | 2052 | if (priv->mac80211_registered && |
2054 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) | 2053 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) |
2055 | iwl_wake_queue(priv, txq_id); | 2054 | iwl_wake_queue(priv, txq_id); |
2056 | } | 2055 | } |
2057 | 2056 | ||
2058 | if (qc && likely(sta_id != IWL_INVALID_STATION)) | 2057 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); |
2059 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | ||
2060 | 2058 | ||
2061 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 2059 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
2062 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); | 2060 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 0a376f720d78..f43a45d0f1dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1236,7 +1236,15 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1236 | /* Ack/clear/reset pending uCode interrupts. | 1236 | /* Ack/clear/reset pending uCode interrupts. |
1237 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, | 1237 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, |
1238 | */ | 1238 | */ |
1239 | iwl_write32(priv, CSR_INT, priv->_agn.inta); | 1239 | /* There is a hardware bug in the interrupt mask function that some |
1240 | * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if | ||
1241 | * they are disabled in the CSR_INT_MASK register. Furthermore the | ||
1242 | * ICT interrupt handling mechanism has another bug that might cause | ||
1243 | * these unmasked interrupts fail to be detected. We workaround the | ||
1244 | * hardware bugs here by ACKing all the possible interrupts so that | ||
1245 | * interrupt coalescing can still be achieved. | ||
1246 | */ | ||
1247 | iwl_write32(priv, CSR_INT, priv->_agn.inta | ~priv->inta_mask); | ||
1240 | 1248 | ||
1241 | inta = priv->_agn.inta; | 1249 | inta = priv->_agn.inta; |
1242 | 1250 | ||
@@ -2611,7 +2619,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv) | |||
2611 | BIT(NL80211_IFTYPE_STATION) | | 2619 | BIT(NL80211_IFTYPE_STATION) | |
2612 | BIT(NL80211_IFTYPE_ADHOC); | 2620 | BIT(NL80211_IFTYPE_ADHOC); |
2613 | 2621 | ||
2614 | hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY | | 2622 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | |
2615 | WIPHY_FLAG_DISABLE_BEACON_HINTS; | 2623 | WIPHY_FLAG_DISABLE_BEACON_HINTS; |
2616 | 2624 | ||
2617 | /* | 2625 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 4995134d7e4a..64f150b19771 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -1946,7 +1946,7 @@ static void iwl3945_init_hw_rates(struct iwl_priv *priv, | |||
1946 | { | 1946 | { |
1947 | int i; | 1947 | int i; |
1948 | 1948 | ||
1949 | for (i = 0; i < IWL_RATE_COUNT; i++) { | 1949 | for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { |
1950 | rates[i].bitrate = iwl3945_rates[i].ieee * 5; | 1950 | rates[i].bitrate = iwl3945_rates[i].ieee * 5; |
1951 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ | 1951 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ |
1952 | rates[i].hw_value_short = i; | 1952 | rates[i].hw_value_short = i; |
@@ -3950,7 +3950,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) | |||
3950 | BIT(NL80211_IFTYPE_STATION) | | 3950 | BIT(NL80211_IFTYPE_STATION) | |
3951 | BIT(NL80211_IFTYPE_ADHOC); | 3951 | BIT(NL80211_IFTYPE_ADHOC); |
3952 | 3952 | ||
3953 | hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY | | 3953 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | |
3954 | WIPHY_FLAG_DISABLE_BEACON_HINTS; | 3954 | WIPHY_FLAG_DISABLE_BEACON_HINTS; |
3955 | 3955 | ||
3956 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; | 3956 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 4396dccd12ac..82ebe1461a77 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -172,6 +172,8 @@ int lbs_cfg_register(struct lbs_private *priv) | |||
172 | if (ret < 0) | 172 | if (ret < 0) |
173 | lbs_pr_err("cannot register wiphy device\n"); | 173 | lbs_pr_err("cannot register wiphy device\n"); |
174 | 174 | ||
175 | priv->wiphy_registered = true; | ||
176 | |||
175 | ret = register_netdev(priv->dev); | 177 | ret = register_netdev(priv->dev); |
176 | if (ret) | 178 | if (ret) |
177 | lbs_pr_err("cannot register network device\n"); | 179 | lbs_pr_err("cannot register network device\n"); |
@@ -190,9 +192,11 @@ void lbs_cfg_free(struct lbs_private *priv) | |||
190 | if (!wdev) | 192 | if (!wdev) |
191 | return; | 193 | return; |
192 | 194 | ||
193 | if (wdev->wiphy) { | 195 | if (priv->wiphy_registered) |
194 | wiphy_unregister(wdev->wiphy); | 196 | wiphy_unregister(wdev->wiphy); |
197 | |||
198 | if (wdev->wiphy) | ||
195 | wiphy_free(wdev->wiphy); | 199 | wiphy_free(wdev->wiphy); |
196 | } | 200 | |
197 | kfree(wdev); | 201 | kfree(wdev); |
198 | } | 202 | } |
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 058d1720242e..a54880e4ad2b 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
@@ -36,6 +36,7 @@ struct lbs_private { | |||
36 | 36 | ||
37 | /* CFG80211 */ | 37 | /* CFG80211 */ |
38 | struct wireless_dev *wdev; | 38 | struct wireless_dev *wdev; |
39 | bool wiphy_registered; | ||
39 | 40 | ||
40 | /* Mesh */ | 41 | /* Mesh */ |
41 | struct net_device *mesh_dev; /* Virtual device */ | 42 | struct net_device *mesh_dev; /* Virtual device */ |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 6599fd15e675..1b5d0aebbb0e 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -3851,6 +3851,7 @@ MODULE_FIRMWARE("mwl8k/helper_8366.fw"); | |||
3851 | MODULE_FIRMWARE("mwl8k/fmimage_8366.fw"); | 3851 | MODULE_FIRMWARE("mwl8k/fmimage_8366.fw"); |
3852 | 3852 | ||
3853 | static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { | 3853 | static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { |
3854 | { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, }, | ||
3854 | { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, }, | 3855 | { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, }, |
3855 | { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, }, | 3856 | { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, }, |
3856 | { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, }, | 3857 | { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, }, |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index b3c4fbd80d8d..e3cfc001d2fd 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -35,6 +35,7 @@ MODULE_FIRMWARE("isl3887usb"); | |||
35 | static struct usb_device_id p54u_table[] __devinitdata = { | 35 | static struct usb_device_id p54u_table[] __devinitdata = { |
36 | /* Version 1 devices (pci chip + net2280) */ | 36 | /* Version 1 devices (pci chip + net2280) */ |
37 | {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ | 37 | {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ |
38 | {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ | ||
38 | {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ | 39 | {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ |
39 | {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */ | 40 | {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */ |
40 | {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */ | 41 | {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */ |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 9b04964deced..13444b6b3e37 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1643,6 +1643,11 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1643 | unsigned int i; | 1643 | unsigned int i; |
1644 | 1644 | ||
1645 | /* | 1645 | /* |
1646 | * Disable powersaving as default. | ||
1647 | */ | ||
1648 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1649 | |||
1650 | /* | ||
1646 | * Initialize all hw fields. | 1651 | * Initialize all hw fields. |
1647 | */ | 1652 | */ |
1648 | rt2x00dev->hw->flags = | 1653 | rt2x00dev->hw->flags = |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 18d4d8e4ae6b..326fce78489d 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -812,9 +812,9 @@ static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev, | |||
812 | rt2800_rfcsr_write(rt2x00dev, 24, | 812 | rt2800_rfcsr_write(rt2x00dev, 24, |
813 | rt2x00dev->calibration[conf_is_ht40(conf)]); | 813 | rt2x00dev->calibration[conf_is_ht40(conf)]); |
814 | 814 | ||
815 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); | 815 | rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr); |
816 | rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); | 816 | rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); |
817 | rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); | 817 | rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); |
818 | } | 818 | } |
819 | 819 | ||
820 | static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | 820 | static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, |
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 3d102dd87c9f..0b51857fbaf7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -48,6 +48,7 @@ obj-$(CONFIG_PPC) += setup-bus.o | |||
48 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o | 48 | obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o |
49 | obj-$(CONFIG_X86_VISWS) += setup-irq.o | 49 | obj-$(CONFIG_X86_VISWS) += setup-irq.o |
50 | obj-$(CONFIG_MN10300) += setup-bus.o | 50 | obj-$(CONFIG_MN10300) += setup-bus.o |
51 | obj-$(CONFIG_MICROBLAZE) += setup-bus.o | ||
51 | 52 | ||
52 | # | 53 | # |
53 | # ACPI Related PCI FW Functions | 54 | # ACPI Related PCI FW Functions |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index de296452c957..997668558e79 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -655,8 +655,8 @@ void pci_create_legacy_files(struct pci_bus *b) | |||
655 | goto legacy_io_err; | 655 | goto legacy_io_err; |
656 | 656 | ||
657 | /* Allocated above after the legacy_io struct */ | 657 | /* Allocated above after the legacy_io struct */ |
658 | sysfs_bin_attr_init(b->legacy_mem); | ||
659 | b->legacy_mem = b->legacy_io + 1; | 658 | b->legacy_mem = b->legacy_io + 1; |
659 | sysfs_bin_attr_init(b->legacy_mem); | ||
660 | b->legacy_mem->attr.name = "legacy_mem"; | 660 | b->legacy_mem->attr.name = "legacy_mem"; |
661 | b->legacy_mem->size = 1024*1024; | 661 | b->legacy_mem->size = 1024*1024; |
662 | b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; | 662 | b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; |
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index a04f21c8170f..f5da62653313 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c | |||
@@ -133,6 +133,7 @@ static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_de | |||
133 | sockets[i].socket.map_size = 0x1000; | 133 | sockets[i].socket.map_size = 0x1000; |
134 | sockets[i].socket.irq_mask = 0; | 134 | sockets[i].socket.irq_mask = 0; |
135 | sockets[i].socket.pci_irq = dev->irq; | 135 | sockets[i].socket.pci_irq = dev->irq; |
136 | sockets[i].socket.cb_dev = dev; | ||
136 | sockets[i].socket.owner = THIS_MODULE; | 137 | sockets[i].socket.owner = THIS_MODULE; |
137 | 138 | ||
138 | sockets[i].number = i; | 139 | sockets[i].number = i; |
diff --git a/drivers/pcmcia/i82365.h b/drivers/pcmcia/i82365.h index 849ef1b5d687..3f84d7a2dc84 100644 --- a/drivers/pcmcia/i82365.h +++ b/drivers/pcmcia/i82365.h | |||
@@ -95,6 +95,7 @@ | |||
95 | #define I365_CSC_DETECT 0x08 | 95 | #define I365_CSC_DETECT 0x08 |
96 | #define I365_CSC_ANY 0x0F | 96 | #define I365_CSC_ANY 0x0F |
97 | #define I365_CSC_GPI 0x10 | 97 | #define I365_CSC_GPI 0x10 |
98 | #define I365_CSC_IRQ_MASK 0xF0 | ||
98 | 99 | ||
99 | /* Flags for I365_ADDRWIN */ | 100 | /* Flags for I365_ADDRWIN */ |
100 | #define I365_ENA_IO(map) (0x40 << (map)) | 101 | #define I365_ENA_IO(map) (0x40 << (map)) |
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index b2df04199a21..c4612c52e4cb 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -256,6 +256,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, | |||
256 | { | 256 | { |
257 | struct pcmcia_socket *s; | 257 | struct pcmcia_socket *s; |
258 | config_t *c; | 258 | config_t *c; |
259 | int ret; | ||
259 | 260 | ||
260 | s = p_dev->socket; | 261 | s = p_dev->socket; |
261 | 262 | ||
@@ -264,13 +265,13 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, | |||
264 | 265 | ||
265 | if (!(s->state & SOCKET_PRESENT)) { | 266 | if (!(s->state & SOCKET_PRESENT)) { |
266 | dev_dbg(&s->dev, "No card present\n"); | 267 | dev_dbg(&s->dev, "No card present\n"); |
267 | mutex_unlock(&s->ops_mutex); | 268 | ret = -ENODEV; |
268 | return -ENODEV; | 269 | goto unlock; |
269 | } | 270 | } |
270 | if (!(c->state & CONFIG_LOCKED)) { | 271 | if (!(c->state & CONFIG_LOCKED)) { |
271 | dev_dbg(&s->dev, "Configuration isnt't locked\n"); | 272 | dev_dbg(&s->dev, "Configuration isnt't locked\n"); |
272 | mutex_unlock(&s->ops_mutex); | 273 | ret = -EACCES; |
273 | return -EACCES; | 274 | goto unlock; |
274 | } | 275 | } |
275 | 276 | ||
276 | if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { | 277 | if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { |
@@ -286,7 +287,8 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, | |||
286 | 287 | ||
287 | if (mod->Attributes & CONF_VCC_CHANGE_VALID) { | 288 | if (mod->Attributes & CONF_VCC_CHANGE_VALID) { |
288 | dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); | 289 | dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); |
289 | return -EINVAL; | 290 | ret = -EINVAL; |
291 | goto unlock; | ||
290 | } | 292 | } |
291 | 293 | ||
292 | /* We only allow changing Vpp1 and Vpp2 to the same value */ | 294 | /* We only allow changing Vpp1 and Vpp2 to the same value */ |
@@ -294,21 +296,21 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, | |||
294 | (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { | 296 | (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { |
295 | if (mod->Vpp1 != mod->Vpp2) { | 297 | if (mod->Vpp1 != mod->Vpp2) { |
296 | dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n"); | 298 | dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n"); |
297 | mutex_unlock(&s->ops_mutex); | 299 | ret = -EINVAL; |
298 | return -EINVAL; | 300 | goto unlock; |
299 | } | 301 | } |
300 | s->socket.Vpp = mod->Vpp1; | 302 | s->socket.Vpp = mod->Vpp1; |
301 | if (s->ops->set_socket(s, &s->socket)) { | 303 | if (s->ops->set_socket(s, &s->socket)) { |
302 | mutex_unlock(&s->ops_mutex); | ||
303 | dev_printk(KERN_WARNING, &s->dev, | 304 | dev_printk(KERN_WARNING, &s->dev, |
304 | "Unable to set VPP\n"); | 305 | "Unable to set VPP\n"); |
305 | return -EIO; | 306 | ret = -EIO; |
307 | goto unlock; | ||
306 | } | 308 | } |
307 | } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || | 309 | } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || |
308 | (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { | 310 | (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { |
309 | dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); | 311 | dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); |
310 | mutex_unlock(&s->ops_mutex); | 312 | ret = -EINVAL; |
311 | return -EINVAL; | 313 | goto unlock; |
312 | } | 314 | } |
313 | 315 | ||
314 | if (mod->Attributes & CONF_IO_CHANGE_WIDTH) { | 316 | if (mod->Attributes & CONF_IO_CHANGE_WIDTH) { |
@@ -332,9 +334,11 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, | |||
332 | s->ops->set_io_map(s, &io_on); | 334 | s->ops->set_io_map(s, &io_on); |
333 | } | 335 | } |
334 | } | 336 | } |
337 | ret = 0; | ||
338 | unlock: | ||
335 | mutex_unlock(&s->ops_mutex); | 339 | mutex_unlock(&s->ops_mutex); |
336 | 340 | ||
337 | return 0; | 341 | return ret; |
338 | } /* modify_configuration */ | 342 | } /* modify_configuration */ |
339 | EXPORT_SYMBOL(pcmcia_modify_configuration); | 343 | EXPORT_SYMBOL(pcmcia_modify_configuration); |
340 | 344 | ||
@@ -752,14 +756,6 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) | |||
752 | 756 | ||
753 | #ifdef CONFIG_PCMCIA_PROBE | 757 | #ifdef CONFIG_PCMCIA_PROBE |
754 | 758 | ||
755 | #ifdef IRQ_NOAUTOEN | ||
756 | /* if the underlying IRQ infrastructure allows for it, only allocate | ||
757 | * the IRQ, but do not enable it | ||
758 | */ | ||
759 | if (!(req->Handler)) | ||
760 | type |= IRQ_NOAUTOEN; | ||
761 | #endif /* IRQ_NOAUTOEN */ | ||
762 | |||
763 | if (s->irq.AssignedIRQ != 0) { | 759 | if (s->irq.AssignedIRQ != 0) { |
764 | /* If the interrupt is already assigned, it must be the same */ | 760 | /* If the interrupt is already assigned, it must be the same */ |
765 | irq = s->irq.AssignedIRQ; | 761 | irq = s->irq.AssignedIRQ; |
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 7c204910a777..7ba57a565cd7 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c | |||
@@ -671,6 +671,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, | |||
671 | socket[i].socket.map_size = 0x1000; | 671 | socket[i].socket.map_size = 0x1000; |
672 | socket[i].socket.irq_mask = mask; | 672 | socket[i].socket.irq_mask = mask; |
673 | socket[i].socket.pci_irq = dev->irq; | 673 | socket[i].socket.pci_irq = dev->irq; |
674 | socket[i].socket.cb_dev = dev; | ||
674 | socket[i].socket.owner = THIS_MODULE; | 675 | socket[i].socket.owner = THIS_MODULE; |
675 | 676 | ||
676 | socket[i].number = i; | 677 | socket[i].number = i; |
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index aaa70227bfb0..9ffa97d0b16c 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h | |||
@@ -296,7 +296,7 @@ static int ti_init(struct yenta_socket *socket) | |||
296 | u8 new, reg = exca_readb(socket, I365_INTCTL); | 296 | u8 new, reg = exca_readb(socket, I365_INTCTL); |
297 | 297 | ||
298 | new = reg & ~I365_INTR_ENA; | 298 | new = reg & ~I365_INTR_ENA; |
299 | if (socket->cb_irq) | 299 | if (socket->dev->irq) |
300 | new |= I365_INTR_ENA; | 300 | new |= I365_INTR_ENA; |
301 | if (new != reg) | 301 | if (new != reg) |
302 | exca_writeb(socket, I365_INTCTL, new); | 302 | exca_writeb(socket, I365_INTCTL, new); |
@@ -316,14 +316,47 @@ static int ti_override(struct yenta_socket *socket) | |||
316 | return 0; | 316 | return 0; |
317 | } | 317 | } |
318 | 318 | ||
319 | static void ti113x_use_isa_irq(struct yenta_socket *socket) | ||
320 | { | ||
321 | int isa_irq = -1; | ||
322 | u8 intctl; | ||
323 | u32 isa_irq_mask = 0; | ||
324 | |||
325 | if (!isa_probe) | ||
326 | return; | ||
327 | |||
328 | /* get a free isa int */ | ||
329 | isa_irq_mask = yenta_probe_irq(socket, isa_interrupts); | ||
330 | if (!isa_irq_mask) | ||
331 | return; /* no useable isa irq found */ | ||
332 | |||
333 | /* choose highest available */ | ||
334 | for (; isa_irq_mask; isa_irq++) | ||
335 | isa_irq_mask >>= 1; | ||
336 | socket->cb_irq = isa_irq; | ||
337 | |||
338 | exca_writeb(socket, I365_CSCINT, (isa_irq << 4)); | ||
339 | |||
340 | intctl = exca_readb(socket, I365_INTCTL); | ||
341 | intctl &= ~(I365_INTR_ENA | I365_IRQ_MASK); /* CSC Enable */ | ||
342 | exca_writeb(socket, I365_INTCTL, intctl); | ||
343 | |||
344 | dev_info(&socket->dev->dev, | ||
345 | "Yenta TI113x: using isa irq %d for CardBus\n", isa_irq); | ||
346 | } | ||
347 | |||
348 | |||
319 | static int ti113x_override(struct yenta_socket *socket) | 349 | static int ti113x_override(struct yenta_socket *socket) |
320 | { | 350 | { |
321 | u8 cardctl; | 351 | u8 cardctl; |
322 | 352 | ||
323 | cardctl = config_readb(socket, TI113X_CARD_CONTROL); | 353 | cardctl = config_readb(socket, TI113X_CARD_CONTROL); |
324 | cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); | 354 | cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); |
325 | if (socket->cb_irq) | 355 | if (socket->dev->irq) |
326 | cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ; | 356 | cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ; |
357 | else | ||
358 | ti113x_use_isa_irq(socket); | ||
359 | |||
327 | config_writeb(socket, TI113X_CARD_CONTROL, cardctl); | 360 | config_writeb(socket, TI113X_CARD_CONTROL, cardctl); |
328 | 361 | ||
329 | return ti_override(socket); | 362 | return ti_override(socket); |
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index c9fcbdc164ea..aaccdb9f4ba1 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c | |||
@@ -105,6 +105,7 @@ typedef struct vrc4171_socket { | |||
105 | char name[24]; | 105 | char name[24]; |
106 | int csc_irq; | 106 | int csc_irq; |
107 | int io_irq; | 107 | int io_irq; |
108 | spinlock_t lock; | ||
108 | } vrc4171_socket_t; | 109 | } vrc4171_socket_t; |
109 | 110 | ||
110 | static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS]; | 111 | static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS]; |
@@ -327,7 +328,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | |||
327 | slot = sock->sock; | 328 | slot = sock->sock; |
328 | socket = &vrc4171_sockets[slot]; | 329 | socket = &vrc4171_sockets[slot]; |
329 | 330 | ||
330 | spin_lock_irq(&sock->lock); | 331 | spin_lock_irq(&socket->lock); |
331 | 332 | ||
332 | voltage = set_Vcc_value(state->Vcc); | 333 | voltage = set_Vcc_value(state->Vcc); |
333 | exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage); | 334 | exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage); |
@@ -370,7 +371,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | |||
370 | cscint |= I365_CSC_DETECT; | 371 | cscint |= I365_CSC_DETECT; |
371 | exca_write_byte(slot, I365_CSCINT, cscint); | 372 | exca_write_byte(slot, I365_CSCINT, cscint); |
372 | 373 | ||
373 | spin_unlock_irq(&sock->lock); | 374 | spin_unlock_irq(&socket->lock); |
374 | 375 | ||
375 | return 0; | 376 | return 0; |
376 | } | 377 | } |
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 967c766f53ba..418988ab6edf 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -42,6 +42,18 @@ module_param_string(o2_speedup, o2_speedup, sizeof(o2_speedup), 0444); | |||
42 | MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' " | 42 | MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' " |
43 | "or 'default' (uses recommended behaviour for the detected bridge)"); | 43 | "or 'default' (uses recommended behaviour for the detected bridge)"); |
44 | 44 | ||
45 | /* | ||
46 | * Only probe "regular" interrupts, don't | ||
47 | * touch dangerous spots like the mouse irq, | ||
48 | * because there are mice that apparently | ||
49 | * get really confused if they get fondled | ||
50 | * too intimately. | ||
51 | * | ||
52 | * Default to 11, 10, 9, 7, 6, 5, 4, 3. | ||
53 | */ | ||
54 | static u32 isa_interrupts = 0x0ef8; | ||
55 | |||
56 | |||
45 | #define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args) | 57 | #define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args) |
46 | 58 | ||
47 | /* Don't ask.. */ | 59 | /* Don't ask.. */ |
@@ -54,6 +66,8 @@ MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' " | |||
54 | */ | 66 | */ |
55 | #ifdef CONFIG_YENTA_TI | 67 | #ifdef CONFIG_YENTA_TI |
56 | static int yenta_probe_cb_irq(struct yenta_socket *socket); | 68 | static int yenta_probe_cb_irq(struct yenta_socket *socket); |
69 | static unsigned int yenta_probe_irq(struct yenta_socket *socket, | ||
70 | u32 isa_irq_mask); | ||
57 | #endif | 71 | #endif |
58 | 72 | ||
59 | 73 | ||
@@ -329,8 +343,8 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | |||
329 | /* ISA interrupt control? */ | 343 | /* ISA interrupt control? */ |
330 | intr = exca_readb(socket, I365_INTCTL); | 344 | intr = exca_readb(socket, I365_INTCTL); |
331 | intr = (intr & ~0xf); | 345 | intr = (intr & ~0xf); |
332 | if (!socket->cb_irq) { | 346 | if (!socket->dev->irq) { |
333 | intr |= state->io_irq; | 347 | intr |= socket->cb_irq ? socket->cb_irq : state->io_irq; |
334 | bridge |= CB_BRIDGE_INTR; | 348 | bridge |= CB_BRIDGE_INTR; |
335 | } | 349 | } |
336 | exca_writeb(socket, I365_INTCTL, intr); | 350 | exca_writeb(socket, I365_INTCTL, intr); |
@@ -340,7 +354,7 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | |||
340 | reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA); | 354 | reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA); |
341 | reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET; | 355 | reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET; |
342 | reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0; | 356 | reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0; |
343 | if (state->io_irq != socket->cb_irq) { | 357 | if (state->io_irq != socket->dev->irq) { |
344 | reg |= state->io_irq; | 358 | reg |= state->io_irq; |
345 | bridge |= CB_BRIDGE_INTR; | 359 | bridge |= CB_BRIDGE_INTR; |
346 | } | 360 | } |
@@ -356,7 +370,9 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | |||
356 | exca_writeb(socket, I365_POWER, reg); | 370 | exca_writeb(socket, I365_POWER, reg); |
357 | 371 | ||
358 | /* CSC interrupt: no ISA irq for CSC */ | 372 | /* CSC interrupt: no ISA irq for CSC */ |
359 | reg = I365_CSC_DETECT; | 373 | reg = exca_readb(socket, I365_CSCINT); |
374 | reg &= I365_CSC_IRQ_MASK; | ||
375 | reg |= I365_CSC_DETECT; | ||
360 | if (state->flags & SS_IOCARD) { | 376 | if (state->flags & SS_IOCARD) { |
361 | if (state->csc_mask & SS_STSCHG) | 377 | if (state->csc_mask & SS_STSCHG) |
362 | reg |= I365_CSC_STSCHG; | 378 | reg |= I365_CSC_STSCHG; |
@@ -896,22 +912,12 @@ static struct cardbus_type cardbus_type[] = { | |||
896 | }; | 912 | }; |
897 | 913 | ||
898 | 914 | ||
899 | /* | ||
900 | * Only probe "regular" interrupts, don't | ||
901 | * touch dangerous spots like the mouse irq, | ||
902 | * because there are mice that apparently | ||
903 | * get really confused if they get fondled | ||
904 | * too intimately. | ||
905 | * | ||
906 | * Default to 11, 10, 9, 7, 6, 5, 4, 3. | ||
907 | */ | ||
908 | static u32 isa_interrupts = 0x0ef8; | ||
909 | |||
910 | static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask) | 915 | static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask) |
911 | { | 916 | { |
912 | int i; | 917 | int i; |
913 | unsigned long val; | 918 | unsigned long val; |
914 | u32 mask; | 919 | u32 mask; |
920 | u8 reg; | ||
915 | 921 | ||
916 | /* | 922 | /* |
917 | * Probe for usable interrupts using the force | 923 | * Probe for usable interrupts using the force |
@@ -919,6 +925,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas | |||
919 | */ | 925 | */ |
920 | cb_writel(socket, CB_SOCKET_EVENT, -1); | 926 | cb_writel(socket, CB_SOCKET_EVENT, -1); |
921 | cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); | 927 | cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); |
928 | reg = exca_readb(socket, I365_CSCINT); | ||
922 | exca_writeb(socket, I365_CSCINT, 0); | 929 | exca_writeb(socket, I365_CSCINT, 0); |
923 | val = probe_irq_on() & isa_irq_mask; | 930 | val = probe_irq_on() & isa_irq_mask; |
924 | for (i = 1; i < 16; i++) { | 931 | for (i = 1; i < 16; i++) { |
@@ -930,7 +937,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas | |||
930 | cb_writel(socket, CB_SOCKET_EVENT, -1); | 937 | cb_writel(socket, CB_SOCKET_EVENT, -1); |
931 | } | 938 | } |
932 | cb_writel(socket, CB_SOCKET_MASK, 0); | 939 | cb_writel(socket, CB_SOCKET_MASK, 0); |
933 | exca_writeb(socket, I365_CSCINT, 0); | 940 | exca_writeb(socket, I365_CSCINT, reg); |
934 | 941 | ||
935 | mask = probe_irq_mask(val) & 0xffff; | 942 | mask = probe_irq_mask(val) & 0xffff; |
936 | 943 | ||
@@ -967,6 +974,8 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id) | |||
967 | /* probes the PCI interrupt, use only on override functions */ | 974 | /* probes the PCI interrupt, use only on override functions */ |
968 | static int yenta_probe_cb_irq(struct yenta_socket *socket) | 975 | static int yenta_probe_cb_irq(struct yenta_socket *socket) |
969 | { | 976 | { |
977 | u8 reg; | ||
978 | |||
970 | if (!socket->cb_irq) | 979 | if (!socket->cb_irq) |
971 | return -1; | 980 | return -1; |
972 | 981 | ||
@@ -979,7 +988,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) | |||
979 | } | 988 | } |
980 | 989 | ||
981 | /* generate interrupt, wait */ | 990 | /* generate interrupt, wait */ |
982 | exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG); | 991 | reg = exca_readb(socket, I365_CSCINT); |
992 | exca_writeb(socket, I365_CSCINT, reg | I365_CSC_STSCHG); | ||
983 | cb_writel(socket, CB_SOCKET_EVENT, -1); | 993 | cb_writel(socket, CB_SOCKET_EVENT, -1); |
984 | cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); | 994 | cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); |
985 | cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); | 995 | cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); |
@@ -988,7 +998,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) | |||
988 | 998 | ||
989 | /* disable interrupts */ | 999 | /* disable interrupts */ |
990 | cb_writel(socket, CB_SOCKET_MASK, 0); | 1000 | cb_writel(socket, CB_SOCKET_MASK, 0); |
991 | exca_writeb(socket, I365_CSCINT, 0); | 1001 | exca_writeb(socket, I365_CSCINT, reg); |
992 | cb_writel(socket, CB_SOCKET_EVENT, -1); | 1002 | cb_writel(socket, CB_SOCKET_EVENT, -1); |
993 | exca_readb(socket, I365_CSC); | 1003 | exca_readb(socket, I365_CSC); |
994 | 1004 | ||
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 226b3e93498c..cbca40aa4006 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -922,9 +922,13 @@ static struct backlight_ops acer_bl_ops = { | |||
922 | 922 | ||
923 | static int __devinit acer_backlight_init(struct device *dev) | 923 | static int __devinit acer_backlight_init(struct device *dev) |
924 | { | 924 | { |
925 | struct backlight_properties props; | ||
925 | struct backlight_device *bd; | 926 | struct backlight_device *bd; |
926 | 927 | ||
927 | bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops); | 928 | memset(&props, 0, sizeof(struct backlight_properties)); |
929 | props.max_brightness = max_brightness; | ||
930 | bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops, | ||
931 | &props); | ||
928 | if (IS_ERR(bd)) { | 932 | if (IS_ERR(bd)) { |
929 | printk(ACER_ERR "Could not register Acer backlight device\n"); | 933 | printk(ACER_ERR "Could not register Acer backlight device\n"); |
930 | acer_backlight_device = NULL; | 934 | acer_backlight_device = NULL; |
@@ -935,7 +939,6 @@ static int __devinit acer_backlight_init(struct device *dev) | |||
935 | 939 | ||
936 | bd->props.power = FB_BLANK_UNBLANK; | 940 | bd->props.power = FB_BLANK_UNBLANK; |
937 | bd->props.brightness = read_brightness(bd); | 941 | bd->props.brightness = read_brightness(bd); |
938 | bd->props.max_brightness = max_brightness; | ||
939 | backlight_update_status(bd); | 942 | backlight_update_status(bd); |
940 | return 0; | 943 | return 0; |
941 | } | 944 | } |
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 791fcf321506..db5f7db2ba33 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -639,12 +639,16 @@ static int asus_backlight_init(struct asus_laptop *asus) | |||
639 | { | 639 | { |
640 | struct backlight_device *bd; | 640 | struct backlight_device *bd; |
641 | struct device *dev = &asus->platform_device->dev; | 641 | struct device *dev = &asus->platform_device->dev; |
642 | struct backlight_properties props; | ||
642 | 643 | ||
643 | if (!acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_GET, NULL) && | 644 | if (!acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_GET, NULL) && |
644 | !acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL) && | 645 | !acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL) && |
645 | lcd_switch_handle) { | 646 | lcd_switch_handle) { |
647 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
648 | props.max_brightness = 15; | ||
649 | |||
646 | bd = backlight_device_register(ASUS_LAPTOP_FILE, dev, | 650 | bd = backlight_device_register(ASUS_LAPTOP_FILE, dev, |
647 | asus, &asusbl_ops); | 651 | asus, &asusbl_ops, &props); |
648 | if (IS_ERR(bd)) { | 652 | if (IS_ERR(bd)) { |
649 | pr_err("Could not register asus backlight device\n"); | 653 | pr_err("Could not register asus backlight device\n"); |
650 | asus->backlight_device = NULL; | 654 | asus->backlight_device = NULL; |
@@ -653,7 +657,6 @@ static int asus_backlight_init(struct asus_laptop *asus) | |||
653 | 657 | ||
654 | asus->backlight_device = bd; | 658 | asus->backlight_device = bd; |
655 | 659 | ||
656 | bd->props.max_brightness = 15; | ||
657 | bd->props.power = FB_BLANK_UNBLANK; | 660 | bd->props.power = FB_BLANK_UNBLANK; |
658 | bd->props.brightness = asus_read_brightness(bd); | 661 | bd->props.brightness = asus_read_brightness(bd); |
659 | backlight_update_status(bd); | 662 | backlight_update_status(bd); |
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index 1381430e1105..ee520357abaa 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c | |||
@@ -1481,6 +1481,7 @@ static void asus_acpi_exit(void) | |||
1481 | 1481 | ||
1482 | static int __init asus_acpi_init(void) | 1482 | static int __init asus_acpi_init(void) |
1483 | { | 1483 | { |
1484 | struct backlight_properties props; | ||
1484 | int result; | 1485 | int result; |
1485 | 1486 | ||
1486 | result = acpi_bus_register_driver(&asus_hotk_driver); | 1487 | result = acpi_bus_register_driver(&asus_hotk_driver); |
@@ -1507,15 +1508,17 @@ static int __init asus_acpi_init(void) | |||
1507 | return -ENODEV; | 1508 | return -ENODEV; |
1508 | } | 1509 | } |
1509 | 1510 | ||
1511 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
1512 | props.max_brightness = 15; | ||
1510 | asus_backlight_device = backlight_device_register("asus", NULL, NULL, | 1513 | asus_backlight_device = backlight_device_register("asus", NULL, NULL, |
1511 | &asus_backlight_data); | 1514 | &asus_backlight_data, |
1515 | &props); | ||
1512 | if (IS_ERR(asus_backlight_device)) { | 1516 | if (IS_ERR(asus_backlight_device)) { |
1513 | printk(KERN_ERR "Could not register asus backlight device\n"); | 1517 | printk(KERN_ERR "Could not register asus backlight device\n"); |
1514 | asus_backlight_device = NULL; | 1518 | asus_backlight_device = NULL; |
1515 | asus_acpi_exit(); | 1519 | asus_acpi_exit(); |
1516 | return -ENODEV; | 1520 | return -ENODEV; |
1517 | } | 1521 | } |
1518 | asus_backlight_device->props.max_brightness = 15; | ||
1519 | 1522 | ||
1520 | return 0; | 1523 | return 0; |
1521 | } | 1524 | } |
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 035a7dd65a3f..c696cf1c2616 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c | |||
@@ -455,18 +455,22 @@ static int cmpc_bl_update_status(struct backlight_device *bd) | |||
455 | return -1; | 455 | return -1; |
456 | } | 456 | } |
457 | 457 | ||
458 | static struct backlight_ops cmpc_bl_ops = { | 458 | static const struct backlight_ops cmpc_bl_ops = { |
459 | .get_brightness = cmpc_bl_get_brightness, | 459 | .get_brightness = cmpc_bl_get_brightness, |
460 | .update_status = cmpc_bl_update_status | 460 | .update_status = cmpc_bl_update_status |
461 | }; | 461 | }; |
462 | 462 | ||
463 | static int cmpc_bl_add(struct acpi_device *acpi) | 463 | static int cmpc_bl_add(struct acpi_device *acpi) |
464 | { | 464 | { |
465 | struct backlight_properties props; | ||
465 | struct backlight_device *bd; | 466 | struct backlight_device *bd; |
466 | 467 | ||
467 | bd = backlight_device_register("cmpc_bl", &acpi->dev, | 468 | memset(&props, 0, sizeof(struct backlight_properties)); |
468 | acpi->handle, &cmpc_bl_ops); | 469 | props.max_brightness = 7; |
469 | bd->props.max_brightness = 7; | 470 | bd = backlight_device_register("cmpc_bl", &acpi->dev, acpi->handle, |
471 | &cmpc_bl_ops, &props); | ||
472 | if (IS_ERR(bd)) | ||
473 | return PTR_ERR(bd); | ||
470 | dev_set_drvdata(&acpi->dev, bd); | 474 | dev_set_drvdata(&acpi->dev, bd); |
471 | return 0; | 475 | return 0; |
472 | } | 476 | } |
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index 2740b40aad9b..71ff1545a93e 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c | |||
@@ -291,12 +291,15 @@ static int __init compal_init(void) | |||
291 | /* Register backlight stuff */ | 291 | /* Register backlight stuff */ |
292 | 292 | ||
293 | if (!acpi_video_backlight_support()) { | 293 | if (!acpi_video_backlight_support()) { |
294 | compalbl_device = backlight_device_register("compal-laptop", NULL, NULL, | 294 | struct backlight_properties props; |
295 | &compalbl_ops); | 295 | memset(&props, 0, sizeof(struct backlight_properties)); |
296 | props.max_brightness = COMPAL_LCD_LEVEL_MAX - 1; | ||
297 | compalbl_device = backlight_device_register("compal-laptop", | ||
298 | NULL, NULL, | ||
299 | &compalbl_ops, | ||
300 | &props); | ||
296 | if (IS_ERR(compalbl_device)) | 301 | if (IS_ERR(compalbl_device)) |
297 | return PTR_ERR(compalbl_device); | 302 | return PTR_ERR(compalbl_device); |
298 | |||
299 | compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1; | ||
300 | } | 303 | } |
301 | 304 | ||
302 | ret = platform_driver_register(&compal_driver); | 305 | ret = platform_driver_register(&compal_driver); |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index ef614979afe9..46435ac4684f 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -559,10 +559,14 @@ static int __init dell_init(void) | |||
559 | release_buffer(); | 559 | release_buffer(); |
560 | 560 | ||
561 | if (max_intensity) { | 561 | if (max_intensity) { |
562 | dell_backlight_device = backlight_device_register( | 562 | struct backlight_properties props; |
563 | "dell_backlight", | 563 | memset(&props, 0, sizeof(struct backlight_properties)); |
564 | &platform_device->dev, NULL, | 564 | props.max_brightness = max_intensity; |
565 | &dell_ops); | 565 | dell_backlight_device = backlight_device_register("dell_backlight", |
566 | &platform_device->dev, | ||
567 | NULL, | ||
568 | &dell_ops, | ||
569 | &props); | ||
566 | 570 | ||
567 | if (IS_ERR(dell_backlight_device)) { | 571 | if (IS_ERR(dell_backlight_device)) { |
568 | ret = PTR_ERR(dell_backlight_device); | 572 | ret = PTR_ERR(dell_backlight_device); |
@@ -570,7 +574,6 @@ static int __init dell_init(void) | |||
570 | goto fail_backlight; | 574 | goto fail_backlight; |
571 | } | 575 | } |
572 | 576 | ||
573 | dell_backlight_device->props.max_brightness = max_intensity; | ||
574 | dell_backlight_device->props.brightness = | 577 | dell_backlight_device->props.brightness = |
575 | dell_get_intensity(dell_backlight_device); | 578 | dell_get_intensity(dell_backlight_device); |
576 | backlight_update_status(dell_backlight_device); | 579 | backlight_update_status(dell_backlight_device); |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 9a844caa3756..3fdf21e0052e 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -1131,18 +1131,20 @@ static int eeepc_backlight_notify(struct eeepc_laptop *eeepc) | |||
1131 | 1131 | ||
1132 | static int eeepc_backlight_init(struct eeepc_laptop *eeepc) | 1132 | static int eeepc_backlight_init(struct eeepc_laptop *eeepc) |
1133 | { | 1133 | { |
1134 | struct backlight_properties props; | ||
1134 | struct backlight_device *bd; | 1135 | struct backlight_device *bd; |
1135 | 1136 | ||
1137 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
1138 | props.max_brightness = 15; | ||
1136 | bd = backlight_device_register(EEEPC_LAPTOP_FILE, | 1139 | bd = backlight_device_register(EEEPC_LAPTOP_FILE, |
1137 | &eeepc->platform_device->dev, | 1140 | &eeepc->platform_device->dev, eeepc, |
1138 | eeepc, &eeepcbl_ops); | 1141 | &eeepcbl_ops, &props); |
1139 | if (IS_ERR(bd)) { | 1142 | if (IS_ERR(bd)) { |
1140 | pr_err("Could not register eeepc backlight device\n"); | 1143 | pr_err("Could not register eeepc backlight device\n"); |
1141 | eeepc->backlight_device = NULL; | 1144 | eeepc->backlight_device = NULL; |
1142 | return PTR_ERR(bd); | 1145 | return PTR_ERR(bd); |
1143 | } | 1146 | } |
1144 | eeepc->backlight_device = bd; | 1147 | eeepc->backlight_device = bd; |
1145 | bd->props.max_brightness = 15; | ||
1146 | bd->props.brightness = read_brightness(bd); | 1148 | bd->props.brightness = read_brightness(bd); |
1147 | bd->props.power = FB_BLANK_UNBLANK; | 1149 | bd->props.power = FB_BLANK_UNBLANK; |
1148 | backlight_update_status(bd); | 1150 | backlight_update_status(bd); |
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 5f3320d468f6..c1074b32490e 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -1126,16 +1126,20 @@ static int __init fujitsu_init(void) | |||
1126 | /* Register backlight stuff */ | 1126 | /* Register backlight stuff */ |
1127 | 1127 | ||
1128 | if (!acpi_video_backlight_support()) { | 1128 | if (!acpi_video_backlight_support()) { |
1129 | fujitsu->bl_device = | 1129 | struct backlight_properties props; |
1130 | backlight_device_register("fujitsu-laptop", NULL, NULL, | 1130 | |
1131 | &fujitsubl_ops); | 1131 | memset(&props, 0, sizeof(struct backlight_properties)); |
1132 | max_brightness = fujitsu->max_brightness; | ||
1133 | props.max_brightness = max_brightness - 1; | ||
1134 | fujitsu->bl_device = backlight_device_register("fujitsu-laptop", | ||
1135 | NULL, NULL, | ||
1136 | &fujitsubl_ops, | ||
1137 | &props); | ||
1132 | if (IS_ERR(fujitsu->bl_device)) { | 1138 | if (IS_ERR(fujitsu->bl_device)) { |
1133 | ret = PTR_ERR(fujitsu->bl_device); | 1139 | ret = PTR_ERR(fujitsu->bl_device); |
1134 | fujitsu->bl_device = NULL; | 1140 | fujitsu->bl_device = NULL; |
1135 | goto fail_sysfs_group; | 1141 | goto fail_sysfs_group; |
1136 | } | 1142 | } |
1137 | max_brightness = fujitsu->max_brightness; | ||
1138 | fujitsu->bl_device->props.max_brightness = max_brightness - 1; | ||
1139 | fujitsu->bl_device->props.brightness = fujitsu->brightness_level; | 1143 | fujitsu->bl_device->props.brightness = fujitsu->brightness_level; |
1140 | } | 1144 | } |
1141 | 1145 | ||
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index c2b05da4289a..996223a7c009 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c | |||
@@ -683,11 +683,14 @@ static int __init msi_init(void) | |||
683 | printk(KERN_INFO "MSI: Brightness ignored, must be controlled " | 683 | printk(KERN_INFO "MSI: Brightness ignored, must be controlled " |
684 | "by ACPI video driver\n"); | 684 | "by ACPI video driver\n"); |
685 | } else { | 685 | } else { |
686 | struct backlight_properties props; | ||
687 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
688 | props.max_brightness = MSI_LCD_LEVEL_MAX - 1; | ||
686 | msibl_device = backlight_device_register("msi-laptop-bl", NULL, | 689 | msibl_device = backlight_device_register("msi-laptop-bl", NULL, |
687 | NULL, &msibl_ops); | 690 | NULL, &msibl_ops, |
691 | &props); | ||
688 | if (IS_ERR(msibl_device)) | 692 | if (IS_ERR(msibl_device)) |
689 | return PTR_ERR(msibl_device); | 693 | return PTR_ERR(msibl_device); |
690 | msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1; | ||
691 | } | 694 | } |
692 | 695 | ||
693 | ret = platform_driver_register(&msipf_driver); | 696 | ret = platform_driver_register(&msipf_driver); |
diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index f5f70d4c6913..367caaae2f3c 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c | |||
@@ -138,7 +138,7 @@ static int bl_set_status(struct backlight_device *bd) | |||
138 | return msi_wmi_set_block(0, backlight_map[bright]); | 138 | return msi_wmi_set_block(0, backlight_map[bright]); |
139 | } | 139 | } |
140 | 140 | ||
141 | static struct backlight_ops msi_backlight_ops = { | 141 | static const struct backlight_ops msi_backlight_ops = { |
142 | .get_brightness = bl_get, | 142 | .get_brightness = bl_get, |
143 | .update_status = bl_set_status, | 143 | .update_status = bl_set_status, |
144 | }; | 144 | }; |
@@ -249,12 +249,17 @@ static int __init msi_wmi_init(void) | |||
249 | goto err_uninstall_notifier; | 249 | goto err_uninstall_notifier; |
250 | 250 | ||
251 | if (!acpi_video_backlight_support()) { | 251 | if (!acpi_video_backlight_support()) { |
252 | backlight = backlight_device_register(DRV_NAME, | 252 | struct backlight_properties props; |
253 | NULL, NULL, &msi_backlight_ops); | 253 | memset(&props, 0, sizeof(struct backlight_properties)); |
254 | if (IS_ERR(backlight)) | 254 | props.max_brightness = ARRAY_SIZE(backlight_map) - 1; |
255 | backlight = backlight_device_register(DRV_NAME, NULL, NULL, | ||
256 | &msi_backlight_ops, | ||
257 | &props); | ||
258 | if (IS_ERR(backlight)) { | ||
259 | err = PTR_ERR(backlight); | ||
255 | goto err_free_input; | 260 | goto err_free_input; |
261 | } | ||
256 | 262 | ||
257 | backlight->props.max_brightness = ARRAY_SIZE(backlight_map) - 1; | ||
258 | err = bl_get(NULL); | 263 | err = bl_get(NULL); |
259 | if (err < 0) | 264 | if (err < 0) |
260 | goto err_free_backlight; | 265 | goto err_free_backlight; |
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index c9fc479fc290..726f02affcb6 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c | |||
@@ -352,7 +352,7 @@ static int bl_set_status(struct backlight_device *bd) | |||
352 | return acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, bright); | 352 | return acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, bright); |
353 | } | 353 | } |
354 | 354 | ||
355 | static struct backlight_ops pcc_backlight_ops = { | 355 | static const struct backlight_ops pcc_backlight_ops = { |
356 | .get_brightness = bl_get, | 356 | .get_brightness = bl_get, |
357 | .update_status = bl_set_status, | 357 | .update_status = bl_set_status, |
358 | }; | 358 | }; |
@@ -600,6 +600,7 @@ static int acpi_pcc_hotkey_resume(struct acpi_device *device) | |||
600 | 600 | ||
601 | static int acpi_pcc_hotkey_add(struct acpi_device *device) | 601 | static int acpi_pcc_hotkey_add(struct acpi_device *device) |
602 | { | 602 | { |
603 | struct backlight_properties props; | ||
603 | struct pcc_acpi *pcc; | 604 | struct pcc_acpi *pcc; |
604 | int num_sifr, result; | 605 | int num_sifr, result; |
605 | 606 | ||
@@ -637,24 +638,25 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) | |||
637 | if (result) { | 638 | if (result) { |
638 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 639 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
639 | "Error installing keyinput handler\n")); | 640 | "Error installing keyinput handler\n")); |
640 | goto out_sinf; | 641 | goto out_hotkey; |
641 | } | 642 | } |
642 | 643 | ||
643 | /* initialize backlight */ | ||
644 | pcc->backlight = backlight_device_register("panasonic", NULL, pcc, | ||
645 | &pcc_backlight_ops); | ||
646 | if (IS_ERR(pcc->backlight)) | ||
647 | goto out_input; | ||
648 | |||
649 | if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) { | 644 | if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) { |
650 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 645 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
651 | "Couldn't retrieve BIOS data\n")); | 646 | "Couldn't retrieve BIOS data\n")); |
652 | goto out_backlight; | 647 | goto out_input; |
648 | } | ||
649 | /* initialize backlight */ | ||
650 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
651 | props.max_brightness = pcc->sinf[SINF_AC_MAX_BRIGHT]; | ||
652 | pcc->backlight = backlight_device_register("panasonic", NULL, pcc, | ||
653 | &pcc_backlight_ops, &props); | ||
654 | if (IS_ERR(pcc->backlight)) { | ||
655 | result = PTR_ERR(pcc->backlight); | ||
656 | goto out_sinf; | ||
653 | } | 657 | } |
654 | 658 | ||
655 | /* read the initial brightness setting from the hardware */ | 659 | /* read the initial brightness setting from the hardware */ |
656 | pcc->backlight->props.max_brightness = | ||
657 | pcc->sinf[SINF_AC_MAX_BRIGHT]; | ||
658 | pcc->backlight->props.brightness = pcc->sinf[SINF_AC_CUR_BRIGHT]; | 660 | pcc->backlight->props.brightness = pcc->sinf[SINF_AC_CUR_BRIGHT]; |
659 | 661 | ||
660 | /* read the initial sticky key mode from the hardware */ | 662 | /* read the initial sticky key mode from the hardware */ |
@@ -669,12 +671,12 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) | |||
669 | 671 | ||
670 | out_backlight: | 672 | out_backlight: |
671 | backlight_device_unregister(pcc->backlight); | 673 | backlight_device_unregister(pcc->backlight); |
674 | out_sinf: | ||
675 | kfree(pcc->sinf); | ||
672 | out_input: | 676 | out_input: |
673 | input_unregister_device(pcc->input_dev); | 677 | input_unregister_device(pcc->input_dev); |
674 | /* no need to input_free_device() since core input API refcount and | 678 | /* no need to input_free_device() since core input API refcount and |
675 | * free()s the device */ | 679 | * free()s the device */ |
676 | out_sinf: | ||
677 | kfree(pcc->sinf); | ||
678 | out_hotkey: | 680 | out_hotkey: |
679 | kfree(pcc); | 681 | kfree(pcc); |
680 | 682 | ||
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 5a3d8514c66d..6553b91caaa4 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -1291,9 +1291,13 @@ static int sony_nc_add(struct acpi_device *device) | |||
1291 | "controlled by ACPI video driver\n"); | 1291 | "controlled by ACPI video driver\n"); |
1292 | } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", | 1292 | } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", |
1293 | &handle))) { | 1293 | &handle))) { |
1294 | struct backlight_properties props; | ||
1295 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
1296 | props.max_brightness = SONY_MAX_BRIGHTNESS - 1; | ||
1294 | sony_backlight_device = backlight_device_register("sony", NULL, | 1297 | sony_backlight_device = backlight_device_register("sony", NULL, |
1295 | NULL, | 1298 | NULL, |
1296 | &sony_backlight_ops); | 1299 | &sony_backlight_ops, |
1300 | &props); | ||
1297 | 1301 | ||
1298 | if (IS_ERR(sony_backlight_device)) { | 1302 | if (IS_ERR(sony_backlight_device)) { |
1299 | printk(KERN_WARNING DRV_PFX "unable to register backlight device\n"); | 1303 | printk(KERN_WARNING DRV_PFX "unable to register backlight device\n"); |
@@ -1302,8 +1306,6 @@ static int sony_nc_add(struct acpi_device *device) | |||
1302 | sony_backlight_device->props.brightness = | 1306 | sony_backlight_device->props.brightness = |
1303 | sony_backlight_get_brightness | 1307 | sony_backlight_get_brightness |
1304 | (sony_backlight_device); | 1308 | (sony_backlight_device); |
1305 | sony_backlight_device->props.max_brightness = | ||
1306 | SONY_MAX_BRIGHTNESS - 1; | ||
1307 | } | 1309 | } |
1308 | 1310 | ||
1309 | } | 1311 | } |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index c64e3528889b..770b85327f84 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -6170,6 +6170,7 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { | |||
6170 | 6170 | ||
6171 | static int __init brightness_init(struct ibm_init_struct *iibm) | 6171 | static int __init brightness_init(struct ibm_init_struct *iibm) |
6172 | { | 6172 | { |
6173 | struct backlight_properties props; | ||
6173 | int b; | 6174 | int b; |
6174 | unsigned long quirks; | 6175 | unsigned long quirks; |
6175 | 6176 | ||
@@ -6259,9 +6260,12 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
6259 | printk(TPACPI_INFO | 6260 | printk(TPACPI_INFO |
6260 | "detected a 16-level brightness capable ThinkPad\n"); | 6261 | "detected a 16-level brightness capable ThinkPad\n"); |
6261 | 6262 | ||
6262 | ibm_backlight_device = backlight_device_register( | 6263 | memset(&props, 0, sizeof(struct backlight_properties)); |
6263 | TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, | 6264 | props.max_brightness = (tp_features.bright_16levels) ? 15 : 7; |
6264 | &ibm_backlight_data); | 6265 | ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME, |
6266 | NULL, NULL, | ||
6267 | &ibm_backlight_data, | ||
6268 | &props); | ||
6265 | if (IS_ERR(ibm_backlight_device)) { | 6269 | if (IS_ERR(ibm_backlight_device)) { |
6266 | int rc = PTR_ERR(ibm_backlight_device); | 6270 | int rc = PTR_ERR(ibm_backlight_device); |
6267 | ibm_backlight_device = NULL; | 6271 | ibm_backlight_device = NULL; |
@@ -6280,8 +6284,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
6280 | "or not on your ThinkPad\n", TPACPI_MAIL); | 6284 | "or not on your ThinkPad\n", TPACPI_MAIL); |
6281 | } | 6285 | } |
6282 | 6286 | ||
6283 | ibm_backlight_device->props.max_brightness = | ||
6284 | (tp_features.bright_16levels)? 15 : 7; | ||
6285 | ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; | 6287 | ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; |
6286 | backlight_update_status(ibm_backlight_device); | 6288 | backlight_update_status(ibm_backlight_device); |
6287 | 6289 | ||
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 789240d1b577..def4841183be 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -924,6 +924,7 @@ static int __init toshiba_acpi_init(void) | |||
924 | u32 hci_result; | 924 | u32 hci_result; |
925 | bool bt_present; | 925 | bool bt_present; |
926 | int ret = 0; | 926 | int ret = 0; |
927 | struct backlight_properties props; | ||
927 | 928 | ||
928 | if (acpi_disabled) | 929 | if (acpi_disabled) |
929 | return -ENODEV; | 930 | return -ENODEV; |
@@ -974,10 +975,12 @@ static int __init toshiba_acpi_init(void) | |||
974 | } | 975 | } |
975 | } | 976 | } |
976 | 977 | ||
978 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; | ||
977 | toshiba_backlight_device = backlight_device_register("toshiba", | 979 | toshiba_backlight_device = backlight_device_register("toshiba", |
978 | &toshiba_acpi.p_dev->dev, | 980 | &toshiba_acpi.p_dev->dev, |
979 | NULL, | 981 | NULL, |
980 | &toshiba_backlight_data); | 982 | &toshiba_backlight_data, |
983 | &props); | ||
981 | if (IS_ERR(toshiba_backlight_device)) { | 984 | if (IS_ERR(toshiba_backlight_device)) { |
982 | ret = PTR_ERR(toshiba_backlight_device); | 985 | ret = PTR_ERR(toshiba_backlight_device); |
983 | 986 | ||
@@ -986,7 +989,6 @@ static int __init toshiba_acpi_init(void) | |||
986 | toshiba_acpi_exit(); | 989 | toshiba_acpi_exit(); |
987 | return ret; | 990 | return ret; |
988 | } | 991 | } |
989 | toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; | ||
990 | 992 | ||
991 | /* Register rfkill switch for Bluetooth */ | 993 | /* Register rfkill switch for Bluetooth */ |
992 | if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) { | 994 | if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) { |
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index b3beab610da4..fc7ae05ce48a 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c | |||
@@ -704,6 +704,13 @@ int sclp_chp_deconfigure(struct chp_id chpid) | |||
704 | return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH | chpid.id << 8); | 704 | return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH | chpid.id << 8); |
705 | } | 705 | } |
706 | 706 | ||
707 | int arch_get_memory_phys_device(unsigned long start_pfn) | ||
708 | { | ||
709 | if (!rzm) | ||
710 | return 0; | ||
711 | return PFN_PHYS(start_pfn) / rzm; | ||
712 | } | ||
713 | |||
707 | struct chp_info_sccb { | 714 | struct chp_info_sccb { |
708 | struct sccb_header header; | 715 | struct sccb_header header; |
709 | u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; | 716 | u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 9191d1ea6451..75f2336807cb 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -1,9 +1,15 @@ | |||
1 | menu "SCSI device support" | 1 | menu "SCSI device support" |
2 | 2 | ||
3 | config SCSI_MOD | ||
4 | tristate | ||
5 | default y if SCSI=n || SCSI=y | ||
6 | default m if SCSI=m | ||
7 | |||
3 | config RAID_ATTRS | 8 | config RAID_ATTRS |
4 | tristate "RAID Transport Class" | 9 | tristate "RAID Transport Class" |
5 | default n | 10 | default n |
6 | depends on BLOCK | 11 | depends on BLOCK |
12 | depends on SCSI_MOD | ||
7 | ---help--- | 13 | ---help--- |
8 | Provides RAID | 14 | Provides RAID |
9 | 15 | ||
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 67098578fba4..cda6642c7368 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c | |||
@@ -32,18 +32,11 @@ void be_mcc_notify(struct beiscsi_hba *phba) | |||
32 | unsigned int alloc_mcc_tag(struct beiscsi_hba *phba) | 32 | unsigned int alloc_mcc_tag(struct beiscsi_hba *phba) |
33 | { | 33 | { |
34 | unsigned int tag = 0; | 34 | unsigned int tag = 0; |
35 | unsigned int num = 0; | ||
36 | 35 | ||
37 | mcc_tag_rdy: | ||
38 | if (phba->ctrl.mcc_tag_available) { | 36 | if (phba->ctrl.mcc_tag_available) { |
39 | tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index]; | 37 | tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index]; |
40 | phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0; | 38 | phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0; |
41 | phba->ctrl.mcc_numtag[tag] = 0; | 39 | phba->ctrl.mcc_numtag[tag] = 0; |
42 | } else { | ||
43 | udelay(100); | ||
44 | num++; | ||
45 | if (num < mcc_timeout) | ||
46 | goto mcc_tag_rdy; | ||
47 | } | 40 | } |
48 | if (tag) { | 41 | if (tag) { |
49 | phba->ctrl.mcc_tag_available--; | 42 | phba->ctrl.mcc_tag_available--; |
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index 29a3aaf35f9f..c3928cb8b042 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c | |||
@@ -482,7 +482,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, | |||
482 | tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep); | 482 | tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep); |
483 | if (!tag) { | 483 | if (!tag) { |
484 | SE_DEBUG(DBG_LVL_1, | 484 | SE_DEBUG(DBG_LVL_1, |
485 | "mgmt_invalidate_connection Failed for cid=%d \n", | 485 | "mgmt_open_connection Failed for cid=%d \n", |
486 | beiscsi_ep->ep_cid); | 486 | beiscsi_ep->ep_cid); |
487 | } else { | 487 | } else { |
488 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | 488 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], |
@@ -701,7 +701,7 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) | |||
701 | if (!tag) { | 701 | if (!tag) { |
702 | SE_DEBUG(DBG_LVL_1, | 702 | SE_DEBUG(DBG_LVL_1, |
703 | "mgmt_invalidate_connection Failed for cid=%d \n", | 703 | "mgmt_invalidate_connection Failed for cid=%d \n", |
704 | beiscsi_ep->ep_cid); | 704 | beiscsi_ep->ep_cid); |
705 | } else { | 705 | } else { |
706 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | 706 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], |
707 | phba->ctrl.mcc_numtag[tag]); | 707 | phba->ctrl.mcc_numtag[tag]); |
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 7c22616ab141..fcfb29e02d8a 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -58,6 +58,123 @@ static int beiscsi_slave_configure(struct scsi_device *sdev) | |||
58 | return 0; | 58 | return 0; |
59 | } | 59 | } |
60 | 60 | ||
61 | static int beiscsi_eh_abort(struct scsi_cmnd *sc) | ||
62 | { | ||
63 | struct iscsi_cls_session *cls_session; | ||
64 | struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr; | ||
65 | struct beiscsi_io_task *aborted_io_task; | ||
66 | struct iscsi_conn *conn; | ||
67 | struct beiscsi_conn *beiscsi_conn; | ||
68 | struct beiscsi_hba *phba; | ||
69 | struct iscsi_session *session; | ||
70 | struct invalidate_command_table *inv_tbl; | ||
71 | unsigned int cid, tag, num_invalidate; | ||
72 | |||
73 | cls_session = starget_to_session(scsi_target(sc->device)); | ||
74 | session = cls_session->dd_data; | ||
75 | |||
76 | spin_lock_bh(&session->lock); | ||
77 | if (!aborted_task || !aborted_task->sc) { | ||
78 | /* we raced */ | ||
79 | spin_unlock_bh(&session->lock); | ||
80 | return SUCCESS; | ||
81 | } | ||
82 | |||
83 | aborted_io_task = aborted_task->dd_data; | ||
84 | if (!aborted_io_task->scsi_cmnd) { | ||
85 | /* raced or invalid command */ | ||
86 | spin_unlock_bh(&session->lock); | ||
87 | return SUCCESS; | ||
88 | } | ||
89 | spin_unlock_bh(&session->lock); | ||
90 | conn = aborted_task->conn; | ||
91 | beiscsi_conn = conn->dd_data; | ||
92 | phba = beiscsi_conn->phba; | ||
93 | |||
94 | /* invalidate iocb */ | ||
95 | cid = beiscsi_conn->beiscsi_conn_cid; | ||
96 | inv_tbl = phba->inv_tbl; | ||
97 | memset(inv_tbl, 0x0, sizeof(*inv_tbl)); | ||
98 | inv_tbl->cid = cid; | ||
99 | inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index; | ||
100 | num_invalidate = 1; | ||
101 | tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid); | ||
102 | if (!tag) { | ||
103 | shost_printk(KERN_WARNING, phba->shost, | ||
104 | "mgmt_invalidate_icds could not be" | ||
105 | " submitted\n"); | ||
106 | return FAILED; | ||
107 | } else { | ||
108 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
109 | phba->ctrl.mcc_numtag[tag]); | ||
110 | free_mcc_tag(&phba->ctrl, tag); | ||
111 | } | ||
112 | |||
113 | return iscsi_eh_abort(sc); | ||
114 | } | ||
115 | |||
116 | static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) | ||
117 | { | ||
118 | struct iscsi_task *abrt_task; | ||
119 | struct beiscsi_io_task *abrt_io_task; | ||
120 | struct iscsi_conn *conn; | ||
121 | struct beiscsi_conn *beiscsi_conn; | ||
122 | struct beiscsi_hba *phba; | ||
123 | struct iscsi_session *session; | ||
124 | struct iscsi_cls_session *cls_session; | ||
125 | struct invalidate_command_table *inv_tbl; | ||
126 | unsigned int cid, tag, i, num_invalidate; | ||
127 | int rc = FAILED; | ||
128 | |||
129 | /* invalidate iocbs */ | ||
130 | cls_session = starget_to_session(scsi_target(sc->device)); | ||
131 | session = cls_session->dd_data; | ||
132 | spin_lock_bh(&session->lock); | ||
133 | if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN) | ||
134 | goto unlock; | ||
135 | |||
136 | conn = session->leadconn; | ||
137 | beiscsi_conn = conn->dd_data; | ||
138 | phba = beiscsi_conn->phba; | ||
139 | cid = beiscsi_conn->beiscsi_conn_cid; | ||
140 | inv_tbl = phba->inv_tbl; | ||
141 | memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN); | ||
142 | num_invalidate = 0; | ||
143 | for (i = 0; i < conn->session->cmds_max; i++) { | ||
144 | abrt_task = conn->session->cmds[i]; | ||
145 | abrt_io_task = abrt_task->dd_data; | ||
146 | if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE) | ||
147 | continue; | ||
148 | |||
149 | if (abrt_task->sc->device->lun != abrt_task->sc->device->lun) | ||
150 | continue; | ||
151 | |||
152 | inv_tbl->cid = cid; | ||
153 | inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index; | ||
154 | num_invalidate++; | ||
155 | inv_tbl++; | ||
156 | } | ||
157 | spin_unlock_bh(&session->lock); | ||
158 | inv_tbl = phba->inv_tbl; | ||
159 | |||
160 | tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid); | ||
161 | if (!tag) { | ||
162 | shost_printk(KERN_WARNING, phba->shost, | ||
163 | "mgmt_invalidate_icds could not be" | ||
164 | " submitted\n"); | ||
165 | return FAILED; | ||
166 | } else { | ||
167 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
168 | phba->ctrl.mcc_numtag[tag]); | ||
169 | free_mcc_tag(&phba->ctrl, tag); | ||
170 | } | ||
171 | |||
172 | return iscsi_eh_device_reset(sc); | ||
173 | unlock: | ||
174 | spin_unlock_bh(&session->lock); | ||
175 | return rc; | ||
176 | } | ||
177 | |||
61 | /*------------------- PCI Driver operations and data ----------------- */ | 178 | /*------------------- PCI Driver operations and data ----------------- */ |
62 | static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { | 179 | static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { |
63 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, | 180 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, |
@@ -74,12 +191,12 @@ static struct scsi_host_template beiscsi_sht = { | |||
74 | .name = "ServerEngines 10Gbe open-iscsi Initiator Driver", | 191 | .name = "ServerEngines 10Gbe open-iscsi Initiator Driver", |
75 | .proc_name = DRV_NAME, | 192 | .proc_name = DRV_NAME, |
76 | .queuecommand = iscsi_queuecommand, | 193 | .queuecommand = iscsi_queuecommand, |
77 | .eh_abort_handler = iscsi_eh_abort, | ||
78 | .change_queue_depth = iscsi_change_queue_depth, | 194 | .change_queue_depth = iscsi_change_queue_depth, |
79 | .slave_configure = beiscsi_slave_configure, | 195 | .slave_configure = beiscsi_slave_configure, |
80 | .target_alloc = iscsi_target_alloc, | 196 | .target_alloc = iscsi_target_alloc, |
81 | .eh_device_reset_handler = iscsi_eh_device_reset, | 197 | .eh_abort_handler = beiscsi_eh_abort, |
82 | .eh_target_reset_handler = iscsi_eh_target_reset, | 198 | .eh_device_reset_handler = beiscsi_eh_device_reset, |
199 | .eh_target_reset_handler = iscsi_eh_session_reset, | ||
83 | .sg_tablesize = BEISCSI_SGLIST_ELEMENTS, | 200 | .sg_tablesize = BEISCSI_SGLIST_ELEMENTS, |
84 | .can_queue = BE2_IO_DEPTH, | 201 | .can_queue = BE2_IO_DEPTH, |
85 | .this_id = -1, | 202 | .this_id = -1, |
@@ -242,7 +359,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba) | |||
242 | + BE2_TMFS | 359 | + BE2_TMFS |
243 | + BE2_NOPOUT_REQ)); | 360 | + BE2_NOPOUT_REQ)); |
244 | phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count; | 361 | phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count; |
245 | phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count;; | 362 | phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count * 2; |
246 | phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;; | 363 | phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;; |
247 | phba->params.num_sge_per_io = BE2_SGE; | 364 | phba->params.num_sge_per_io = BE2_SGE; |
248 | phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; | 365 | phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; |
@@ -946,14 +1063,18 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, | |||
946 | case HWH_TYPE_IO: | 1063 | case HWH_TYPE_IO: |
947 | case HWH_TYPE_IO_RD: | 1064 | case HWH_TYPE_IO_RD: |
948 | if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == | 1065 | if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == |
949 | ISCSI_OP_NOOP_OUT) { | 1066 | ISCSI_OP_NOOP_OUT) |
950 | be_complete_nopin_resp(beiscsi_conn, task, psol); | 1067 | be_complete_nopin_resp(beiscsi_conn, task, psol); |
951 | } else | 1068 | else |
952 | be_complete_io(beiscsi_conn, task, psol); | 1069 | be_complete_io(beiscsi_conn, task, psol); |
953 | break; | 1070 | break; |
954 | 1071 | ||
955 | case HWH_TYPE_LOGOUT: | 1072 | case HWH_TYPE_LOGOUT: |
956 | be_complete_logout(beiscsi_conn, task, psol); | 1073 | if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) |
1074 | be_complete_logout(beiscsi_conn, task, psol); | ||
1075 | else | ||
1076 | be_complete_tmf(beiscsi_conn, task, psol); | ||
1077 | |||
957 | break; | 1078 | break; |
958 | 1079 | ||
959 | case HWH_TYPE_LOGIN: | 1080 | case HWH_TYPE_LOGIN: |
@@ -962,10 +1083,6 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, | |||
962 | "- Solicited path \n"); | 1083 | "- Solicited path \n"); |
963 | break; | 1084 | break; |
964 | 1085 | ||
965 | case HWH_TYPE_TMF: | ||
966 | be_complete_tmf(beiscsi_conn, task, psol); | ||
967 | break; | ||
968 | |||
969 | case HWH_TYPE_NOP: | 1086 | case HWH_TYPE_NOP: |
970 | be_complete_nopin_resp(beiscsi_conn, task, psol); | 1087 | be_complete_nopin_resp(beiscsi_conn, task, psol); |
971 | break; | 1088 | break; |
@@ -2052,7 +2169,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) | |||
2052 | num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / | 2169 | num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / |
2053 | ((sizeof(struct iscsi_wrb) * | 2170 | ((sizeof(struct iscsi_wrb) * |
2054 | phba->params.wrbs_per_cxn)); | 2171 | phba->params.wrbs_per_cxn)); |
2055 | for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) { | 2172 | for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { |
2056 | pwrb_context = &phwi_ctrlr->wrb_context[index]; | 2173 | pwrb_context = &phwi_ctrlr->wrb_context[index]; |
2057 | if (num_cxn_wrb) { | 2174 | if (num_cxn_wrb) { |
2058 | for (j = 0; j < phba->params.wrbs_per_cxn; j++) { | 2175 | for (j = 0; j < phba->params.wrbs_per_cxn; j++) { |
@@ -3073,14 +3190,18 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba) | |||
3073 | reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; | 3190 | reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; |
3074 | SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr); | 3191 | SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr); |
3075 | iowrite32(reg, addr); | 3192 | iowrite32(reg, addr); |
3076 | for (i = 0; i <= phba->num_cpus; i++) { | 3193 | if (!phba->msix_enabled) { |
3077 | eq = &phwi_context->be_eq[i].q; | 3194 | eq = &phwi_context->be_eq[0].q; |
3078 | SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); | 3195 | SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); |
3079 | hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); | 3196 | hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); |
3197 | } else { | ||
3198 | for (i = 0; i <= phba->num_cpus; i++) { | ||
3199 | eq = &phwi_context->be_eq[i].q; | ||
3200 | SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); | ||
3201 | hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); | ||
3202 | } | ||
3080 | } | 3203 | } |
3081 | } else | 3204 | } |
3082 | shost_printk(KERN_WARNING, phba->shost, | ||
3083 | "In hwi_enable_intr, Not Enabled \n"); | ||
3084 | return true; | 3205 | return true; |
3085 | } | 3206 | } |
3086 | 3207 | ||
@@ -3476,19 +3597,13 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, | |||
3476 | 3597 | ||
3477 | static int beiscsi_mtask(struct iscsi_task *task) | 3598 | static int beiscsi_mtask(struct iscsi_task *task) |
3478 | { | 3599 | { |
3479 | struct beiscsi_io_task *aborted_io_task, *io_task = task->dd_data; | 3600 | struct beiscsi_io_task *io_task = task->dd_data; |
3480 | struct iscsi_conn *conn = task->conn; | 3601 | struct iscsi_conn *conn = task->conn; |
3481 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; | 3602 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; |
3482 | struct beiscsi_hba *phba = beiscsi_conn->phba; | 3603 | struct beiscsi_hba *phba = beiscsi_conn->phba; |
3483 | struct iscsi_session *session; | ||
3484 | struct iscsi_wrb *pwrb = NULL; | 3604 | struct iscsi_wrb *pwrb = NULL; |
3485 | struct hwi_controller *phwi_ctrlr; | ||
3486 | struct hwi_wrb_context *pwrb_context; | ||
3487 | struct wrb_handle *pwrb_handle; | ||
3488 | unsigned int doorbell = 0; | 3605 | unsigned int doorbell = 0; |
3489 | unsigned int i, cid; | 3606 | unsigned int cid; |
3490 | struct iscsi_task *aborted_task; | ||
3491 | unsigned int tag; | ||
3492 | 3607 | ||
3493 | cid = beiscsi_conn->beiscsi_conn_cid; | 3608 | cid = beiscsi_conn->beiscsi_conn_cid; |
3494 | pwrb = io_task->pwrb_handle->pwrb; | 3609 | pwrb = io_task->pwrb_handle->pwrb; |
@@ -3499,6 +3614,7 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3499 | io_task->pwrb_handle->wrb_index); | 3614 | io_task->pwrb_handle->wrb_index); |
3500 | AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, | 3615 | AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, |
3501 | io_task->psgl_handle->sgl_index); | 3616 | io_task->psgl_handle->sgl_index); |
3617 | |||
3502 | switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { | 3618 | switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { |
3503 | case ISCSI_OP_LOGIN: | 3619 | case ISCSI_OP_LOGIN: |
3504 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3620 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
@@ -3523,33 +3639,6 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3523 | hwi_write_buffer(pwrb, task); | 3639 | hwi_write_buffer(pwrb, task); |
3524 | break; | 3640 | break; |
3525 | case ISCSI_OP_SCSI_TMFUNC: | 3641 | case ISCSI_OP_SCSI_TMFUNC: |
3526 | session = conn->session; | ||
3527 | i = ((struct iscsi_tm *)task->hdr)->rtt; | ||
3528 | phwi_ctrlr = phba->phwi_ctrlr; | ||
3529 | pwrb_context = &phwi_ctrlr->wrb_context[cid - | ||
3530 | phba->fw_config.iscsi_cid_start]; | ||
3531 | pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i) | ||
3532 | >> 16]; | ||
3533 | aborted_task = pwrb_handle->pio_handle; | ||
3534 | if (!aborted_task) | ||
3535 | return 0; | ||
3536 | |||
3537 | aborted_io_task = aborted_task->dd_data; | ||
3538 | if (!aborted_io_task->scsi_cmnd) | ||
3539 | return 0; | ||
3540 | |||
3541 | tag = mgmt_invalidate_icds(phba, | ||
3542 | aborted_io_task->psgl_handle->sgl_index, | ||
3543 | cid); | ||
3544 | if (!tag) { | ||
3545 | shost_printk(KERN_WARNING, phba->shost, | ||
3546 | "mgmt_invalidate_icds could not be" | ||
3547 | " submitted\n"); | ||
3548 | } else { | ||
3549 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
3550 | phba->ctrl.mcc_numtag[tag]); | ||
3551 | free_mcc_tag(&phba->ctrl, tag); | ||
3552 | } | ||
3553 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3642 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3554 | INI_TMF_CMD); | 3643 | INI_TMF_CMD); |
3555 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 3644 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); |
@@ -3558,7 +3647,7 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3558 | case ISCSI_OP_LOGOUT: | 3647 | case ISCSI_OP_LOGOUT: |
3559 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); | 3648 | AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); |
3560 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, | 3649 | AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, |
3561 | HWH_TYPE_LOGOUT); | 3650 | HWH_TYPE_LOGOUT); |
3562 | hwi_write_buffer(pwrb, task); | 3651 | hwi_write_buffer(pwrb, task); |
3563 | break; | 3652 | break; |
3564 | 3653 | ||
@@ -3584,17 +3673,12 @@ static int beiscsi_mtask(struct iscsi_task *task) | |||
3584 | 3673 | ||
3585 | static int beiscsi_task_xmit(struct iscsi_task *task) | 3674 | static int beiscsi_task_xmit(struct iscsi_task *task) |
3586 | { | 3675 | { |
3587 | struct iscsi_conn *conn = task->conn; | ||
3588 | struct beiscsi_io_task *io_task = task->dd_data; | 3676 | struct beiscsi_io_task *io_task = task->dd_data; |
3589 | struct scsi_cmnd *sc = task->sc; | 3677 | struct scsi_cmnd *sc = task->sc; |
3590 | struct beiscsi_conn *beiscsi_conn = conn->dd_data; | ||
3591 | struct scatterlist *sg; | 3678 | struct scatterlist *sg; |
3592 | int num_sg; | 3679 | int num_sg; |
3593 | unsigned int writedir = 0, xferlen = 0; | 3680 | unsigned int writedir = 0, xferlen = 0; |
3594 | 3681 | ||
3595 | SE_DEBUG(DBG_LVL_4, "\n cid=%d In beiscsi_task_xmit task=%p conn=%p \t" | ||
3596 | "beiscsi_conn=%p \n", beiscsi_conn->beiscsi_conn_cid, | ||
3597 | task, conn, beiscsi_conn); | ||
3598 | if (!sc) | 3682 | if (!sc) |
3599 | return beiscsi_mtask(task); | 3683 | return beiscsi_mtask(task); |
3600 | 3684 | ||
@@ -3699,7 +3783,6 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
3699 | " Failed in beiscsi_hba_alloc \n"); | 3783 | " Failed in beiscsi_hba_alloc \n"); |
3700 | goto disable_pci; | 3784 | goto disable_pci; |
3701 | } | 3785 | } |
3702 | SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba); | ||
3703 | 3786 | ||
3704 | switch (pcidev->device) { | 3787 | switch (pcidev->device) { |
3705 | case BE_DEVICE_ID1: | 3788 | case BE_DEVICE_ID1: |
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index c53a80ab796c..87ec21280a37 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h | |||
@@ -257,6 +257,11 @@ struct hba_parameters { | |||
257 | unsigned int num_sge; | 257 | unsigned int num_sge; |
258 | }; | 258 | }; |
259 | 259 | ||
260 | struct invalidate_command_table { | ||
261 | unsigned short icd; | ||
262 | unsigned short cid; | ||
263 | } __packed; | ||
264 | |||
260 | struct beiscsi_hba { | 265 | struct beiscsi_hba { |
261 | struct hba_parameters params; | 266 | struct hba_parameters params; |
262 | struct hwi_controller *phwi_ctrlr; | 267 | struct hwi_controller *phwi_ctrlr; |
@@ -329,6 +334,8 @@ struct beiscsi_hba { | |||
329 | struct work_struct work_cqs; /* The work being queued */ | 334 | struct work_struct work_cqs; /* The work being queued */ |
330 | struct be_ctrl_info ctrl; | 335 | struct be_ctrl_info ctrl; |
331 | unsigned int generation; | 336 | unsigned int generation; |
337 | struct invalidate_command_table inv_tbl[128]; | ||
338 | |||
332 | }; | 339 | }; |
333 | 340 | ||
334 | struct beiscsi_session { | 341 | struct beiscsi_session { |
@@ -491,8 +498,6 @@ struct hwi_async_entry { | |||
491 | struct list_head data_busy_list; | 498 | struct list_head data_busy_list; |
492 | }; | 499 | }; |
493 | 500 | ||
494 | #define BE_MIN_ASYNC_ENTRIES 128 | ||
495 | |||
496 | struct hwi_async_pdu_context { | 501 | struct hwi_async_pdu_context { |
497 | struct { | 502 | struct { |
498 | struct be_bus_address pa_base; | 503 | struct be_bus_address pa_base; |
@@ -533,7 +538,7 @@ struct hwi_async_pdu_context { | |||
533 | * This is a varying size list! Do not add anything | 538 | * This is a varying size list! Do not add anything |
534 | * after this entry!! | 539 | * after this entry!! |
535 | */ | 540 | */ |
536 | struct hwi_async_entry async_entry[BE_MIN_ASYNC_ENTRIES]; | 541 | struct hwi_async_entry async_entry[BE2_MAX_SESSIONS * 2]; |
537 | }; | 542 | }; |
538 | 543 | ||
539 | #define PDUCQE_CODE_MASK 0x0000003F | 544 | #define PDUCQE_CODE_MASK 0x0000003F |
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 317bcd042ced..72617b650a7e 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c | |||
@@ -145,14 +145,15 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) | |||
145 | } | 145 | } |
146 | 146 | ||
147 | unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, | 147 | unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, |
148 | unsigned int icd, unsigned int cid) | 148 | struct invalidate_command_table *inv_tbl, |
149 | unsigned int num_invalidate, unsigned int cid) | ||
149 | { | 150 | { |
150 | struct be_dma_mem nonemb_cmd; | 151 | struct be_dma_mem nonemb_cmd; |
151 | struct be_ctrl_info *ctrl = &phba->ctrl; | 152 | struct be_ctrl_info *ctrl = &phba->ctrl; |
152 | struct be_mcc_wrb *wrb; | 153 | struct be_mcc_wrb *wrb; |
153 | struct be_sge *sge; | 154 | struct be_sge *sge; |
154 | struct invalidate_commands_params_in *req; | 155 | struct invalidate_commands_params_in *req; |
155 | unsigned int tag = 0; | 156 | unsigned int i, tag = 0; |
156 | 157 | ||
157 | spin_lock(&ctrl->mbox_lock); | 158 | spin_lock(&ctrl->mbox_lock); |
158 | tag = alloc_mcc_tag(phba); | 159 | tag = alloc_mcc_tag(phba); |
@@ -183,9 +184,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, | |||
183 | sizeof(*req)); | 184 | sizeof(*req)); |
184 | req->ref_handle = 0; | 185 | req->ref_handle = 0; |
185 | req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE; | 186 | req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE; |
186 | req->icd_count = 0; | 187 | for (i = 0; i < num_invalidate; i++) { |
187 | req->table[req->icd_count].icd = icd; | 188 | req->table[i].icd = inv_tbl->icd; |
188 | req->table[req->icd_count].cid = cid; | 189 | req->table[i].cid = inv_tbl->cid; |
190 | req->icd_count++; | ||
191 | inv_tbl++; | ||
192 | } | ||
189 | sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma)); | 193 | sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma)); |
190 | sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); | 194 | sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); |
191 | sge->len = cpu_to_le32(nonemb_cmd.size); | 195 | sge->len = cpu_to_le32(nonemb_cmd.size); |
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index ecead6a5aa56..3d316b82feb1 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h | |||
@@ -94,7 +94,8 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, | |||
94 | unsigned short cid, | 94 | unsigned short cid, |
95 | unsigned int upload_flag); | 95 | unsigned int upload_flag); |
96 | unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, | 96 | unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, |
97 | unsigned int icd, unsigned int cid); | 97 | struct invalidate_command_table *inv_tbl, |
98 | unsigned int num_invalidate, unsigned int cid); | ||
98 | 99 | ||
99 | struct iscsi_invalidate_connection_params_in { | 100 | struct iscsi_invalidate_connection_params_in { |
100 | struct be_cmd_req_hdr hdr; | 101 | struct be_cmd_req_hdr hdr; |
@@ -116,11 +117,6 @@ union iscsi_invalidate_connection_params { | |||
116 | struct iscsi_invalidate_connection_params_out response; | 117 | struct iscsi_invalidate_connection_params_out response; |
117 | } __packed; | 118 | } __packed; |
118 | 119 | ||
119 | struct invalidate_command_table { | ||
120 | unsigned short icd; | ||
121 | unsigned short cid; | ||
122 | } __packed; | ||
123 | |||
124 | struct invalidate_commands_params_in { | 120 | struct invalidate_commands_params_in { |
125 | struct be_cmd_req_hdr hdr; | 121 | struct be_cmd_req_hdr hdr; |
126 | unsigned int ref_handle; | 122 | unsigned int ref_handle; |
diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile index 1d6009490d1c..17e06cae71b2 100644 --- a/drivers/scsi/bfa/Makefile +++ b/drivers/scsi/bfa/Makefile | |||
@@ -2,14 +2,14 @@ obj-$(CONFIG_SCSI_BFA_FC) := bfa.o | |||
2 | 2 | ||
3 | bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o | 3 | bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o |
4 | 4 | ||
5 | bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o | 5 | bfa-y += bfa_core.o bfa_ioc.o bfa_ioc_ct.o bfa_ioc_cb.o bfa_iocfc.o bfa_fcxp.o |
6 | bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o | 6 | bfa-y += bfa_lps.o bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o |
7 | bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o | 7 | bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o |
8 | bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o | 8 | bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o |
9 | bfa-y += bfa_csdebug.o bfa_sm.o plog.o | 9 | bfa-y += bfa_csdebug.o bfa_sm.o plog.o |
10 | 10 | ||
11 | bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o | 11 | bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o |
12 | bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o | 12 | bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o |
13 | bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o | 13 | bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o |
14 | 14 | ||
15 | ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna | 15 | ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna -DBFA_PERF_BUILD |
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index 44e2d1155c51..0c08e185a766 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c | |||
@@ -385,6 +385,15 @@ bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen) | |||
385 | } | 385 | } |
386 | 386 | ||
387 | /** | 387 | /** |
388 | * Clear the saved firmware trace information of an IOC. | ||
389 | */ | ||
390 | void | ||
391 | bfa_debug_fwsave_clear(struct bfa_s *bfa) | ||
392 | { | ||
393 | bfa_ioc_debug_fwsave_clear(&bfa->ioc); | ||
394 | } | ||
395 | |||
396 | /** | ||
388 | * Fetch firmware trace data. | 397 | * Fetch firmware trace data. |
389 | * | 398 | * |
390 | * @param[in] bfa BFA instance | 399 | * @param[in] bfa BFA instance |
@@ -399,4 +408,14 @@ bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen) | |||
399 | { | 408 | { |
400 | return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen); | 409 | return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen); |
401 | } | 410 | } |
411 | |||
412 | /** | ||
413 | * Reset hw semaphore & usage cnt regs and initialize. | ||
414 | */ | ||
415 | void | ||
416 | bfa_chip_reset(struct bfa_s *bfa) | ||
417 | { | ||
418 | bfa_ioc_ownership_reset(&bfa->ioc); | ||
419 | bfa_ioc_pll_init(&bfa->ioc); | ||
420 | } | ||
402 | #endif | 421 | #endif |
diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c index aef648b55dfc..c589488db0c1 100644 --- a/drivers/scsi/bfa/bfa_fcport.c +++ b/drivers/scsi/bfa/bfa_fcport.c | |||
@@ -23,40 +23,33 @@ | |||
23 | #include <cs/bfa_plog.h> | 23 | #include <cs/bfa_plog.h> |
24 | #include <aen/bfa_aen_port.h> | 24 | #include <aen/bfa_aen_port.h> |
25 | 25 | ||
26 | BFA_TRC_FILE(HAL, PPORT); | 26 | BFA_TRC_FILE(HAL, FCPORT); |
27 | BFA_MODULE(pport); | 27 | BFA_MODULE(fcport); |
28 | |||
29 | #define bfa_pport_callback(__pport, __event) do { \ | ||
30 | if ((__pport)->bfa->fcs) { \ | ||
31 | (__pport)->event_cbfn((__pport)->event_cbarg, (__event)); \ | ||
32 | } else { \ | ||
33 | (__pport)->hcb_event = (__event); \ | ||
34 | bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe, \ | ||
35 | __bfa_cb_port_event, (__pport)); \ | ||
36 | } \ | ||
37 | } while (0) | ||
38 | 28 | ||
39 | /* | 29 | /* |
40 | * The port is considered disabled if corresponding physical port or IOC are | 30 | * The port is considered disabled if corresponding physical port or IOC are |
41 | * disabled explicitly | 31 | * disabled explicitly |
42 | */ | 32 | */ |
43 | #define BFA_PORT_IS_DISABLED(bfa) \ | 33 | #define BFA_PORT_IS_DISABLED(bfa) \ |
44 | ((bfa_pport_is_disabled(bfa) == BFA_TRUE) || \ | 34 | ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \ |
45 | (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE)) | 35 | (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE)) |
46 | 36 | ||
47 | /* | 37 | /* |
48 | * forward declarations | 38 | * forward declarations |
49 | */ | 39 | */ |
50 | static bfa_boolean_t bfa_pport_send_enable(struct bfa_pport_s *port); | 40 | static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport); |
51 | static bfa_boolean_t bfa_pport_send_disable(struct bfa_pport_s *port); | 41 | static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport); |
52 | static void bfa_pport_update_linkinfo(struct bfa_pport_s *pport); | 42 | static void bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport); |
53 | static void bfa_pport_reset_linkinfo(struct bfa_pport_s *pport); | 43 | static void bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport); |
54 | static void bfa_pport_set_wwns(struct bfa_pport_s *port); | 44 | static void bfa_fcport_set_wwns(struct bfa_fcport_s *fcport); |
55 | static void __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete); | 45 | static void __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete); |
56 | static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete); | 46 | static void bfa_fcport_callback(struct bfa_fcport_s *fcport, |
57 | static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete); | 47 | enum bfa_pport_linkstate event); |
58 | static void bfa_port_stats_timeout(void *cbarg); | 48 | static void bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, |
59 | static void bfa_port_stats_clr_timeout(void *cbarg); | 49 | enum bfa_pport_linkstate event); |
50 | static void __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete); | ||
51 | static void bfa_fcport_stats_get_timeout(void *cbarg); | ||
52 | static void bfa_fcport_stats_clr_timeout(void *cbarg); | ||
60 | 53 | ||
61 | /** | 54 | /** |
62 | * bfa_pport_private | 55 | * bfa_pport_private |
@@ -65,111 +58,114 @@ static void bfa_port_stats_clr_timeout(void *cbarg); | |||
65 | /** | 58 | /** |
66 | * BFA port state machine events | 59 | * BFA port state machine events |
67 | */ | 60 | */ |
68 | enum bfa_pport_sm_event { | 61 | enum bfa_fcport_sm_event { |
69 | BFA_PPORT_SM_START = 1, /* start port state machine */ | 62 | BFA_FCPORT_SM_START = 1, /* start port state machine */ |
70 | BFA_PPORT_SM_STOP = 2, /* stop port state machine */ | 63 | BFA_FCPORT_SM_STOP = 2, /* stop port state machine */ |
71 | BFA_PPORT_SM_ENABLE = 3, /* enable port */ | 64 | BFA_FCPORT_SM_ENABLE = 3, /* enable port */ |
72 | BFA_PPORT_SM_DISABLE = 4, /* disable port state machine */ | 65 | BFA_FCPORT_SM_DISABLE = 4, /* disable port state machine */ |
73 | BFA_PPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */ | 66 | BFA_FCPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */ |
74 | BFA_PPORT_SM_LINKUP = 6, /* firmware linkup event */ | 67 | BFA_FCPORT_SM_LINKUP = 6, /* firmware linkup event */ |
75 | BFA_PPORT_SM_LINKDOWN = 7, /* firmware linkup down */ | 68 | BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */ |
76 | BFA_PPORT_SM_QRESUME = 8, /* CQ space available */ | 69 | BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */ |
77 | BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */ | 70 | BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */ |
78 | }; | 71 | }; |
79 | 72 | ||
80 | static void bfa_pport_sm_uninit(struct bfa_pport_s *pport, | 73 | /** |
81 | enum bfa_pport_sm_event event); | 74 | * BFA port link notification state machine events |
82 | static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, | 75 | */ |
83 | enum bfa_pport_sm_event event); | 76 | |
84 | static void bfa_pport_sm_enabling(struct bfa_pport_s *pport, | 77 | enum bfa_fcport_ln_sm_event { |
85 | enum bfa_pport_sm_event event); | 78 | BFA_FCPORT_LN_SM_LINKUP = 1, /* linkup event */ |
86 | static void bfa_pport_sm_linkdown(struct bfa_pport_s *pport, | 79 | BFA_FCPORT_LN_SM_LINKDOWN = 2, /* linkdown event */ |
87 | enum bfa_pport_sm_event event); | 80 | BFA_FCPORT_LN_SM_NOTIFICATION = 3 /* done notification */ |
88 | static void bfa_pport_sm_linkup(struct bfa_pport_s *pport, | 81 | }; |
89 | enum bfa_pport_sm_event event); | 82 | |
90 | static void bfa_pport_sm_disabling(struct bfa_pport_s *pport, | 83 | static void bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport, |
91 | enum bfa_pport_sm_event event); | 84 | enum bfa_fcport_sm_event event); |
92 | static void bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport, | 85 | static void bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, |
93 | enum bfa_pport_sm_event event); | 86 | enum bfa_fcport_sm_event event); |
94 | static void bfa_pport_sm_disabled(struct bfa_pport_s *pport, | 87 | static void bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, |
95 | enum bfa_pport_sm_event event); | 88 | enum bfa_fcport_sm_event event); |
96 | static void bfa_pport_sm_stopped(struct bfa_pport_s *pport, | 89 | static void bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, |
97 | enum bfa_pport_sm_event event); | 90 | enum bfa_fcport_sm_event event); |
98 | static void bfa_pport_sm_iocdown(struct bfa_pport_s *pport, | 91 | static void bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, |
99 | enum bfa_pport_sm_event event); | 92 | enum bfa_fcport_sm_event event); |
100 | static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport, | 93 | static void bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, |
101 | enum bfa_pport_sm_event event); | 94 | enum bfa_fcport_sm_event event); |
95 | static void bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, | ||
96 | enum bfa_fcport_sm_event event); | ||
97 | static void bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, | ||
98 | enum bfa_fcport_sm_event event); | ||
99 | static void bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport, | ||
100 | enum bfa_fcport_sm_event event); | ||
101 | static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, | ||
102 | enum bfa_fcport_sm_event event); | ||
103 | static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, | ||
104 | enum bfa_fcport_sm_event event); | ||
105 | |||
106 | static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, | ||
107 | enum bfa_fcport_ln_sm_event event); | ||
108 | static void bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln, | ||
109 | enum bfa_fcport_ln_sm_event event); | ||
110 | static void bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln, | ||
111 | enum bfa_fcport_ln_sm_event event); | ||
112 | static void bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln, | ||
113 | enum bfa_fcport_ln_sm_event event); | ||
114 | static void bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln, | ||
115 | enum bfa_fcport_ln_sm_event event); | ||
116 | static void bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln, | ||
117 | enum bfa_fcport_ln_sm_event event); | ||
118 | static void bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln, | ||
119 | enum bfa_fcport_ln_sm_event event); | ||
102 | 120 | ||
103 | static struct bfa_sm_table_s hal_pport_sm_table[] = { | 121 | static struct bfa_sm_table_s hal_pport_sm_table[] = { |
104 | {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT}, | 122 | {BFA_SM(bfa_fcport_sm_uninit), BFA_PPORT_ST_UNINIT}, |
105 | {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT}, | 123 | {BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT}, |
106 | {BFA_SM(bfa_pport_sm_enabling), BFA_PPORT_ST_ENABLING}, | 124 | {BFA_SM(bfa_fcport_sm_enabling), BFA_PPORT_ST_ENABLING}, |
107 | {BFA_SM(bfa_pport_sm_linkdown), BFA_PPORT_ST_LINKDOWN}, | 125 | {BFA_SM(bfa_fcport_sm_linkdown), BFA_PPORT_ST_LINKDOWN}, |
108 | {BFA_SM(bfa_pport_sm_linkup), BFA_PPORT_ST_LINKUP}, | 126 | {BFA_SM(bfa_fcport_sm_linkup), BFA_PPORT_ST_LINKUP}, |
109 | {BFA_SM(bfa_pport_sm_disabling_qwait), | 127 | {BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PPORT_ST_DISABLING_QWAIT}, |
110 | BFA_PPORT_ST_DISABLING_QWAIT}, | 128 | {BFA_SM(bfa_fcport_sm_disabling), BFA_PPORT_ST_DISABLING}, |
111 | {BFA_SM(bfa_pport_sm_disabling), BFA_PPORT_ST_DISABLING}, | 129 | {BFA_SM(bfa_fcport_sm_disabled), BFA_PPORT_ST_DISABLED}, |
112 | {BFA_SM(bfa_pport_sm_disabled), BFA_PPORT_ST_DISABLED}, | 130 | {BFA_SM(bfa_fcport_sm_stopped), BFA_PPORT_ST_STOPPED}, |
113 | {BFA_SM(bfa_pport_sm_stopped), BFA_PPORT_ST_STOPPED}, | 131 | {BFA_SM(bfa_fcport_sm_iocdown), BFA_PPORT_ST_IOCDOWN}, |
114 | {BFA_SM(bfa_pport_sm_iocdown), BFA_PPORT_ST_IOCDOWN}, | 132 | {BFA_SM(bfa_fcport_sm_iocfail), BFA_PPORT_ST_IOCDOWN}, |
115 | {BFA_SM(bfa_pport_sm_iocfail), BFA_PPORT_ST_IOCDOWN}, | ||
116 | }; | 133 | }; |
117 | 134 | ||
118 | static void | 135 | static void |
119 | bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event) | 136 | bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event) |
120 | { | 137 | { |
121 | union bfa_aen_data_u aen_data; | 138 | union bfa_aen_data_u aen_data; |
122 | struct bfa_log_mod_s *logmod = pport->bfa->logm; | 139 | struct bfa_log_mod_s *logmod = fcport->bfa->logm; |
123 | wwn_t pwwn = pport->pwwn; | 140 | wwn_t pwwn = fcport->pwwn; |
124 | char pwwn_ptr[BFA_STRING_32]; | 141 | char pwwn_ptr[BFA_STRING_32]; |
125 | struct bfa_ioc_attr_s ioc_attr; | ||
126 | 142 | ||
143 | memset(&aen_data, 0, sizeof(aen_data)); | ||
127 | wwn2str(pwwn_ptr, pwwn); | 144 | wwn2str(pwwn_ptr, pwwn); |
128 | switch (event) { | 145 | bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event), pwwn_ptr); |
129 | case BFA_PORT_AEN_ONLINE: | ||
130 | bfa_log(logmod, BFA_AEN_PORT_ONLINE, pwwn_ptr); | ||
131 | break; | ||
132 | case BFA_PORT_AEN_OFFLINE: | ||
133 | bfa_log(logmod, BFA_AEN_PORT_OFFLINE, pwwn_ptr); | ||
134 | break; | ||
135 | case BFA_PORT_AEN_ENABLE: | ||
136 | bfa_log(logmod, BFA_AEN_PORT_ENABLE, pwwn_ptr); | ||
137 | break; | ||
138 | case BFA_PORT_AEN_DISABLE: | ||
139 | bfa_log(logmod, BFA_AEN_PORT_DISABLE, pwwn_ptr); | ||
140 | break; | ||
141 | case BFA_PORT_AEN_DISCONNECT: | ||
142 | bfa_log(logmod, BFA_AEN_PORT_DISCONNECT, pwwn_ptr); | ||
143 | break; | ||
144 | case BFA_PORT_AEN_QOS_NEG: | ||
145 | bfa_log(logmod, BFA_AEN_PORT_QOS_NEG, pwwn_ptr); | ||
146 | break; | ||
147 | default: | ||
148 | break; | ||
149 | } | ||
150 | 146 | ||
151 | bfa_ioc_get_attr(&pport->bfa->ioc, &ioc_attr); | 147 | aen_data.port.ioc_type = bfa_get_type(fcport->bfa); |
152 | aen_data.port.ioc_type = ioc_attr.ioc_type; | ||
153 | aen_data.port.pwwn = pwwn; | 148 | aen_data.port.pwwn = pwwn; |
154 | } | 149 | } |
155 | 150 | ||
156 | static void | 151 | static void |
157 | bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | 152 | bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport, |
153 | enum bfa_fcport_sm_event event) | ||
158 | { | 154 | { |
159 | bfa_trc(pport->bfa, event); | 155 | bfa_trc(fcport->bfa, event); |
160 | 156 | ||
161 | switch (event) { | 157 | switch (event) { |
162 | case BFA_PPORT_SM_START: | 158 | case BFA_FCPORT_SM_START: |
163 | /** | 159 | /** |
164 | * Start event after IOC is configured and BFA is started. | 160 | * Start event after IOC is configured and BFA is started. |
165 | */ | 161 | */ |
166 | if (bfa_pport_send_enable(pport)) | 162 | if (bfa_fcport_send_enable(fcport)) |
167 | bfa_sm_set_state(pport, bfa_pport_sm_enabling); | 163 | bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); |
168 | else | 164 | else |
169 | bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); | 165 | bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait); |
170 | break; | 166 | break; |
171 | 167 | ||
172 | case BFA_PPORT_SM_ENABLE: | 168 | case BFA_FCPORT_SM_ENABLE: |
173 | /** | 169 | /** |
174 | * Port is persistently configured to be in enabled state. Do | 170 | * Port is persistently configured to be in enabled state. Do |
175 | * not change state. Port enabling is done when START event is | 171 | * not change state. Port enabling is done when START event is |
@@ -177,389 +173,412 @@ bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | |||
177 | */ | 173 | */ |
178 | break; | 174 | break; |
179 | 175 | ||
180 | case BFA_PPORT_SM_DISABLE: | 176 | case BFA_FCPORT_SM_DISABLE: |
181 | /** | 177 | /** |
182 | * If a port is persistently configured to be disabled, the | 178 | * If a port is persistently configured to be disabled, the |
183 | * first event will a port disable request. | 179 | * first event will a port disable request. |
184 | */ | 180 | */ |
185 | bfa_sm_set_state(pport, bfa_pport_sm_disabled); | 181 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); |
186 | break; | 182 | break; |
187 | 183 | ||
188 | case BFA_PPORT_SM_HWFAIL: | 184 | case BFA_FCPORT_SM_HWFAIL: |
189 | bfa_sm_set_state(pport, bfa_pport_sm_iocdown); | 185 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); |
190 | break; | 186 | break; |
191 | 187 | ||
192 | default: | 188 | default: |
193 | bfa_sm_fault(pport->bfa, event); | 189 | bfa_sm_fault(fcport->bfa, event); |
194 | } | 190 | } |
195 | } | 191 | } |
196 | 192 | ||
197 | static void | 193 | static void |
198 | bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, | 194 | bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, |
199 | enum bfa_pport_sm_event event) | 195 | enum bfa_fcport_sm_event event) |
200 | { | 196 | { |
201 | bfa_trc(pport->bfa, event); | 197 | bfa_trc(fcport->bfa, event); |
202 | 198 | ||
203 | switch (event) { | 199 | switch (event) { |
204 | case BFA_PPORT_SM_QRESUME: | 200 | case BFA_FCPORT_SM_QRESUME: |
205 | bfa_sm_set_state(pport, bfa_pport_sm_enabling); | 201 | bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); |
206 | bfa_pport_send_enable(pport); | 202 | bfa_fcport_send_enable(fcport); |
207 | break; | 203 | break; |
208 | 204 | ||
209 | case BFA_PPORT_SM_STOP: | 205 | case BFA_FCPORT_SM_STOP: |
210 | bfa_reqq_wcancel(&pport->reqq_wait); | 206 | bfa_reqq_wcancel(&fcport->reqq_wait); |
211 | bfa_sm_set_state(pport, bfa_pport_sm_stopped); | 207 | bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); |
212 | break; | 208 | break; |
213 | 209 | ||
214 | case BFA_PPORT_SM_ENABLE: | 210 | case BFA_FCPORT_SM_ENABLE: |
215 | /** | 211 | /** |
216 | * Already enable is in progress. | 212 | * Already enable is in progress. |
217 | */ | 213 | */ |
218 | break; | 214 | break; |
219 | 215 | ||
220 | case BFA_PPORT_SM_DISABLE: | 216 | case BFA_FCPORT_SM_DISABLE: |
221 | /** | 217 | /** |
222 | * Just send disable request to firmware when room becomes | 218 | * Just send disable request to firmware when room becomes |
223 | * available in request queue. | 219 | * available in request queue. |
224 | */ | 220 | */ |
225 | bfa_sm_set_state(pport, bfa_pport_sm_disabled); | 221 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); |
226 | bfa_reqq_wcancel(&pport->reqq_wait); | 222 | bfa_reqq_wcancel(&fcport->reqq_wait); |
227 | bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, | 223 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
228 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); | 224 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); |
229 | bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); | 225 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); |
230 | break; | 226 | break; |
231 | 227 | ||
232 | case BFA_PPORT_SM_LINKUP: | 228 | case BFA_FCPORT_SM_LINKUP: |
233 | case BFA_PPORT_SM_LINKDOWN: | 229 | case BFA_FCPORT_SM_LINKDOWN: |
234 | /** | 230 | /** |
235 | * Possible to get link events when doing back-to-back | 231 | * Possible to get link events when doing back-to-back |
236 | * enable/disables. | 232 | * enable/disables. |
237 | */ | 233 | */ |
238 | break; | 234 | break; |
239 | 235 | ||
240 | case BFA_PPORT_SM_HWFAIL: | 236 | case BFA_FCPORT_SM_HWFAIL: |
241 | bfa_reqq_wcancel(&pport->reqq_wait); | 237 | bfa_reqq_wcancel(&fcport->reqq_wait); |
242 | bfa_sm_set_state(pport, bfa_pport_sm_iocdown); | 238 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); |
243 | break; | 239 | break; |
244 | 240 | ||
245 | default: | 241 | default: |
246 | bfa_sm_fault(pport->bfa, event); | 242 | bfa_sm_fault(fcport->bfa, event); |
247 | } | 243 | } |
248 | } | 244 | } |
249 | 245 | ||
250 | static void | 246 | static void |
251 | bfa_pport_sm_enabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | 247 | bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, |
248 | enum bfa_fcport_sm_event event) | ||
252 | { | 249 | { |
253 | bfa_trc(pport->bfa, event); | 250 | bfa_trc(fcport->bfa, event); |
254 | 251 | ||
255 | switch (event) { | 252 | switch (event) { |
256 | case BFA_PPORT_SM_FWRSP: | 253 | case BFA_FCPORT_SM_FWRSP: |
257 | case BFA_PPORT_SM_LINKDOWN: | 254 | case BFA_FCPORT_SM_LINKDOWN: |
258 | bfa_sm_set_state(pport, bfa_pport_sm_linkdown); | 255 | bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown); |
259 | break; | 256 | break; |
260 | 257 | ||
261 | case BFA_PPORT_SM_LINKUP: | 258 | case BFA_FCPORT_SM_LINKUP: |
262 | bfa_pport_update_linkinfo(pport); | 259 | bfa_fcport_update_linkinfo(fcport); |
263 | bfa_sm_set_state(pport, bfa_pport_sm_linkup); | 260 | bfa_sm_set_state(fcport, bfa_fcport_sm_linkup); |
264 | 261 | ||
265 | bfa_assert(pport->event_cbfn); | 262 | bfa_assert(fcport->event_cbfn); |
266 | bfa_pport_callback(pport, BFA_PPORT_LINKUP); | 263 | bfa_fcport_callback(fcport, BFA_PPORT_LINKUP); |
267 | break; | 264 | break; |
268 | 265 | ||
269 | case BFA_PPORT_SM_ENABLE: | 266 | case BFA_FCPORT_SM_ENABLE: |
270 | /** | 267 | /** |
271 | * Already being enabled. | 268 | * Already being enabled. |
272 | */ | 269 | */ |
273 | break; | 270 | break; |
274 | 271 | ||
275 | case BFA_PPORT_SM_DISABLE: | 272 | case BFA_FCPORT_SM_DISABLE: |
276 | if (bfa_pport_send_disable(pport)) | 273 | if (bfa_fcport_send_disable(fcport)) |
277 | bfa_sm_set_state(pport, bfa_pport_sm_disabling); | 274 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); |
278 | else | 275 | else |
279 | bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait); | 276 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); |
280 | 277 | ||
281 | bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, | 278 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
282 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); | 279 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); |
283 | bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); | 280 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); |
284 | break; | 281 | break; |
285 | 282 | ||
286 | case BFA_PPORT_SM_STOP: | 283 | case BFA_FCPORT_SM_STOP: |
287 | bfa_sm_set_state(pport, bfa_pport_sm_stopped); | 284 | bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); |
288 | break; | 285 | break; |
289 | 286 | ||
290 | case BFA_PPORT_SM_HWFAIL: | 287 | case BFA_FCPORT_SM_HWFAIL: |
291 | bfa_sm_set_state(pport, bfa_pport_sm_iocdown); | 288 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); |
292 | break; | 289 | break; |
293 | 290 | ||
294 | default: | 291 | default: |
295 | bfa_sm_fault(pport->bfa, event); | 292 | bfa_sm_fault(fcport->bfa, event); |
296 | } | 293 | } |
297 | } | 294 | } |
298 | 295 | ||
299 | static void | 296 | static void |
300 | bfa_pport_sm_linkdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | 297 | bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, |
298 | enum bfa_fcport_sm_event event) | ||
301 | { | 299 | { |
302 | bfa_trc(pport->bfa, event); | 300 | struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; |
301 | bfa_trc(fcport->bfa, event); | ||
303 | 302 | ||
304 | switch (event) { | 303 | switch (event) { |
305 | case BFA_PPORT_SM_LINKUP: | 304 | case BFA_FCPORT_SM_LINKUP: |
306 | bfa_pport_update_linkinfo(pport); | 305 | bfa_fcport_update_linkinfo(fcport); |
307 | bfa_sm_set_state(pport, bfa_pport_sm_linkup); | 306 | bfa_sm_set_state(fcport, bfa_fcport_sm_linkup); |
308 | bfa_assert(pport->event_cbfn); | 307 | bfa_assert(fcport->event_cbfn); |
309 | bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, | 308 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
310 | BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup"); | 309 | BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup"); |
311 | bfa_pport_callback(pport, BFA_PPORT_LINKUP); | 310 | |
312 | bfa_pport_aen_post(pport, BFA_PORT_AEN_ONLINE); | 311 | if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { |
312 | |||
313 | bfa_trc(fcport->bfa, pevent->link_state.fcf.fipenabled); | ||
314 | bfa_trc(fcport->bfa, pevent->link_state.fcf.fipfailed); | ||
315 | |||
316 | if (pevent->link_state.fcf.fipfailed) | ||
317 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, | ||
318 | BFA_PL_EID_FIP_FCF_DISC, 0, | ||
319 | "FIP FCF Discovery Failed"); | ||
320 | else | ||
321 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, | ||
322 | BFA_PL_EID_FIP_FCF_DISC, 0, | ||
323 | "FIP FCF Discovered"); | ||
324 | } | ||
325 | |||
326 | bfa_fcport_callback(fcport, BFA_PPORT_LINKUP); | ||
327 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE); | ||
313 | /** | 328 | /** |
314 | * If QoS is enabled and it is not online, | 329 | * If QoS is enabled and it is not online, |
315 | * Send a separate event. | 330 | * Send a separate event. |
316 | */ | 331 | */ |
317 | if ((pport->cfg.qos_enabled) | 332 | if ((fcport->cfg.qos_enabled) |
318 | && (bfa_os_ntohl(pport->qos_attr.state) != BFA_QOS_ONLINE)) | 333 | && (bfa_os_ntohl(fcport->qos_attr.state) != BFA_QOS_ONLINE)) |
319 | bfa_pport_aen_post(pport, BFA_PORT_AEN_QOS_NEG); | 334 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG); |
320 | 335 | ||
321 | break; | 336 | break; |
322 | 337 | ||
323 | case BFA_PPORT_SM_LINKDOWN: | 338 | case BFA_FCPORT_SM_LINKDOWN: |
324 | /** | 339 | /** |
325 | * Possible to get link down event. | 340 | * Possible to get link down event. |
326 | */ | 341 | */ |
327 | break; | 342 | break; |
328 | 343 | ||
329 | case BFA_PPORT_SM_ENABLE: | 344 | case BFA_FCPORT_SM_ENABLE: |
330 | /** | 345 | /** |
331 | * Already enabled. | 346 | * Already enabled. |
332 | */ | 347 | */ |
333 | break; | 348 | break; |
334 | 349 | ||
335 | case BFA_PPORT_SM_DISABLE: | 350 | case BFA_FCPORT_SM_DISABLE: |
336 | if (bfa_pport_send_disable(pport)) | 351 | if (bfa_fcport_send_disable(fcport)) |
337 | bfa_sm_set_state(pport, bfa_pport_sm_disabling); | 352 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); |
338 | else | 353 | else |
339 | bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait); | 354 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); |
340 | 355 | ||
341 | bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, | 356 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
342 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); | 357 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); |
343 | bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); | 358 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); |
344 | break; | 359 | break; |
345 | 360 | ||
346 | case BFA_PPORT_SM_STOP: | 361 | case BFA_FCPORT_SM_STOP: |
347 | bfa_sm_set_state(pport, bfa_pport_sm_stopped); | 362 | bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); |
348 | break; | 363 | break; |
349 | 364 | ||
350 | case BFA_PPORT_SM_HWFAIL: | 365 | case BFA_FCPORT_SM_HWFAIL: |
351 | bfa_sm_set_state(pport, bfa_pport_sm_iocdown); | 366 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); |
352 | break; | 367 | break; |
353 | 368 | ||
354 | default: | 369 | default: |
355 | bfa_sm_fault(pport->bfa, event); | 370 | bfa_sm_fault(fcport->bfa, event); |
356 | } | 371 | } |
357 | } | 372 | } |
358 | 373 | ||
359 | static void | 374 | static void |
360 | bfa_pport_sm_linkup(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | 375 | bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, |
376 | enum bfa_fcport_sm_event event) | ||
361 | { | 377 | { |
362 | bfa_trc(pport->bfa, event); | 378 | bfa_trc(fcport->bfa, event); |
363 | 379 | ||
364 | switch (event) { | 380 | switch (event) { |
365 | case BFA_PPORT_SM_ENABLE: | 381 | case BFA_FCPORT_SM_ENABLE: |
366 | /** | 382 | /** |
367 | * Already enabled. | 383 | * Already enabled. |
368 | */ | 384 | */ |
369 | break; | 385 | break; |
370 | 386 | ||
371 | case BFA_PPORT_SM_DISABLE: | 387 | case BFA_FCPORT_SM_DISABLE: |
372 | if (bfa_pport_send_disable(pport)) | 388 | if (bfa_fcport_send_disable(fcport)) |
373 | bfa_sm_set_state(pport, bfa_pport_sm_disabling); | 389 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); |
374 | else | 390 | else |
375 | bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait); | 391 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); |
376 | 392 | ||
377 | bfa_pport_reset_linkinfo(pport); | 393 | bfa_fcport_reset_linkinfo(fcport); |
378 | bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); | 394 | bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN); |
379 | bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, | 395 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
380 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); | 396 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); |
381 | bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); | 397 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); |
382 | bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); | 398 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); |
383 | break; | 399 | break; |
384 | 400 | ||
385 | case BFA_PPORT_SM_LINKDOWN: | 401 | case BFA_FCPORT_SM_LINKDOWN: |
386 | bfa_sm_set_state(pport, bfa_pport_sm_linkdown); | 402 | bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown); |
387 | bfa_pport_reset_linkinfo(pport); | 403 | bfa_fcport_reset_linkinfo(fcport); |
388 | bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); | 404 | bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN); |
389 | bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, | 405 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
390 | BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); | 406 | BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); |
391 | if (BFA_PORT_IS_DISABLED(pport->bfa)) | 407 | if (BFA_PORT_IS_DISABLED(fcport->bfa)) |
392 | bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); | 408 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); |
393 | else | 409 | else |
394 | bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); | 410 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); |
395 | break; | 411 | break; |
396 | 412 | ||
397 | case BFA_PPORT_SM_STOP: | 413 | case BFA_FCPORT_SM_STOP: |
398 | bfa_sm_set_state(pport, bfa_pport_sm_stopped); | 414 | bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); |
399 | bfa_pport_reset_linkinfo(pport); | 415 | bfa_fcport_reset_linkinfo(fcport); |
400 | if (BFA_PORT_IS_DISABLED(pport->bfa)) | 416 | if (BFA_PORT_IS_DISABLED(fcport->bfa)) |
401 | bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); | 417 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); |
402 | else | 418 | else |
403 | bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); | 419 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); |
404 | break; | 420 | break; |
405 | 421 | ||
406 | case BFA_PPORT_SM_HWFAIL: | 422 | case BFA_FCPORT_SM_HWFAIL: |
407 | bfa_sm_set_state(pport, bfa_pport_sm_iocdown); | 423 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); |
408 | bfa_pport_reset_linkinfo(pport); | 424 | bfa_fcport_reset_linkinfo(fcport); |
409 | bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); | 425 | bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN); |
410 | if (BFA_PORT_IS_DISABLED(pport->bfa)) | 426 | if (BFA_PORT_IS_DISABLED(fcport->bfa)) |
411 | bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); | 427 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); |
412 | else | 428 | else |
413 | bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); | 429 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); |
414 | break; | 430 | break; |
415 | 431 | ||
416 | default: | 432 | default: |
417 | bfa_sm_fault(pport->bfa, event); | 433 | bfa_sm_fault(fcport->bfa, event); |
418 | } | 434 | } |
419 | } | 435 | } |
420 | 436 | ||
421 | static void | 437 | static void |
422 | bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport, | 438 | bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, |
423 | enum bfa_pport_sm_event event) | 439 | enum bfa_fcport_sm_event event) |
424 | { | 440 | { |
425 | bfa_trc(pport->bfa, event); | 441 | bfa_trc(fcport->bfa, event); |
426 | 442 | ||
427 | switch (event) { | 443 | switch (event) { |
428 | case BFA_PPORT_SM_QRESUME: | 444 | case BFA_FCPORT_SM_QRESUME: |
429 | bfa_sm_set_state(pport, bfa_pport_sm_disabling); | 445 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); |
430 | bfa_pport_send_disable(pport); | 446 | bfa_fcport_send_disable(fcport); |
431 | break; | 447 | break; |
432 | 448 | ||
433 | case BFA_PPORT_SM_STOP: | 449 | case BFA_FCPORT_SM_STOP: |
434 | bfa_sm_set_state(pport, bfa_pport_sm_stopped); | 450 | bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); |
435 | bfa_reqq_wcancel(&pport->reqq_wait); | 451 | bfa_reqq_wcancel(&fcport->reqq_wait); |
436 | break; | 452 | break; |
437 | 453 | ||
438 | case BFA_PPORT_SM_DISABLE: | 454 | case BFA_FCPORT_SM_DISABLE: |
439 | /** | 455 | /** |
440 | * Already being disabled. | 456 | * Already being disabled. |
441 | */ | 457 | */ |
442 | break; | 458 | break; |
443 | 459 | ||
444 | case BFA_PPORT_SM_LINKUP: | 460 | case BFA_FCPORT_SM_LINKUP: |
445 | case BFA_PPORT_SM_LINKDOWN: | 461 | case BFA_FCPORT_SM_LINKDOWN: |
446 | /** | 462 | /** |
447 | * Possible to get link events when doing back-to-back | 463 | * Possible to get link events when doing back-to-back |
448 | * enable/disables. | 464 | * enable/disables. |
449 | */ | 465 | */ |
450 | break; | 466 | break; |
451 | 467 | ||
452 | case BFA_PPORT_SM_HWFAIL: | 468 | case BFA_FCPORT_SM_HWFAIL: |
453 | bfa_sm_set_state(pport, bfa_pport_sm_iocfail); | 469 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); |
454 | bfa_reqq_wcancel(&pport->reqq_wait); | 470 | bfa_reqq_wcancel(&fcport->reqq_wait); |
455 | break; | 471 | break; |
456 | 472 | ||
457 | default: | 473 | default: |
458 | bfa_sm_fault(pport->bfa, event); | 474 | bfa_sm_fault(fcport->bfa, event); |
459 | } | 475 | } |
460 | } | 476 | } |
461 | 477 | ||
462 | static void | 478 | static void |
463 | bfa_pport_sm_disabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | 479 | bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, |
480 | enum bfa_fcport_sm_event event) | ||
464 | { | 481 | { |
465 | bfa_trc(pport->bfa, event); | 482 | bfa_trc(fcport->bfa, event); |
466 | 483 | ||
467 | switch (event) { | 484 | switch (event) { |
468 | case BFA_PPORT_SM_FWRSP: | 485 | case BFA_FCPORT_SM_FWRSP: |
469 | bfa_sm_set_state(pport, bfa_pport_sm_disabled); | 486 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); |
470 | break; | 487 | break; |
471 | 488 | ||
472 | case BFA_PPORT_SM_DISABLE: | 489 | case BFA_FCPORT_SM_DISABLE: |
473 | /** | 490 | /** |
474 | * Already being disabled. | 491 | * Already being disabled. |
475 | */ | 492 | */ |
476 | break; | 493 | break; |
477 | 494 | ||
478 | case BFA_PPORT_SM_ENABLE: | 495 | case BFA_FCPORT_SM_ENABLE: |
479 | if (bfa_pport_send_enable(pport)) | 496 | if (bfa_fcport_send_enable(fcport)) |
480 | bfa_sm_set_state(pport, bfa_pport_sm_enabling); | 497 | bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); |
481 | else | 498 | else |
482 | bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); | 499 | bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait); |
483 | 500 | ||
484 | bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, | 501 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
485 | BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); | 502 | BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); |
486 | bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE); | 503 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE); |
487 | break; | 504 | break; |
488 | 505 | ||
489 | case BFA_PPORT_SM_STOP: | 506 | case BFA_FCPORT_SM_STOP: |
490 | bfa_sm_set_state(pport, bfa_pport_sm_stopped); | 507 | bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); |
491 | break; | 508 | break; |
492 | 509 | ||
493 | case BFA_PPORT_SM_LINKUP: | 510 | case BFA_FCPORT_SM_LINKUP: |
494 | case BFA_PPORT_SM_LINKDOWN: | 511 | case BFA_FCPORT_SM_LINKDOWN: |
495 | /** | 512 | /** |
496 | * Possible to get link events when doing back-to-back | 513 | * Possible to get link events when doing back-to-back |
497 | * enable/disables. | 514 | * enable/disables. |
498 | */ | 515 | */ |
499 | break; | 516 | break; |
500 | 517 | ||
501 | case BFA_PPORT_SM_HWFAIL: | 518 | case BFA_FCPORT_SM_HWFAIL: |
502 | bfa_sm_set_state(pport, bfa_pport_sm_iocfail); | 519 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); |
503 | break; | 520 | break; |
504 | 521 | ||
505 | default: | 522 | default: |
506 | bfa_sm_fault(pport->bfa, event); | 523 | bfa_sm_fault(fcport->bfa, event); |
507 | } | 524 | } |
508 | } | 525 | } |
509 | 526 | ||
510 | static void | 527 | static void |
511 | bfa_pport_sm_disabled(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | 528 | bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, |
529 | enum bfa_fcport_sm_event event) | ||
512 | { | 530 | { |
513 | bfa_trc(pport->bfa, event); | 531 | bfa_trc(fcport->bfa, event); |
514 | 532 | ||
515 | switch (event) { | 533 | switch (event) { |
516 | case BFA_PPORT_SM_START: | 534 | case BFA_FCPORT_SM_START: |
517 | /** | 535 | /** |
518 | * Ignore start event for a port that is disabled. | 536 | * Ignore start event for a port that is disabled. |
519 | */ | 537 | */ |
520 | break; | 538 | break; |
521 | 539 | ||
522 | case BFA_PPORT_SM_STOP: | 540 | case BFA_FCPORT_SM_STOP: |
523 | bfa_sm_set_state(pport, bfa_pport_sm_stopped); | 541 | bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); |
524 | break; | 542 | break; |
525 | 543 | ||
526 | case BFA_PPORT_SM_ENABLE: | 544 | case BFA_FCPORT_SM_ENABLE: |
527 | if (bfa_pport_send_enable(pport)) | 545 | if (bfa_fcport_send_enable(fcport)) |
528 | bfa_sm_set_state(pport, bfa_pport_sm_enabling); | 546 | bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); |
529 | else | 547 | else |
530 | bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); | 548 | bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait); |
531 | 549 | ||
532 | bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, | 550 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
533 | BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); | 551 | BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); |
534 | bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE); | 552 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE); |
535 | break; | 553 | break; |
536 | 554 | ||
537 | case BFA_PPORT_SM_DISABLE: | 555 | case BFA_FCPORT_SM_DISABLE: |
538 | /** | 556 | /** |
539 | * Already disabled. | 557 | * Already disabled. |
540 | */ | 558 | */ |
541 | break; | 559 | break; |
542 | 560 | ||
543 | case BFA_PPORT_SM_HWFAIL: | 561 | case BFA_FCPORT_SM_HWFAIL: |
544 | bfa_sm_set_state(pport, bfa_pport_sm_iocfail); | 562 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); |
545 | break; | 563 | break; |
546 | 564 | ||
547 | default: | 565 | default: |
548 | bfa_sm_fault(pport->bfa, event); | 566 | bfa_sm_fault(fcport->bfa, event); |
549 | } | 567 | } |
550 | } | 568 | } |
551 | 569 | ||
552 | static void | 570 | static void |
553 | bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | 571 | bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport, |
572 | enum bfa_fcport_sm_event event) | ||
554 | { | 573 | { |
555 | bfa_trc(pport->bfa, event); | 574 | bfa_trc(fcport->bfa, event); |
556 | 575 | ||
557 | switch (event) { | 576 | switch (event) { |
558 | case BFA_PPORT_SM_START: | 577 | case BFA_FCPORT_SM_START: |
559 | if (bfa_pport_send_enable(pport)) | 578 | if (bfa_fcport_send_enable(fcport)) |
560 | bfa_sm_set_state(pport, bfa_pport_sm_enabling); | 579 | bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); |
561 | else | 580 | else |
562 | bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); | 581 | bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait); |
563 | break; | 582 | break; |
564 | 583 | ||
565 | default: | 584 | default: |
@@ -574,16 +593,17 @@ bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | |||
574 | * Port is enabled. IOC is down/failed. | 593 | * Port is enabled. IOC is down/failed. |
575 | */ | 594 | */ |
576 | static void | 595 | static void |
577 | bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | 596 | bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, |
597 | enum bfa_fcport_sm_event event) | ||
578 | { | 598 | { |
579 | bfa_trc(pport->bfa, event); | 599 | bfa_trc(fcport->bfa, event); |
580 | 600 | ||
581 | switch (event) { | 601 | switch (event) { |
582 | case BFA_PPORT_SM_START: | 602 | case BFA_FCPORT_SM_START: |
583 | if (bfa_pport_send_enable(pport)) | 603 | if (bfa_fcport_send_enable(fcport)) |
584 | bfa_sm_set_state(pport, bfa_pport_sm_enabling); | 604 | bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); |
585 | else | 605 | else |
586 | bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); | 606 | bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait); |
587 | break; | 607 | break; |
588 | 608 | ||
589 | default: | 609 | default: |
@@ -598,17 +618,18 @@ bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | |||
598 | * Port is disabled. IOC is down/failed. | 618 | * Port is disabled. IOC is down/failed. |
599 | */ | 619 | */ |
600 | static void | 620 | static void |
601 | bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | 621 | bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, |
622 | enum bfa_fcport_sm_event event) | ||
602 | { | 623 | { |
603 | bfa_trc(pport->bfa, event); | 624 | bfa_trc(fcport->bfa, event); |
604 | 625 | ||
605 | switch (event) { | 626 | switch (event) { |
606 | case BFA_PPORT_SM_START: | 627 | case BFA_FCPORT_SM_START: |
607 | bfa_sm_set_state(pport, bfa_pport_sm_disabled); | 628 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); |
608 | break; | 629 | break; |
609 | 630 | ||
610 | case BFA_PPORT_SM_ENABLE: | 631 | case BFA_FCPORT_SM_ENABLE: |
611 | bfa_sm_set_state(pport, bfa_pport_sm_iocdown); | 632 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); |
612 | break; | 633 | break; |
613 | 634 | ||
614 | default: | 635 | default: |
@@ -619,41 +640,226 @@ bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) | |||
619 | } | 640 | } |
620 | } | 641 | } |
621 | 642 | ||
643 | /** | ||
644 | * Link state is down | ||
645 | */ | ||
646 | static void | ||
647 | bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, | ||
648 | enum bfa_fcport_ln_sm_event event) | ||
649 | { | ||
650 | bfa_trc(ln->fcport->bfa, event); | ||
651 | |||
652 | switch (event) { | ||
653 | case BFA_FCPORT_LN_SM_LINKUP: | ||
654 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf); | ||
655 | bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP); | ||
656 | break; | ||
657 | |||
658 | default: | ||
659 | bfa_sm_fault(ln->fcport->bfa, event); | ||
660 | } | ||
661 | } | ||
662 | |||
663 | /** | ||
664 | * Link state is waiting for down notification | ||
665 | */ | ||
666 | static void | ||
667 | bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln, | ||
668 | enum bfa_fcport_ln_sm_event event) | ||
669 | { | ||
670 | bfa_trc(ln->fcport->bfa, event); | ||
671 | |||
672 | switch (event) { | ||
673 | case BFA_FCPORT_LN_SM_LINKUP: | ||
674 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf); | ||
675 | break; | ||
676 | |||
677 | case BFA_FCPORT_LN_SM_NOTIFICATION: | ||
678 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn); | ||
679 | break; | ||
680 | |||
681 | default: | ||
682 | bfa_sm_fault(ln->fcport->bfa, event); | ||
683 | } | ||
684 | } | ||
685 | |||
686 | /** | ||
687 | * Link state is waiting for down notification and there is a pending up | ||
688 | */ | ||
689 | static void | ||
690 | bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln, | ||
691 | enum bfa_fcport_ln_sm_event event) | ||
692 | { | ||
693 | bfa_trc(ln->fcport->bfa, event); | ||
694 | |||
695 | switch (event) { | ||
696 | case BFA_FCPORT_LN_SM_LINKDOWN: | ||
697 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); | ||
698 | break; | ||
699 | |||
700 | case BFA_FCPORT_LN_SM_NOTIFICATION: | ||
701 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf); | ||
702 | bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP); | ||
703 | break; | ||
704 | |||
705 | default: | ||
706 | bfa_sm_fault(ln->fcport->bfa, event); | ||
707 | } | ||
708 | } | ||
709 | |||
710 | /** | ||
711 | * Link state is up | ||
712 | */ | ||
713 | static void | ||
714 | bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln, | ||
715 | enum bfa_fcport_ln_sm_event event) | ||
716 | { | ||
717 | bfa_trc(ln->fcport->bfa, event); | ||
718 | |||
719 | switch (event) { | ||
720 | case BFA_FCPORT_LN_SM_LINKDOWN: | ||
721 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); | ||
722 | bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN); | ||
723 | break; | ||
622 | 724 | ||
725 | default: | ||
726 | bfa_sm_fault(ln->fcport->bfa, event); | ||
727 | } | ||
728 | } | ||
729 | |||
730 | /** | ||
731 | * Link state is waiting for up notification | ||
732 | */ | ||
733 | static void | ||
734 | bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln, | ||
735 | enum bfa_fcport_ln_sm_event event) | ||
736 | { | ||
737 | bfa_trc(ln->fcport->bfa, event); | ||
738 | |||
739 | switch (event) { | ||
740 | case BFA_FCPORT_LN_SM_LINKDOWN: | ||
741 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf); | ||
742 | break; | ||
743 | |||
744 | case BFA_FCPORT_LN_SM_NOTIFICATION: | ||
745 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_up); | ||
746 | break; | ||
747 | |||
748 | default: | ||
749 | bfa_sm_fault(ln->fcport->bfa, event); | ||
750 | } | ||
751 | } | ||
752 | |||
753 | /** | ||
754 | * Link state is waiting for up notification and there is a pending down | ||
755 | */ | ||
756 | static void | ||
757 | bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln, | ||
758 | enum bfa_fcport_ln_sm_event event) | ||
759 | { | ||
760 | bfa_trc(ln->fcport->bfa, event); | ||
761 | |||
762 | switch (event) { | ||
763 | case BFA_FCPORT_LN_SM_LINKUP: | ||
764 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf); | ||
765 | break; | ||
766 | |||
767 | case BFA_FCPORT_LN_SM_NOTIFICATION: | ||
768 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); | ||
769 | bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN); | ||
770 | break; | ||
771 | |||
772 | default: | ||
773 | bfa_sm_fault(ln->fcport->bfa, event); | ||
774 | } | ||
775 | } | ||
776 | |||
777 | /** | ||
778 | * Link state is waiting for up notification and there are pending down and up | ||
779 | */ | ||
780 | static void | ||
781 | bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln, | ||
782 | enum bfa_fcport_ln_sm_event event) | ||
783 | { | ||
784 | bfa_trc(ln->fcport->bfa, event); | ||
785 | |||
786 | switch (event) { | ||
787 | case BFA_FCPORT_LN_SM_LINKDOWN: | ||
788 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf); | ||
789 | break; | ||
790 | |||
791 | case BFA_FCPORT_LN_SM_NOTIFICATION: | ||
792 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf); | ||
793 | bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN); | ||
794 | break; | ||
795 | |||
796 | default: | ||
797 | bfa_sm_fault(ln->fcport->bfa, event); | ||
798 | } | ||
799 | } | ||
623 | 800 | ||
624 | /** | 801 | /** |
625 | * bfa_pport_private | 802 | * bfa_pport_private |
626 | */ | 803 | */ |
627 | 804 | ||
628 | static void | 805 | static void |
629 | __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete) | 806 | __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete) |
630 | { | 807 | { |
631 | struct bfa_pport_s *pport = cbarg; | 808 | struct bfa_fcport_ln_s *ln = cbarg; |
632 | 809 | ||
633 | if (complete) | 810 | if (complete) |
634 | pport->event_cbfn(pport->event_cbarg, pport->hcb_event); | 811 | ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event); |
812 | else | ||
813 | bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION); | ||
635 | } | 814 | } |
636 | 815 | ||
637 | #define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \ | 816 | static void |
817 | bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event) | ||
818 | { | ||
819 | if (fcport->bfa->fcs) { | ||
820 | fcport->event_cbfn(fcport->event_cbarg, event); | ||
821 | return; | ||
822 | } | ||
823 | |||
824 | switch (event) { | ||
825 | case BFA_PPORT_LINKUP: | ||
826 | bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP); | ||
827 | break; | ||
828 | case BFA_PPORT_LINKDOWN: | ||
829 | bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN); | ||
830 | break; | ||
831 | default: | ||
832 | bfa_assert(0); | ||
833 | } | ||
834 | } | ||
835 | |||
836 | static void | ||
837 | bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event) | ||
838 | { | ||
839 | ln->ln_event = event; | ||
840 | bfa_cb_queue(ln->fcport->bfa, &ln->ln_qe, __bfa_cb_fcport_event, ln); | ||
841 | } | ||
842 | |||
843 | #define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \ | ||
638 | BFA_CACHELINE_SZ)) | 844 | BFA_CACHELINE_SZ)) |
639 | 845 | ||
640 | static void | 846 | static void |
641 | bfa_pport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, | 847 | bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, |
642 | u32 *dm_len) | 848 | u32 *dm_len) |
643 | { | 849 | { |
644 | *dm_len += PPORT_STATS_DMA_SZ; | 850 | *dm_len += FCPORT_STATS_DMA_SZ; |
645 | } | 851 | } |
646 | 852 | ||
647 | static void | 853 | static void |
648 | bfa_pport_qresume(void *cbarg) | 854 | bfa_fcport_qresume(void *cbarg) |
649 | { | 855 | { |
650 | struct bfa_pport_s *port = cbarg; | 856 | struct bfa_fcport_s *fcport = cbarg; |
651 | 857 | ||
652 | bfa_sm_send_event(port, BFA_PPORT_SM_QRESUME); | 858 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME); |
653 | } | 859 | } |
654 | 860 | ||
655 | static void | 861 | static void |
656 | bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo) | 862 | bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo) |
657 | { | 863 | { |
658 | u8 *dm_kva; | 864 | u8 *dm_kva; |
659 | u64 dm_pa; | 865 | u64 dm_pa; |
@@ -661,12 +867,12 @@ bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo) | |||
661 | dm_kva = bfa_meminfo_dma_virt(meminfo); | 867 | dm_kva = bfa_meminfo_dma_virt(meminfo); |
662 | dm_pa = bfa_meminfo_dma_phys(meminfo); | 868 | dm_pa = bfa_meminfo_dma_phys(meminfo); |
663 | 869 | ||
664 | pport->stats_kva = dm_kva; | 870 | fcport->stats_kva = dm_kva; |
665 | pport->stats_pa = dm_pa; | 871 | fcport->stats_pa = dm_pa; |
666 | pport->stats = (union bfa_pport_stats_u *)dm_kva; | 872 | fcport->stats = (union bfa_fcport_stats_u *)dm_kva; |
667 | 873 | ||
668 | dm_kva += PPORT_STATS_DMA_SZ; | 874 | dm_kva += FCPORT_STATS_DMA_SZ; |
669 | dm_pa += PPORT_STATS_DMA_SZ; | 875 | dm_pa += FCPORT_STATS_DMA_SZ; |
670 | 876 | ||
671 | bfa_meminfo_dma_virt(meminfo) = dm_kva; | 877 | bfa_meminfo_dma_virt(meminfo) = dm_kva; |
672 | bfa_meminfo_dma_phys(meminfo) = dm_pa; | 878 | bfa_meminfo_dma_phys(meminfo) = dm_pa; |
@@ -676,18 +882,21 @@ bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo) | |||
676 | * Memory initialization. | 882 | * Memory initialization. |
677 | */ | 883 | */ |
678 | static void | 884 | static void |
679 | bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | 885 | bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, |
680 | struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) | 886 | struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) |
681 | { | 887 | { |
682 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 888 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
683 | struct bfa_pport_cfg_s *port_cfg = &pport->cfg; | 889 | struct bfa_pport_cfg_s *port_cfg = &fcport->cfg; |
890 | struct bfa_fcport_ln_s *ln = &fcport->ln; | ||
684 | 891 | ||
685 | bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s)); | 892 | bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s)); |
686 | pport->bfa = bfa; | 893 | fcport->bfa = bfa; |
894 | ln->fcport = fcport; | ||
687 | 895 | ||
688 | bfa_pport_mem_claim(pport, meminfo); | 896 | bfa_fcport_mem_claim(fcport, meminfo); |
689 | 897 | ||
690 | bfa_sm_set_state(pport, bfa_pport_sm_uninit); | 898 | bfa_sm_set_state(fcport, bfa_fcport_sm_uninit); |
899 | bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn); | ||
691 | 900 | ||
692 | /** | 901 | /** |
693 | * initialize and set default configuration | 902 | * initialize and set default configuration |
@@ -699,30 +908,30 @@ bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
699 | 908 | ||
700 | port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS; | 909 | port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS; |
701 | 910 | ||
702 | bfa_reqq_winit(&pport->reqq_wait, bfa_pport_qresume, pport); | 911 | bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport); |
703 | } | 912 | } |
704 | 913 | ||
705 | static void | 914 | static void |
706 | bfa_pport_initdone(struct bfa_s *bfa) | 915 | bfa_fcport_initdone(struct bfa_s *bfa) |
707 | { | 916 | { |
708 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 917 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
709 | 918 | ||
710 | /** | 919 | /** |
711 | * Initialize port attributes from IOC hardware data. | 920 | * Initialize port attributes from IOC hardware data. |
712 | */ | 921 | */ |
713 | bfa_pport_set_wwns(pport); | 922 | bfa_fcport_set_wwns(fcport); |
714 | if (pport->cfg.maxfrsize == 0) | 923 | if (fcport->cfg.maxfrsize == 0) |
715 | pport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc); | 924 | fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc); |
716 | pport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc); | 925 | fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc); |
717 | pport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc); | 926 | fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc); |
718 | 927 | ||
719 | bfa_assert(pport->cfg.maxfrsize); | 928 | bfa_assert(fcport->cfg.maxfrsize); |
720 | bfa_assert(pport->cfg.rx_bbcredit); | 929 | bfa_assert(fcport->cfg.rx_bbcredit); |
721 | bfa_assert(pport->speed_sup); | 930 | bfa_assert(fcport->speed_sup); |
722 | } | 931 | } |
723 | 932 | ||
724 | static void | 933 | static void |
725 | bfa_pport_detach(struct bfa_s *bfa) | 934 | bfa_fcport_detach(struct bfa_s *bfa) |
726 | { | 935 | { |
727 | } | 936 | } |
728 | 937 | ||
@@ -730,95 +939,97 @@ bfa_pport_detach(struct bfa_s *bfa) | |||
730 | * Called when IOC is ready. | 939 | * Called when IOC is ready. |
731 | */ | 940 | */ |
732 | static void | 941 | static void |
733 | bfa_pport_start(struct bfa_s *bfa) | 942 | bfa_fcport_start(struct bfa_s *bfa) |
734 | { | 943 | { |
735 | bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_START); | 944 | bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START); |
736 | } | 945 | } |
737 | 946 | ||
738 | /** | 947 | /** |
739 | * Called before IOC is stopped. | 948 | * Called before IOC is stopped. |
740 | */ | 949 | */ |
741 | static void | 950 | static void |
742 | bfa_pport_stop(struct bfa_s *bfa) | 951 | bfa_fcport_stop(struct bfa_s *bfa) |
743 | { | 952 | { |
744 | bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_STOP); | 953 | bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP); |
745 | } | 954 | } |
746 | 955 | ||
747 | /** | 956 | /** |
748 | * Called when IOC failure is detected. | 957 | * Called when IOC failure is detected. |
749 | */ | 958 | */ |
750 | static void | 959 | static void |
751 | bfa_pport_iocdisable(struct bfa_s *bfa) | 960 | bfa_fcport_iocdisable(struct bfa_s *bfa) |
752 | { | 961 | { |
753 | bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_HWFAIL); | 962 | bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_HWFAIL); |
754 | } | 963 | } |
755 | 964 | ||
756 | static void | 965 | static void |
757 | bfa_pport_update_linkinfo(struct bfa_pport_s *pport) | 966 | bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) |
758 | { | 967 | { |
759 | struct bfi_pport_event_s *pevent = pport->event_arg.i2hmsg.event; | 968 | struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; |
760 | 969 | ||
761 | pport->speed = pevent->link_state.speed; | 970 | fcport->speed = pevent->link_state.speed; |
762 | pport->topology = pevent->link_state.topology; | 971 | fcport->topology = pevent->link_state.topology; |
763 | 972 | ||
764 | if (pport->topology == BFA_PPORT_TOPOLOGY_LOOP) | 973 | if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP) |
765 | pport->myalpa = pevent->link_state.tl.loop_info.myalpa; | 974 | fcport->myalpa = |
975 | pevent->link_state.tl.loop_info.myalpa; | ||
766 | 976 | ||
767 | /* | 977 | /* |
768 | * QoS Details | 978 | * QoS Details |
769 | */ | 979 | */ |
770 | bfa_os_assign(pport->qos_attr, pevent->link_state.qos_attr); | 980 | bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr); |
771 | bfa_os_assign(pport->qos_vc_attr, pevent->link_state.qos_vc_attr); | 981 | bfa_os_assign(fcport->qos_vc_attr, pevent->link_state.qos_vc_attr); |
772 | 982 | ||
773 | bfa_trc(pport->bfa, pport->speed); | 983 | bfa_trc(fcport->bfa, fcport->speed); |
774 | bfa_trc(pport->bfa, pport->topology); | 984 | bfa_trc(fcport->bfa, fcport->topology); |
775 | } | 985 | } |
776 | 986 | ||
777 | static void | 987 | static void |
778 | bfa_pport_reset_linkinfo(struct bfa_pport_s *pport) | 988 | bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport) |
779 | { | 989 | { |
780 | pport->speed = BFA_PPORT_SPEED_UNKNOWN; | 990 | fcport->speed = BFA_PPORT_SPEED_UNKNOWN; |
781 | pport->topology = BFA_PPORT_TOPOLOGY_NONE; | 991 | fcport->topology = BFA_PPORT_TOPOLOGY_NONE; |
782 | } | 992 | } |
783 | 993 | ||
784 | /** | 994 | /** |
785 | * Send port enable message to firmware. | 995 | * Send port enable message to firmware. |
786 | */ | 996 | */ |
787 | static bfa_boolean_t | 997 | static bfa_boolean_t |
788 | bfa_pport_send_enable(struct bfa_pport_s *port) | 998 | bfa_fcport_send_enable(struct bfa_fcport_s *fcport) |
789 | { | 999 | { |
790 | struct bfi_pport_enable_req_s *m; | 1000 | struct bfi_fcport_enable_req_s *m; |
791 | 1001 | ||
792 | /** | 1002 | /** |
793 | * Increment message tag before queue check, so that responses to old | 1003 | * Increment message tag before queue check, so that responses to old |
794 | * requests are discarded. | 1004 | * requests are discarded. |
795 | */ | 1005 | */ |
796 | port->msgtag++; | 1006 | fcport->msgtag++; |
797 | 1007 | ||
798 | /** | 1008 | /** |
799 | * check for room in queue to send request now | 1009 | * check for room in queue to send request now |
800 | */ | 1010 | */ |
801 | m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); | 1011 | m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); |
802 | if (!m) { | 1012 | if (!m) { |
803 | bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait); | 1013 | bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, |
1014 | &fcport->reqq_wait); | ||
804 | return BFA_FALSE; | 1015 | return BFA_FALSE; |
805 | } | 1016 | } |
806 | 1017 | ||
807 | bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ, | 1018 | bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ, |
808 | bfa_lpuid(port->bfa)); | 1019 | bfa_lpuid(fcport->bfa)); |
809 | m->nwwn = port->nwwn; | 1020 | m->nwwn = fcport->nwwn; |
810 | m->pwwn = port->pwwn; | 1021 | m->pwwn = fcport->pwwn; |
811 | m->port_cfg = port->cfg; | 1022 | m->port_cfg = fcport->cfg; |
812 | m->msgtag = port->msgtag; | 1023 | m->msgtag = fcport->msgtag; |
813 | m->port_cfg.maxfrsize = bfa_os_htons(port->cfg.maxfrsize); | 1024 | m->port_cfg.maxfrsize = bfa_os_htons(fcport->cfg.maxfrsize); |
814 | bfa_dma_be_addr_set(m->stats_dma_addr, port->stats_pa); | 1025 | bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa); |
815 | bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_lo); | 1026 | bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo); |
816 | bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_hi); | 1027 | bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi); |
817 | 1028 | ||
818 | /** | 1029 | /** |
819 | * queue I/O message to firmware | 1030 | * queue I/O message to firmware |
820 | */ | 1031 | */ |
821 | bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); | 1032 | bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); |
822 | return BFA_TRUE; | 1033 | return BFA_TRUE; |
823 | } | 1034 | } |
824 | 1035 | ||
@@ -826,74 +1037,226 @@ bfa_pport_send_enable(struct bfa_pport_s *port) | |||
826 | * Send port disable message to firmware. | 1037 | * Send port disable message to firmware. |
827 | */ | 1038 | */ |
828 | static bfa_boolean_t | 1039 | static bfa_boolean_t |
829 | bfa_pport_send_disable(struct bfa_pport_s *port) | 1040 | bfa_fcport_send_disable(struct bfa_fcport_s *fcport) |
830 | { | 1041 | { |
831 | bfi_pport_disable_req_t *m; | 1042 | struct bfi_fcport_req_s *m; |
832 | 1043 | ||
833 | /** | 1044 | /** |
834 | * Increment message tag before queue check, so that responses to old | 1045 | * Increment message tag before queue check, so that responses to old |
835 | * requests are discarded. | 1046 | * requests are discarded. |
836 | */ | 1047 | */ |
837 | port->msgtag++; | 1048 | fcport->msgtag++; |
838 | 1049 | ||
839 | /** | 1050 | /** |
840 | * check for room in queue to send request now | 1051 | * check for room in queue to send request now |
841 | */ | 1052 | */ |
842 | m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); | 1053 | m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); |
843 | if (!m) { | 1054 | if (!m) { |
844 | bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait); | 1055 | bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, |
1056 | &fcport->reqq_wait); | ||
845 | return BFA_FALSE; | 1057 | return BFA_FALSE; |
846 | } | 1058 | } |
847 | 1059 | ||
848 | bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ, | 1060 | bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ, |
849 | bfa_lpuid(port->bfa)); | 1061 | bfa_lpuid(fcport->bfa)); |
850 | m->msgtag = port->msgtag; | 1062 | m->msgtag = fcport->msgtag; |
851 | 1063 | ||
852 | /** | 1064 | /** |
853 | * queue I/O message to firmware | 1065 | * queue I/O message to firmware |
854 | */ | 1066 | */ |
855 | bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); | 1067 | bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); |
856 | 1068 | ||
857 | return BFA_TRUE; | 1069 | return BFA_TRUE; |
858 | } | 1070 | } |
859 | 1071 | ||
860 | static void | 1072 | static void |
861 | bfa_pport_set_wwns(struct bfa_pport_s *port) | 1073 | bfa_fcport_set_wwns(struct bfa_fcport_s *fcport) |
862 | { | 1074 | { |
863 | port->pwwn = bfa_ioc_get_pwwn(&port->bfa->ioc); | 1075 | fcport->pwwn = bfa_ioc_get_pwwn(&fcport->bfa->ioc); |
864 | port->nwwn = bfa_ioc_get_nwwn(&port->bfa->ioc); | 1076 | fcport->nwwn = bfa_ioc_get_nwwn(&fcport->bfa->ioc); |
865 | 1077 | ||
866 | bfa_trc(port->bfa, port->pwwn); | 1078 | bfa_trc(fcport->bfa, fcport->pwwn); |
867 | bfa_trc(port->bfa, port->nwwn); | 1079 | bfa_trc(fcport->bfa, fcport->nwwn); |
868 | } | 1080 | } |
869 | 1081 | ||
870 | static void | 1082 | static void |
871 | bfa_port_send_txcredit(void *port_cbarg) | 1083 | bfa_fcport_send_txcredit(void *port_cbarg) |
872 | { | 1084 | { |
873 | 1085 | ||
874 | struct bfa_pport_s *port = port_cbarg; | 1086 | struct bfa_fcport_s *fcport = port_cbarg; |
875 | struct bfi_pport_set_svc_params_req_s *m; | 1087 | struct bfi_fcport_set_svc_params_req_s *m; |
876 | 1088 | ||
877 | /** | 1089 | /** |
878 | * check for room in queue to send request now | 1090 | * check for room in queue to send request now |
879 | */ | 1091 | */ |
880 | m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); | 1092 | m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); |
881 | if (!m) { | 1093 | if (!m) { |
882 | bfa_trc(port->bfa, port->cfg.tx_bbcredit); | 1094 | bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit); |
883 | return; | 1095 | return; |
884 | } | 1096 | } |
885 | 1097 | ||
886 | bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ, | 1098 | bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ, |
887 | bfa_lpuid(port->bfa)); | 1099 | bfa_lpuid(fcport->bfa)); |
888 | m->tx_bbcredit = bfa_os_htons((u16) port->cfg.tx_bbcredit); | 1100 | m->tx_bbcredit = bfa_os_htons((u16) fcport->cfg.tx_bbcredit); |
889 | 1101 | ||
890 | /** | 1102 | /** |
891 | * queue I/O message to firmware | 1103 | * queue I/O message to firmware |
892 | */ | 1104 | */ |
893 | bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); | 1105 | bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); |
894 | } | 1106 | } |
895 | 1107 | ||
1108 | static void | ||
1109 | bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d, | ||
1110 | struct bfa_qos_stats_s *s) | ||
1111 | { | ||
1112 | u32 *dip = (u32 *) d; | ||
1113 | u32 *sip = (u32 *) s; | ||
1114 | int i; | ||
1115 | |||
1116 | /* Now swap the 32 bit fields */ | ||
1117 | for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i) | ||
1118 | dip[i] = bfa_os_ntohl(sip[i]); | ||
1119 | } | ||
896 | 1120 | ||
1121 | static void | ||
1122 | bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d, | ||
1123 | struct bfa_fcoe_stats_s *s) | ||
1124 | { | ||
1125 | u32 *dip = (u32 *) d; | ||
1126 | u32 *sip = (u32 *) s; | ||
1127 | int i; | ||
1128 | |||
1129 | for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32)); | ||
1130 | i = i + 2) { | ||
1131 | #ifdef __BIGENDIAN | ||
1132 | dip[i] = bfa_os_ntohl(sip[i]); | ||
1133 | dip[i + 1] = bfa_os_ntohl(sip[i + 1]); | ||
1134 | #else | ||
1135 | dip[i] = bfa_os_ntohl(sip[i + 1]); | ||
1136 | dip[i + 1] = bfa_os_ntohl(sip[i]); | ||
1137 | #endif | ||
1138 | } | ||
1139 | } | ||
1140 | |||
1141 | static void | ||
1142 | __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete) | ||
1143 | { | ||
1144 | struct bfa_fcport_s *fcport = cbarg; | ||
1145 | |||
1146 | if (complete) { | ||
1147 | if (fcport->stats_status == BFA_STATUS_OK) { | ||
1148 | |||
1149 | /* Swap FC QoS or FCoE stats */ | ||
1150 | if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) | ||
1151 | bfa_fcport_qos_stats_swap( | ||
1152 | &fcport->stats_ret->fcqos, | ||
1153 | &fcport->stats->fcqos); | ||
1154 | else | ||
1155 | bfa_fcport_fcoe_stats_swap( | ||
1156 | &fcport->stats_ret->fcoe, | ||
1157 | &fcport->stats->fcoe); | ||
1158 | } | ||
1159 | fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); | ||
1160 | } else { | ||
1161 | fcport->stats_busy = BFA_FALSE; | ||
1162 | fcport->stats_status = BFA_STATUS_OK; | ||
1163 | } | ||
1164 | } | ||
1165 | |||
1166 | static void | ||
1167 | bfa_fcport_stats_get_timeout(void *cbarg) | ||
1168 | { | ||
1169 | struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; | ||
1170 | |||
1171 | bfa_trc(fcport->bfa, fcport->stats_qfull); | ||
1172 | |||
1173 | if (fcport->stats_qfull) { | ||
1174 | bfa_reqq_wcancel(&fcport->stats_reqq_wait); | ||
1175 | fcport->stats_qfull = BFA_FALSE; | ||
1176 | } | ||
1177 | |||
1178 | fcport->stats_status = BFA_STATUS_ETIMER; | ||
1179 | bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get, | ||
1180 | fcport); | ||
1181 | } | ||
1182 | |||
1183 | static void | ||
1184 | bfa_fcport_send_stats_get(void *cbarg) | ||
1185 | { | ||
1186 | struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; | ||
1187 | struct bfi_fcport_req_s *msg; | ||
1188 | |||
1189 | msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); | ||
1190 | |||
1191 | if (!msg) { | ||
1192 | fcport->stats_qfull = BFA_TRUE; | ||
1193 | bfa_reqq_winit(&fcport->stats_reqq_wait, | ||
1194 | bfa_fcport_send_stats_get, fcport); | ||
1195 | bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, | ||
1196 | &fcport->stats_reqq_wait); | ||
1197 | return; | ||
1198 | } | ||
1199 | fcport->stats_qfull = BFA_FALSE; | ||
1200 | |||
1201 | bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s)); | ||
1202 | bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ, | ||
1203 | bfa_lpuid(fcport->bfa)); | ||
1204 | bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); | ||
1205 | } | ||
1206 | |||
1207 | static void | ||
1208 | __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete) | ||
1209 | { | ||
1210 | struct bfa_fcport_s *fcport = cbarg; | ||
1211 | |||
1212 | if (complete) { | ||
1213 | fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); | ||
1214 | } else { | ||
1215 | fcport->stats_busy = BFA_FALSE; | ||
1216 | fcport->stats_status = BFA_STATUS_OK; | ||
1217 | } | ||
1218 | } | ||
1219 | |||
1220 | static void | ||
1221 | bfa_fcport_stats_clr_timeout(void *cbarg) | ||
1222 | { | ||
1223 | struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; | ||
1224 | |||
1225 | bfa_trc(fcport->bfa, fcport->stats_qfull); | ||
1226 | |||
1227 | if (fcport->stats_qfull) { | ||
1228 | bfa_reqq_wcancel(&fcport->stats_reqq_wait); | ||
1229 | fcport->stats_qfull = BFA_FALSE; | ||
1230 | } | ||
1231 | |||
1232 | fcport->stats_status = BFA_STATUS_ETIMER; | ||
1233 | bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, | ||
1234 | __bfa_cb_fcport_stats_clr, fcport); | ||
1235 | } | ||
1236 | |||
1237 | static void | ||
1238 | bfa_fcport_send_stats_clear(void *cbarg) | ||
1239 | { | ||
1240 | struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; | ||
1241 | struct bfi_fcport_req_s *msg; | ||
1242 | |||
1243 | msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); | ||
1244 | |||
1245 | if (!msg) { | ||
1246 | fcport->stats_qfull = BFA_TRUE; | ||
1247 | bfa_reqq_winit(&fcport->stats_reqq_wait, | ||
1248 | bfa_fcport_send_stats_clear, fcport); | ||
1249 | bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, | ||
1250 | &fcport->stats_reqq_wait); | ||
1251 | return; | ||
1252 | } | ||
1253 | fcport->stats_qfull = BFA_FALSE; | ||
1254 | |||
1255 | bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s)); | ||
1256 | bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ, | ||
1257 | bfa_lpuid(fcport->bfa)); | ||
1258 | bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); | ||
1259 | } | ||
897 | 1260 | ||
898 | /** | 1261 | /** |
899 | * bfa_pport_public | 1262 | * bfa_pport_public |
@@ -903,32 +1266,32 @@ bfa_port_send_txcredit(void *port_cbarg) | |||
903 | * Firmware message handler. | 1266 | * Firmware message handler. |
904 | */ | 1267 | */ |
905 | void | 1268 | void |
906 | bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | 1269 | bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) |
907 | { | 1270 | { |
908 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1271 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
909 | union bfi_pport_i2h_msg_u i2hmsg; | 1272 | union bfi_fcport_i2h_msg_u i2hmsg; |
910 | 1273 | ||
911 | i2hmsg.msg = msg; | 1274 | i2hmsg.msg = msg; |
912 | pport->event_arg.i2hmsg = i2hmsg; | 1275 | fcport->event_arg.i2hmsg = i2hmsg; |
913 | 1276 | ||
914 | switch (msg->mhdr.msg_id) { | 1277 | switch (msg->mhdr.msg_id) { |
915 | case BFI_PPORT_I2H_ENABLE_RSP: | 1278 | case BFI_FCPORT_I2H_ENABLE_RSP: |
916 | if (pport->msgtag == i2hmsg.enable_rsp->msgtag) | 1279 | if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) |
917 | bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP); | 1280 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); |
918 | break; | 1281 | break; |
919 | 1282 | ||
920 | case BFI_PPORT_I2H_DISABLE_RSP: | 1283 | case BFI_FCPORT_I2H_DISABLE_RSP: |
921 | if (pport->msgtag == i2hmsg.enable_rsp->msgtag) | 1284 | if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) |
922 | bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP); | 1285 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); |
923 | break; | 1286 | break; |
924 | 1287 | ||
925 | case BFI_PPORT_I2H_EVENT: | 1288 | case BFI_FCPORT_I2H_EVENT: |
926 | switch (i2hmsg.event->link_state.linkstate) { | 1289 | switch (i2hmsg.event->link_state.linkstate) { |
927 | case BFA_PPORT_LINKUP: | 1290 | case BFA_PPORT_LINKUP: |
928 | bfa_sm_send_event(pport, BFA_PPORT_SM_LINKUP); | 1291 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP); |
929 | break; | 1292 | break; |
930 | case BFA_PPORT_LINKDOWN: | 1293 | case BFA_PPORT_LINKDOWN: |
931 | bfa_sm_send_event(pport, BFA_PPORT_SM_LINKDOWN); | 1294 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN); |
932 | break; | 1295 | break; |
933 | case BFA_PPORT_TRUNK_LINKDOWN: | 1296 | case BFA_PPORT_TRUNK_LINKDOWN: |
934 | /** todo: event notification */ | 1297 | /** todo: event notification */ |
@@ -936,42 +1299,40 @@ bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
936 | } | 1299 | } |
937 | break; | 1300 | break; |
938 | 1301 | ||
939 | case BFI_PPORT_I2H_GET_STATS_RSP: | 1302 | case BFI_FCPORT_I2H_STATS_GET_RSP: |
940 | case BFI_PPORT_I2H_GET_QOS_STATS_RSP: | ||
941 | /* | 1303 | /* |
942 | * check for timer pop before processing the rsp | 1304 | * check for timer pop before processing the rsp |
943 | */ | 1305 | */ |
944 | if (pport->stats_busy == BFA_FALSE | 1306 | if (fcport->stats_busy == BFA_FALSE || |
945 | || pport->stats_status == BFA_STATUS_ETIMER) | 1307 | fcport->stats_status == BFA_STATUS_ETIMER) |
946 | break; | 1308 | break; |
947 | 1309 | ||
948 | bfa_timer_stop(&pport->timer); | 1310 | bfa_timer_stop(&fcport->timer); |
949 | pport->stats_status = i2hmsg.getstats_rsp->status; | 1311 | fcport->stats_status = i2hmsg.pstatsget_rsp->status; |
950 | bfa_cb_queue(pport->bfa, &pport->hcb_qe, __bfa_cb_port_stats, | 1312 | bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, |
951 | pport); | 1313 | __bfa_cb_fcport_stats_get, fcport); |
952 | break; | 1314 | break; |
953 | case BFI_PPORT_I2H_CLEAR_STATS_RSP: | 1315 | |
954 | case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP: | 1316 | case BFI_FCPORT_I2H_STATS_CLEAR_RSP: |
955 | /* | 1317 | /* |
956 | * check for timer pop before processing the rsp | 1318 | * check for timer pop before processing the rsp |
957 | */ | 1319 | */ |
958 | if (pport->stats_busy == BFA_FALSE | 1320 | if (fcport->stats_busy == BFA_FALSE || |
959 | || pport->stats_status == BFA_STATUS_ETIMER) | 1321 | fcport->stats_status == BFA_STATUS_ETIMER) |
960 | break; | 1322 | break; |
961 | 1323 | ||
962 | bfa_timer_stop(&pport->timer); | 1324 | bfa_timer_stop(&fcport->timer); |
963 | pport->stats_status = BFA_STATUS_OK; | 1325 | fcport->stats_status = BFA_STATUS_OK; |
964 | bfa_cb_queue(pport->bfa, &pport->hcb_qe, | 1326 | bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, |
965 | __bfa_cb_port_stats_clr, pport); | 1327 | __bfa_cb_fcport_stats_clr, fcport); |
966 | break; | 1328 | break; |
967 | 1329 | ||
968 | default: | 1330 | default: |
969 | bfa_assert(0); | 1331 | bfa_assert(0); |
1332 | break; | ||
970 | } | 1333 | } |
971 | } | 1334 | } |
972 | 1335 | ||
973 | |||
974 | |||
975 | /** | 1336 | /** |
976 | * bfa_pport_api | 1337 | * bfa_pport_api |
977 | */ | 1338 | */ |
@@ -980,35 +1341,35 @@ bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
980 | * Registered callback for port events. | 1341 | * Registered callback for port events. |
981 | */ | 1342 | */ |
982 | void | 1343 | void |
983 | bfa_pport_event_register(struct bfa_s *bfa, | 1344 | bfa_fcport_event_register(struct bfa_s *bfa, |
984 | void (*cbfn) (void *cbarg, bfa_pport_event_t event), | 1345 | void (*cbfn) (void *cbarg, bfa_pport_event_t event), |
985 | void *cbarg) | 1346 | void *cbarg) |
986 | { | 1347 | { |
987 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1348 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
988 | 1349 | ||
989 | pport->event_cbfn = cbfn; | 1350 | fcport->event_cbfn = cbfn; |
990 | pport->event_cbarg = cbarg; | 1351 | fcport->event_cbarg = cbarg; |
991 | } | 1352 | } |
992 | 1353 | ||
993 | bfa_status_t | 1354 | bfa_status_t |
994 | bfa_pport_enable(struct bfa_s *bfa) | 1355 | bfa_fcport_enable(struct bfa_s *bfa) |
995 | { | 1356 | { |
996 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1357 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
997 | 1358 | ||
998 | if (pport->diag_busy) | 1359 | if (fcport->diag_busy) |
999 | return BFA_STATUS_DIAG_BUSY; | 1360 | return BFA_STATUS_DIAG_BUSY; |
1000 | else if (bfa_sm_cmp_state | 1361 | else if (bfa_sm_cmp_state |
1001 | (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait)) | 1362 | (BFA_FCPORT_MOD(bfa), bfa_fcport_sm_disabling_qwait)) |
1002 | return BFA_STATUS_DEVBUSY; | 1363 | return BFA_STATUS_DEVBUSY; |
1003 | 1364 | ||
1004 | bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE); | 1365 | bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE); |
1005 | return BFA_STATUS_OK; | 1366 | return BFA_STATUS_OK; |
1006 | } | 1367 | } |
1007 | 1368 | ||
1008 | bfa_status_t | 1369 | bfa_status_t |
1009 | bfa_pport_disable(struct bfa_s *bfa) | 1370 | bfa_fcport_disable(struct bfa_s *bfa) |
1010 | { | 1371 | { |
1011 | bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_DISABLE); | 1372 | bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE); |
1012 | return BFA_STATUS_OK; | 1373 | return BFA_STATUS_OK; |
1013 | } | 1374 | } |
1014 | 1375 | ||
@@ -1016,18 +1377,18 @@ bfa_pport_disable(struct bfa_s *bfa) | |||
1016 | * Configure port speed. | 1377 | * Configure port speed. |
1017 | */ | 1378 | */ |
1018 | bfa_status_t | 1379 | bfa_status_t |
1019 | bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) | 1380 | bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) |
1020 | { | 1381 | { |
1021 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1382 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1022 | 1383 | ||
1023 | bfa_trc(bfa, speed); | 1384 | bfa_trc(bfa, speed); |
1024 | 1385 | ||
1025 | if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > pport->speed_sup)) { | 1386 | if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > fcport->speed_sup)) { |
1026 | bfa_trc(bfa, pport->speed_sup); | 1387 | bfa_trc(bfa, fcport->speed_sup); |
1027 | return BFA_STATUS_UNSUPP_SPEED; | 1388 | return BFA_STATUS_UNSUPP_SPEED; |
1028 | } | 1389 | } |
1029 | 1390 | ||
1030 | pport->cfg.speed = speed; | 1391 | fcport->cfg.speed = speed; |
1031 | 1392 | ||
1032 | return BFA_STATUS_OK; | 1393 | return BFA_STATUS_OK; |
1033 | } | 1394 | } |
@@ -1036,23 +1397,23 @@ bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) | |||
1036 | * Get current speed. | 1397 | * Get current speed. |
1037 | */ | 1398 | */ |
1038 | enum bfa_pport_speed | 1399 | enum bfa_pport_speed |
1039 | bfa_pport_get_speed(struct bfa_s *bfa) | 1400 | bfa_fcport_get_speed(struct bfa_s *bfa) |
1040 | { | 1401 | { |
1041 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | 1402 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1042 | 1403 | ||
1043 | return port->speed; | 1404 | return fcport->speed; |
1044 | } | 1405 | } |
1045 | 1406 | ||
1046 | /** | 1407 | /** |
1047 | * Configure port topology. | 1408 | * Configure port topology. |
1048 | */ | 1409 | */ |
1049 | bfa_status_t | 1410 | bfa_status_t |
1050 | bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology) | 1411 | bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology) |
1051 | { | 1412 | { |
1052 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1413 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1053 | 1414 | ||
1054 | bfa_trc(bfa, topology); | 1415 | bfa_trc(bfa, topology); |
1055 | bfa_trc(bfa, pport->cfg.topology); | 1416 | bfa_trc(bfa, fcport->cfg.topology); |
1056 | 1417 | ||
1057 | switch (topology) { | 1418 | switch (topology) { |
1058 | case BFA_PPORT_TOPOLOGY_P2P: | 1419 | case BFA_PPORT_TOPOLOGY_P2P: |
@@ -1064,7 +1425,7 @@ bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology) | |||
1064 | return BFA_STATUS_EINVAL; | 1425 | return BFA_STATUS_EINVAL; |
1065 | } | 1426 | } |
1066 | 1427 | ||
1067 | pport->cfg.topology = topology; | 1428 | fcport->cfg.topology = topology; |
1068 | return BFA_STATUS_OK; | 1429 | return BFA_STATUS_OK; |
1069 | } | 1430 | } |
1070 | 1431 | ||
@@ -1072,64 +1433,64 @@ bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology) | |||
1072 | * Get current topology. | 1433 | * Get current topology. |
1073 | */ | 1434 | */ |
1074 | enum bfa_pport_topology | 1435 | enum bfa_pport_topology |
1075 | bfa_pport_get_topology(struct bfa_s *bfa) | 1436 | bfa_fcport_get_topology(struct bfa_s *bfa) |
1076 | { | 1437 | { |
1077 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | 1438 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1078 | 1439 | ||
1079 | return port->topology; | 1440 | return fcport->topology; |
1080 | } | 1441 | } |
1081 | 1442 | ||
1082 | bfa_status_t | 1443 | bfa_status_t |
1083 | bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) | 1444 | bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) |
1084 | { | 1445 | { |
1085 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1446 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1086 | 1447 | ||
1087 | bfa_trc(bfa, alpa); | 1448 | bfa_trc(bfa, alpa); |
1088 | bfa_trc(bfa, pport->cfg.cfg_hardalpa); | 1449 | bfa_trc(bfa, fcport->cfg.cfg_hardalpa); |
1089 | bfa_trc(bfa, pport->cfg.hardalpa); | 1450 | bfa_trc(bfa, fcport->cfg.hardalpa); |
1090 | 1451 | ||
1091 | pport->cfg.cfg_hardalpa = BFA_TRUE; | 1452 | fcport->cfg.cfg_hardalpa = BFA_TRUE; |
1092 | pport->cfg.hardalpa = alpa; | 1453 | fcport->cfg.hardalpa = alpa; |
1093 | 1454 | ||
1094 | return BFA_STATUS_OK; | 1455 | return BFA_STATUS_OK; |
1095 | } | 1456 | } |
1096 | 1457 | ||
1097 | bfa_status_t | 1458 | bfa_status_t |
1098 | bfa_pport_clr_hardalpa(struct bfa_s *bfa) | 1459 | bfa_fcport_clr_hardalpa(struct bfa_s *bfa) |
1099 | { | 1460 | { |
1100 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1461 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1101 | 1462 | ||
1102 | bfa_trc(bfa, pport->cfg.cfg_hardalpa); | 1463 | bfa_trc(bfa, fcport->cfg.cfg_hardalpa); |
1103 | bfa_trc(bfa, pport->cfg.hardalpa); | 1464 | bfa_trc(bfa, fcport->cfg.hardalpa); |
1104 | 1465 | ||
1105 | pport->cfg.cfg_hardalpa = BFA_FALSE; | 1466 | fcport->cfg.cfg_hardalpa = BFA_FALSE; |
1106 | return BFA_STATUS_OK; | 1467 | return BFA_STATUS_OK; |
1107 | } | 1468 | } |
1108 | 1469 | ||
1109 | bfa_boolean_t | 1470 | bfa_boolean_t |
1110 | bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa) | 1471 | bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa) |
1111 | { | 1472 | { |
1112 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | 1473 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1113 | 1474 | ||
1114 | *alpa = port->cfg.hardalpa; | 1475 | *alpa = fcport->cfg.hardalpa; |
1115 | return port->cfg.cfg_hardalpa; | 1476 | return fcport->cfg.cfg_hardalpa; |
1116 | } | 1477 | } |
1117 | 1478 | ||
1118 | u8 | 1479 | u8 |
1119 | bfa_pport_get_myalpa(struct bfa_s *bfa) | 1480 | bfa_fcport_get_myalpa(struct bfa_s *bfa) |
1120 | { | 1481 | { |
1121 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | 1482 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1122 | 1483 | ||
1123 | return port->myalpa; | 1484 | return fcport->myalpa; |
1124 | } | 1485 | } |
1125 | 1486 | ||
1126 | bfa_status_t | 1487 | bfa_status_t |
1127 | bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) | 1488 | bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) |
1128 | { | 1489 | { |
1129 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1490 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1130 | 1491 | ||
1131 | bfa_trc(bfa, maxfrsize); | 1492 | bfa_trc(bfa, maxfrsize); |
1132 | bfa_trc(bfa, pport->cfg.maxfrsize); | 1493 | bfa_trc(bfa, fcport->cfg.maxfrsize); |
1133 | 1494 | ||
1134 | /* | 1495 | /* |
1135 | * with in range | 1496 | * with in range |
@@ -1143,41 +1504,41 @@ bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) | |||
1143 | if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1))) | 1504 | if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1))) |
1144 | return BFA_STATUS_INVLD_DFSZ; | 1505 | return BFA_STATUS_INVLD_DFSZ; |
1145 | 1506 | ||
1146 | pport->cfg.maxfrsize = maxfrsize; | 1507 | fcport->cfg.maxfrsize = maxfrsize; |
1147 | return BFA_STATUS_OK; | 1508 | return BFA_STATUS_OK; |
1148 | } | 1509 | } |
1149 | 1510 | ||
1150 | u16 | 1511 | u16 |
1151 | bfa_pport_get_maxfrsize(struct bfa_s *bfa) | 1512 | bfa_fcport_get_maxfrsize(struct bfa_s *bfa) |
1152 | { | 1513 | { |
1153 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | 1514 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1154 | 1515 | ||
1155 | return port->cfg.maxfrsize; | 1516 | return fcport->cfg.maxfrsize; |
1156 | } | 1517 | } |
1157 | 1518 | ||
1158 | u32 | 1519 | u32 |
1159 | bfa_pport_mypid(struct bfa_s *bfa) | 1520 | bfa_fcport_mypid(struct bfa_s *bfa) |
1160 | { | 1521 | { |
1161 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | 1522 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1162 | 1523 | ||
1163 | return port->mypid; | 1524 | return fcport->mypid; |
1164 | } | 1525 | } |
1165 | 1526 | ||
1166 | u8 | 1527 | u8 |
1167 | bfa_pport_get_rx_bbcredit(struct bfa_s *bfa) | 1528 | bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) |
1168 | { | 1529 | { |
1169 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | 1530 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1170 | 1531 | ||
1171 | return port->cfg.rx_bbcredit; | 1532 | return fcport->cfg.rx_bbcredit; |
1172 | } | 1533 | } |
1173 | 1534 | ||
1174 | void | 1535 | void |
1175 | bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit) | 1536 | bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit) |
1176 | { | 1537 | { |
1177 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | 1538 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1178 | 1539 | ||
1179 | port->cfg.tx_bbcredit = (u8) tx_bbcredit; | 1540 | fcport->cfg.tx_bbcredit = (u8) tx_bbcredit; |
1180 | bfa_port_send_txcredit(port); | 1541 | bfa_fcport_send_txcredit(fcport); |
1181 | } | 1542 | } |
1182 | 1543 | ||
1183 | /** | 1544 | /** |
@@ -1185,302 +1546,192 @@ bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit) | |||
1185 | */ | 1546 | */ |
1186 | 1547 | ||
1187 | wwn_t | 1548 | wwn_t |
1188 | bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node) | 1549 | bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node) |
1189 | { | 1550 | { |
1190 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1551 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1191 | if (node) | 1552 | if (node) |
1192 | return pport->nwwn; | 1553 | return fcport->nwwn; |
1193 | else | 1554 | else |
1194 | return pport->pwwn; | 1555 | return fcport->pwwn; |
1195 | } | 1556 | } |
1196 | 1557 | ||
1197 | void | 1558 | void |
1198 | bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr) | 1559 | bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr) |
1199 | { | 1560 | { |
1200 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1561 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1201 | 1562 | ||
1202 | bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s)); | 1563 | bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s)); |
1203 | 1564 | ||
1204 | attr->nwwn = pport->nwwn; | 1565 | attr->nwwn = fcport->nwwn; |
1205 | attr->pwwn = pport->pwwn; | 1566 | attr->pwwn = fcport->pwwn; |
1206 | 1567 | ||
1207 | bfa_os_memcpy(&attr->pport_cfg, &pport->cfg, | 1568 | bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg, |
1208 | sizeof(struct bfa_pport_cfg_s)); | 1569 | sizeof(struct bfa_pport_cfg_s)); |
1209 | /* | 1570 | /* |
1210 | * speed attributes | 1571 | * speed attributes |
1211 | */ | 1572 | */ |
1212 | attr->pport_cfg.speed = pport->cfg.speed; | 1573 | attr->pport_cfg.speed = fcport->cfg.speed; |
1213 | attr->speed_supported = pport->speed_sup; | 1574 | attr->speed_supported = fcport->speed_sup; |
1214 | attr->speed = pport->speed; | 1575 | attr->speed = fcport->speed; |
1215 | attr->cos_supported = FC_CLASS_3; | 1576 | attr->cos_supported = FC_CLASS_3; |
1216 | 1577 | ||
1217 | /* | 1578 | /* |
1218 | * topology attributes | 1579 | * topology attributes |
1219 | */ | 1580 | */ |
1220 | attr->pport_cfg.topology = pport->cfg.topology; | 1581 | attr->pport_cfg.topology = fcport->cfg.topology; |
1221 | attr->topology = pport->topology; | 1582 | attr->topology = fcport->topology; |
1222 | 1583 | ||
1223 | /* | 1584 | /* |
1224 | * beacon attributes | 1585 | * beacon attributes |
1225 | */ | 1586 | */ |
1226 | attr->beacon = pport->beacon; | 1587 | attr->beacon = fcport->beacon; |
1227 | attr->link_e2e_beacon = pport->link_e2e_beacon; | 1588 | attr->link_e2e_beacon = fcport->link_e2e_beacon; |
1228 | attr->plog_enabled = bfa_plog_get_setting(pport->bfa->plog); | 1589 | attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog); |
1229 | 1590 | ||
1230 | attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); | 1591 | attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); |
1231 | attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); | 1592 | attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); |
1232 | attr->port_state = bfa_sm_to_state(hal_pport_sm_table, pport->sm); | 1593 | attr->port_state = bfa_sm_to_state(hal_pport_sm_table, fcport->sm); |
1233 | if (bfa_ioc_is_disabled(&pport->bfa->ioc)) | 1594 | if (bfa_ioc_is_disabled(&fcport->bfa->ioc)) |
1234 | attr->port_state = BFA_PPORT_ST_IOCDIS; | 1595 | attr->port_state = BFA_PPORT_ST_IOCDIS; |
1235 | else if (bfa_ioc_fw_mismatch(&pport->bfa->ioc)) | 1596 | else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc)) |
1236 | attr->port_state = BFA_PPORT_ST_FWMISMATCH; | 1597 | attr->port_state = BFA_PPORT_ST_FWMISMATCH; |
1237 | } | 1598 | } |
1238 | 1599 | ||
1239 | static void | 1600 | #define BFA_FCPORT_STATS_TOV 1000 |
1240 | bfa_port_stats_query(void *cbarg) | ||
1241 | { | ||
1242 | struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; | ||
1243 | bfi_pport_get_stats_req_t *msg; | ||
1244 | |||
1245 | msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); | ||
1246 | |||
1247 | if (!msg) { | ||
1248 | port->stats_qfull = BFA_TRUE; | ||
1249 | bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_query, | ||
1250 | port); | ||
1251 | bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); | ||
1252 | return; | ||
1253 | } | ||
1254 | port->stats_qfull = BFA_FALSE; | ||
1255 | |||
1256 | bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t)); | ||
1257 | bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ, | ||
1258 | bfa_lpuid(port->bfa)); | ||
1259 | bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); | ||
1260 | |||
1261 | return; | ||
1262 | } | ||
1263 | |||
1264 | static void | ||
1265 | bfa_port_stats_clear(void *cbarg) | ||
1266 | { | ||
1267 | struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; | ||
1268 | bfi_pport_clear_stats_req_t *msg; | ||
1269 | |||
1270 | msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); | ||
1271 | 1601 | ||
1272 | if (!msg) { | 1602 | /** |
1273 | port->stats_qfull = BFA_TRUE; | 1603 | * Fetch port attributes (FCQoS or FCoE). |
1274 | bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_clear, | 1604 | */ |
1275 | port); | 1605 | bfa_status_t |
1276 | bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); | 1606 | bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats, |
1277 | return; | 1607 | bfa_cb_pport_t cbfn, void *cbarg) |
1278 | } | ||
1279 | port->stats_qfull = BFA_FALSE; | ||
1280 | |||
1281 | bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t)); | ||
1282 | bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ, | ||
1283 | bfa_lpuid(port->bfa)); | ||
1284 | bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); | ||
1285 | return; | ||
1286 | } | ||
1287 | |||
1288 | static void | ||
1289 | bfa_port_qos_stats_clear(void *cbarg) | ||
1290 | { | 1608 | { |
1291 | struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; | 1609 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1292 | bfi_pport_clear_qos_stats_req_t *msg; | ||
1293 | |||
1294 | msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); | ||
1295 | 1610 | ||
1296 | if (!msg) { | 1611 | if (fcport->stats_busy) { |
1297 | port->stats_qfull = BFA_TRUE; | 1612 | bfa_trc(bfa, fcport->stats_busy); |
1298 | bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_qos_stats_clear, | 1613 | return BFA_STATUS_DEVBUSY; |
1299 | port); | ||
1300 | bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); | ||
1301 | return; | ||
1302 | } | 1614 | } |
1303 | port->stats_qfull = BFA_FALSE; | ||
1304 | 1615 | ||
1305 | bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t)); | 1616 | fcport->stats_busy = BFA_TRUE; |
1306 | bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ, | 1617 | fcport->stats_ret = stats; |
1307 | bfa_lpuid(port->bfa)); | 1618 | fcport->stats_cbfn = cbfn; |
1308 | bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); | 1619 | fcport->stats_cbarg = cbarg; |
1309 | return; | ||
1310 | } | ||
1311 | |||
1312 | static void | ||
1313 | bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s) | ||
1314 | { | ||
1315 | u32 *dip = (u32 *) d; | ||
1316 | u32 *sip = (u32 *) s; | ||
1317 | int i; | ||
1318 | 1620 | ||
1319 | /* | 1621 | bfa_fcport_send_stats_get(fcport); |
1320 | * Do 64 bit fields swap first | ||
1321 | */ | ||
1322 | for (i = 0; | ||
1323 | i < | ||
1324 | ((sizeof(union bfa_pport_stats_u) - | ||
1325 | sizeof(struct bfa_qos_stats_s)) / sizeof(u32)); i = i + 2) { | ||
1326 | #ifdef __BIGENDIAN | ||
1327 | dip[i] = bfa_os_ntohl(sip[i]); | ||
1328 | dip[i + 1] = bfa_os_ntohl(sip[i + 1]); | ||
1329 | #else | ||
1330 | dip[i] = bfa_os_ntohl(sip[i + 1]); | ||
1331 | dip[i + 1] = bfa_os_ntohl(sip[i]); | ||
1332 | #endif | ||
1333 | } | ||
1334 | 1622 | ||
1335 | /* | 1623 | bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout, |
1336 | * Now swap the 32 bit fields | 1624 | fcport, BFA_FCPORT_STATS_TOV); |
1337 | */ | 1625 | return BFA_STATUS_OK; |
1338 | for (; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); ++i) | ||
1339 | dip[i] = bfa_os_ntohl(sip[i]); | ||
1340 | } | 1626 | } |
1341 | 1627 | ||
1342 | static void | 1628 | /** |
1343 | __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete) | 1629 | * Reset port statistics (FCQoS or FCoE). |
1630 | */ | ||
1631 | bfa_status_t | ||
1632 | bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) | ||
1344 | { | 1633 | { |
1345 | struct bfa_pport_s *port = cbarg; | 1634 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1346 | 1635 | ||
1347 | if (complete) { | 1636 | if (fcport->stats_busy) { |
1348 | port->stats_cbfn(port->stats_cbarg, port->stats_status); | 1637 | bfa_trc(bfa, fcport->stats_busy); |
1349 | } else { | 1638 | return BFA_STATUS_DEVBUSY; |
1350 | port->stats_busy = BFA_FALSE; | ||
1351 | port->stats_status = BFA_STATUS_OK; | ||
1352 | } | 1639 | } |
1353 | } | ||
1354 | |||
1355 | static void | ||
1356 | bfa_port_stats_clr_timeout(void *cbarg) | ||
1357 | { | ||
1358 | struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; | ||
1359 | 1640 | ||
1360 | bfa_trc(port->bfa, port->stats_qfull); | 1641 | fcport->stats_busy = BFA_TRUE; |
1642 | fcport->stats_cbfn = cbfn; | ||
1643 | fcport->stats_cbarg = cbarg; | ||
1361 | 1644 | ||
1362 | if (port->stats_qfull) { | 1645 | bfa_fcport_send_stats_clear(fcport); |
1363 | bfa_reqq_wcancel(&port->stats_reqq_wait); | ||
1364 | port->stats_qfull = BFA_FALSE; | ||
1365 | } | ||
1366 | 1646 | ||
1367 | port->stats_status = BFA_STATUS_ETIMER; | 1647 | bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout, |
1368 | bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port); | 1648 | fcport, BFA_FCPORT_STATS_TOV); |
1649 | return BFA_STATUS_OK; | ||
1369 | } | 1650 | } |
1370 | 1651 | ||
1371 | static void | 1652 | /** |
1372 | __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete) | 1653 | * Fetch FCQoS port statistics |
1654 | */ | ||
1655 | bfa_status_t | ||
1656 | bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats, | ||
1657 | bfa_cb_pport_t cbfn, void *cbarg) | ||
1373 | { | 1658 | { |
1374 | struct bfa_pport_s *port = cbarg; | 1659 | /* Meaningful only for FC mode */ |
1660 | bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc)); | ||
1375 | 1661 | ||
1376 | if (complete) { | 1662 | return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg); |
1377 | if (port->stats_status == BFA_STATUS_OK) | ||
1378 | bfa_pport_stats_swap(port->stats_ret, port->stats); | ||
1379 | port->stats_cbfn(port->stats_cbarg, port->stats_status); | ||
1380 | } else { | ||
1381 | port->stats_busy = BFA_FALSE; | ||
1382 | port->stats_status = BFA_STATUS_OK; | ||
1383 | } | ||
1384 | } | 1663 | } |
1385 | 1664 | ||
1386 | static void | 1665 | /** |
1387 | bfa_port_stats_timeout(void *cbarg) | 1666 | * Reset FCoE port statistics |
1667 | */ | ||
1668 | bfa_status_t | ||
1669 | bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) | ||
1388 | { | 1670 | { |
1389 | struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; | 1671 | /* Meaningful only for FC mode */ |
1390 | 1672 | bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc)); | |
1391 | bfa_trc(port->bfa, port->stats_qfull); | ||
1392 | 1673 | ||
1393 | if (port->stats_qfull) { | 1674 | return bfa_fcport_clear_stats(bfa, cbfn, cbarg); |
1394 | bfa_reqq_wcancel(&port->stats_reqq_wait); | ||
1395 | port->stats_qfull = BFA_FALSE; | ||
1396 | } | ||
1397 | |||
1398 | port->stats_status = BFA_STATUS_ETIMER; | ||
1399 | bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats, port); | ||
1400 | } | 1675 | } |
1401 | 1676 | ||
1402 | #define BFA_PORT_STATS_TOV 1000 | ||
1403 | |||
1404 | /** | 1677 | /** |
1405 | * Fetch port attributes. | 1678 | * Fetch FCQoS port statistics |
1406 | */ | 1679 | */ |
1407 | bfa_status_t | 1680 | bfa_status_t |
1408 | bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, | 1681 | bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats, |
1409 | bfa_cb_pport_t cbfn, void *cbarg) | 1682 | bfa_cb_pport_t cbfn, void *cbarg) |
1410 | { | 1683 | { |
1411 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | 1684 | /* Meaningful only for FCoE mode */ |
1412 | 1685 | bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc)); | |
1413 | if (port->stats_busy) { | ||
1414 | bfa_trc(bfa, port->stats_busy); | ||
1415 | return BFA_STATUS_DEVBUSY; | ||
1416 | } | ||
1417 | |||
1418 | port->stats_busy = BFA_TRUE; | ||
1419 | port->stats_ret = stats; | ||
1420 | port->stats_cbfn = cbfn; | ||
1421 | port->stats_cbarg = cbarg; | ||
1422 | |||
1423 | bfa_port_stats_query(port); | ||
1424 | 1686 | ||
1425 | bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port, | 1687 | return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg); |
1426 | BFA_PORT_STATS_TOV); | ||
1427 | return BFA_STATUS_OK; | ||
1428 | } | 1688 | } |
1429 | 1689 | ||
1690 | /** | ||
1691 | * Reset FCoE port statistics | ||
1692 | */ | ||
1430 | bfa_status_t | 1693 | bfa_status_t |
1431 | bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) | 1694 | bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) |
1432 | { | 1695 | { |
1433 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | 1696 | /* Meaningful only for FCoE mode */ |
1434 | 1697 | bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc)); | |
1435 | if (port->stats_busy) { | ||
1436 | bfa_trc(bfa, port->stats_busy); | ||
1437 | return BFA_STATUS_DEVBUSY; | ||
1438 | } | ||
1439 | |||
1440 | port->stats_busy = BFA_TRUE; | ||
1441 | port->stats_cbfn = cbfn; | ||
1442 | port->stats_cbarg = cbarg; | ||
1443 | |||
1444 | bfa_port_stats_clear(port); | ||
1445 | 1698 | ||
1446 | bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port, | 1699 | return bfa_fcport_clear_stats(bfa, cbfn, cbarg); |
1447 | BFA_PORT_STATS_TOV); | ||
1448 | return BFA_STATUS_OK; | ||
1449 | } | 1700 | } |
1450 | 1701 | ||
1451 | bfa_status_t | 1702 | bfa_status_t |
1452 | bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap) | 1703 | bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap) |
1453 | { | 1704 | { |
1454 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1705 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1455 | 1706 | ||
1456 | bfa_trc(bfa, bitmap); | 1707 | bfa_trc(bfa, bitmap); |
1457 | bfa_trc(bfa, pport->cfg.trunked); | 1708 | bfa_trc(bfa, fcport->cfg.trunked); |
1458 | bfa_trc(bfa, pport->cfg.trunk_ports); | 1709 | bfa_trc(bfa, fcport->cfg.trunk_ports); |
1459 | 1710 | ||
1460 | if (!bitmap || (bitmap & (bitmap - 1))) | 1711 | if (!bitmap || (bitmap & (bitmap - 1))) |
1461 | return BFA_STATUS_EINVAL; | 1712 | return BFA_STATUS_EINVAL; |
1462 | 1713 | ||
1463 | pport->cfg.trunked = BFA_TRUE; | 1714 | fcport->cfg.trunked = BFA_TRUE; |
1464 | pport->cfg.trunk_ports = bitmap; | 1715 | fcport->cfg.trunk_ports = bitmap; |
1465 | 1716 | ||
1466 | return BFA_STATUS_OK; | 1717 | return BFA_STATUS_OK; |
1467 | } | 1718 | } |
1468 | 1719 | ||
1469 | void | 1720 | void |
1470 | bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr) | 1721 | bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr) |
1471 | { | 1722 | { |
1472 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1723 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1473 | 1724 | ||
1474 | qos_attr->state = bfa_os_ntohl(pport->qos_attr.state); | 1725 | qos_attr->state = bfa_os_ntohl(fcport->qos_attr.state); |
1475 | qos_attr->total_bb_cr = bfa_os_ntohl(pport->qos_attr.total_bb_cr); | 1726 | qos_attr->total_bb_cr = bfa_os_ntohl(fcport->qos_attr.total_bb_cr); |
1476 | } | 1727 | } |
1477 | 1728 | ||
1478 | void | 1729 | void |
1479 | bfa_pport_qos_get_vc_attr(struct bfa_s *bfa, | 1730 | bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa, |
1480 | struct bfa_qos_vc_attr_s *qos_vc_attr) | 1731 | struct bfa_qos_vc_attr_s *qos_vc_attr) |
1481 | { | 1732 | { |
1482 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1733 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1483 | struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr; | 1734 | struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr; |
1484 | u32 i = 0; | 1735 | u32 i = 0; |
1485 | 1736 | ||
1486 | qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count); | 1737 | qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count); |
@@ -1503,119 +1754,89 @@ bfa_pport_qos_get_vc_attr(struct bfa_s *bfa, | |||
1503 | } | 1754 | } |
1504 | 1755 | ||
1505 | /** | 1756 | /** |
1506 | * Fetch QoS Stats. | ||
1507 | */ | ||
1508 | bfa_status_t | ||
1509 | bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, | ||
1510 | bfa_cb_pport_t cbfn, void *cbarg) | ||
1511 | { | ||
1512 | /* | ||
1513 | * QoS stats is embedded in port stats | ||
1514 | */ | ||
1515 | return bfa_pport_get_stats(bfa, stats, cbfn, cbarg); | ||
1516 | } | ||
1517 | |||
1518 | bfa_status_t | ||
1519 | bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) | ||
1520 | { | ||
1521 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | ||
1522 | |||
1523 | if (port->stats_busy) { | ||
1524 | bfa_trc(bfa, port->stats_busy); | ||
1525 | return BFA_STATUS_DEVBUSY; | ||
1526 | } | ||
1527 | |||
1528 | port->stats_busy = BFA_TRUE; | ||
1529 | port->stats_cbfn = cbfn; | ||
1530 | port->stats_cbarg = cbarg; | ||
1531 | |||
1532 | bfa_port_qos_stats_clear(port); | ||
1533 | |||
1534 | bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port, | ||
1535 | BFA_PORT_STATS_TOV); | ||
1536 | return BFA_STATUS_OK; | ||
1537 | } | ||
1538 | |||
1539 | /** | ||
1540 | * Fetch port attributes. | 1757 | * Fetch port attributes. |
1541 | */ | 1758 | */ |
1542 | bfa_status_t | 1759 | bfa_status_t |
1543 | bfa_pport_trunk_disable(struct bfa_s *bfa) | 1760 | bfa_fcport_trunk_disable(struct bfa_s *bfa) |
1544 | { | 1761 | { |
1545 | return BFA_STATUS_OK; | 1762 | return BFA_STATUS_OK; |
1546 | } | 1763 | } |
1547 | 1764 | ||
1548 | bfa_boolean_t | 1765 | bfa_boolean_t |
1549 | bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap) | 1766 | bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap) |
1550 | { | 1767 | { |
1551 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | 1768 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1552 | 1769 | ||
1553 | *bitmap = port->cfg.trunk_ports; | 1770 | *bitmap = fcport->cfg.trunk_ports; |
1554 | return port->cfg.trunked; | 1771 | return fcport->cfg.trunked; |
1555 | } | 1772 | } |
1556 | 1773 | ||
1557 | bfa_boolean_t | 1774 | bfa_boolean_t |
1558 | bfa_pport_is_disabled(struct bfa_s *bfa) | 1775 | bfa_fcport_is_disabled(struct bfa_s *bfa) |
1559 | { | 1776 | { |
1560 | struct bfa_pport_s *port = BFA_PORT_MOD(bfa); | 1777 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1561 | 1778 | ||
1562 | return bfa_sm_to_state(hal_pport_sm_table, port->sm) == | 1779 | return bfa_sm_to_state(hal_pport_sm_table, fcport->sm) == |
1563 | BFA_PPORT_ST_DISABLED; | 1780 | BFA_PPORT_ST_DISABLED; |
1564 | 1781 | ||
1565 | } | 1782 | } |
1566 | 1783 | ||
1567 | bfa_boolean_t | 1784 | bfa_boolean_t |
1568 | bfa_pport_is_ratelim(struct bfa_s *bfa) | 1785 | bfa_fcport_is_ratelim(struct bfa_s *bfa) |
1569 | { | 1786 | { |
1570 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1787 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1571 | 1788 | ||
1572 | return pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE; | 1789 | return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE; |
1573 | 1790 | ||
1574 | } | 1791 | } |
1575 | 1792 | ||
1576 | void | 1793 | void |
1577 | bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off) | 1794 | bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off) |
1578 | { | 1795 | { |
1579 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1796 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1797 | enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa); | ||
1580 | 1798 | ||
1581 | bfa_trc(bfa, on_off); | 1799 | bfa_trc(bfa, on_off); |
1582 | bfa_trc(bfa, pport->cfg.qos_enabled); | 1800 | bfa_trc(bfa, fcport->cfg.qos_enabled); |
1801 | |||
1802 | bfa_trc(bfa, ioc_type); | ||
1583 | 1803 | ||
1584 | pport->cfg.qos_enabled = on_off; | 1804 | if (ioc_type == BFA_IOC_TYPE_FC) |
1805 | fcport->cfg.qos_enabled = on_off; | ||
1585 | } | 1806 | } |
1586 | 1807 | ||
1587 | void | 1808 | void |
1588 | bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off) | 1809 | bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off) |
1589 | { | 1810 | { |
1590 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1811 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1591 | 1812 | ||
1592 | bfa_trc(bfa, on_off); | 1813 | bfa_trc(bfa, on_off); |
1593 | bfa_trc(bfa, pport->cfg.ratelimit); | 1814 | bfa_trc(bfa, fcport->cfg.ratelimit); |
1594 | 1815 | ||
1595 | pport->cfg.ratelimit = on_off; | 1816 | fcport->cfg.ratelimit = on_off; |
1596 | if (pport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN) | 1817 | if (fcport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN) |
1597 | pport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS; | 1818 | fcport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS; |
1598 | } | 1819 | } |
1599 | 1820 | ||
1600 | /** | 1821 | /** |
1601 | * Configure default minimum ratelim speed | 1822 | * Configure default minimum ratelim speed |
1602 | */ | 1823 | */ |
1603 | bfa_status_t | 1824 | bfa_status_t |
1604 | bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) | 1825 | bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) |
1605 | { | 1826 | { |
1606 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1827 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1607 | 1828 | ||
1608 | bfa_trc(bfa, speed); | 1829 | bfa_trc(bfa, speed); |
1609 | 1830 | ||
1610 | /* | 1831 | /* |
1611 | * Auto and speeds greater than the supported speed, are invalid | 1832 | * Auto and speeds greater than the supported speed, are invalid |
1612 | */ | 1833 | */ |
1613 | if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > pport->speed_sup)) { | 1834 | if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > fcport->speed_sup)) { |
1614 | bfa_trc(bfa, pport->speed_sup); | 1835 | bfa_trc(bfa, fcport->speed_sup); |
1615 | return BFA_STATUS_UNSUPP_SPEED; | 1836 | return BFA_STATUS_UNSUPP_SPEED; |
1616 | } | 1837 | } |
1617 | 1838 | ||
1618 | pport->cfg.trl_def_speed = speed; | 1839 | fcport->cfg.trl_def_speed = speed; |
1619 | 1840 | ||
1620 | return BFA_STATUS_OK; | 1841 | return BFA_STATUS_OK; |
1621 | } | 1842 | } |
@@ -1624,45 +1845,45 @@ bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) | |||
1624 | * Get default minimum ratelim speed | 1845 | * Get default minimum ratelim speed |
1625 | */ | 1846 | */ |
1626 | enum bfa_pport_speed | 1847 | enum bfa_pport_speed |
1627 | bfa_pport_get_ratelim_speed(struct bfa_s *bfa) | 1848 | bfa_fcport_get_ratelim_speed(struct bfa_s *bfa) |
1628 | { | 1849 | { |
1629 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1850 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1630 | 1851 | ||
1631 | bfa_trc(bfa, pport->cfg.trl_def_speed); | 1852 | bfa_trc(bfa, fcport->cfg.trl_def_speed); |
1632 | return pport->cfg.trl_def_speed; | 1853 | return fcport->cfg.trl_def_speed; |
1633 | 1854 | ||
1634 | } | 1855 | } |
1635 | 1856 | ||
1636 | void | 1857 | void |
1637 | bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status) | 1858 | bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status) |
1638 | { | 1859 | { |
1639 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1860 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1640 | 1861 | ||
1641 | bfa_trc(bfa, status); | 1862 | bfa_trc(bfa, status); |
1642 | bfa_trc(bfa, pport->diag_busy); | 1863 | bfa_trc(bfa, fcport->diag_busy); |
1643 | 1864 | ||
1644 | pport->diag_busy = status; | 1865 | fcport->diag_busy = status; |
1645 | } | 1866 | } |
1646 | 1867 | ||
1647 | void | 1868 | void |
1648 | bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, | 1869 | bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, |
1649 | bfa_boolean_t link_e2e_beacon) | 1870 | bfa_boolean_t link_e2e_beacon) |
1650 | { | 1871 | { |
1651 | struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); | 1872 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
1652 | 1873 | ||
1653 | bfa_trc(bfa, beacon); | 1874 | bfa_trc(bfa, beacon); |
1654 | bfa_trc(bfa, link_e2e_beacon); | 1875 | bfa_trc(bfa, link_e2e_beacon); |
1655 | bfa_trc(bfa, pport->beacon); | 1876 | bfa_trc(bfa, fcport->beacon); |
1656 | bfa_trc(bfa, pport->link_e2e_beacon); | 1877 | bfa_trc(bfa, fcport->link_e2e_beacon); |
1657 | 1878 | ||
1658 | pport->beacon = beacon; | 1879 | fcport->beacon = beacon; |
1659 | pport->link_e2e_beacon = link_e2e_beacon; | 1880 | fcport->link_e2e_beacon = link_e2e_beacon; |
1660 | } | 1881 | } |
1661 | 1882 | ||
1662 | bfa_boolean_t | 1883 | bfa_boolean_t |
1663 | bfa_pport_is_linkup(struct bfa_s *bfa) | 1884 | bfa_fcport_is_linkup(struct bfa_s *bfa) |
1664 | { | 1885 | { |
1665 | return bfa_sm_cmp_state(BFA_PORT_MOD(bfa), bfa_pport_sm_linkup); | 1886 | return bfa_sm_cmp_state(BFA_FCPORT_MOD(bfa), bfa_fcport_sm_linkup); |
1666 | } | 1887 | } |
1667 | 1888 | ||
1668 | 1889 | ||
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index 7cb39a306ea9..3516172c597c 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c | |||
@@ -36,6 +36,7 @@ | |||
36 | * FCS sub-modules | 36 | * FCS sub-modules |
37 | */ | 37 | */ |
38 | struct bfa_fcs_mod_s { | 38 | struct bfa_fcs_mod_s { |
39 | void (*attach) (struct bfa_fcs_s *fcs); | ||
39 | void (*modinit) (struct bfa_fcs_s *fcs); | 40 | void (*modinit) (struct bfa_fcs_s *fcs); |
40 | void (*modexit) (struct bfa_fcs_s *fcs); | 41 | void (*modexit) (struct bfa_fcs_s *fcs); |
41 | }; | 42 | }; |
@@ -43,12 +44,10 @@ struct bfa_fcs_mod_s { | |||
43 | #define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit } | 44 | #define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit } |
44 | 45 | ||
45 | static struct bfa_fcs_mod_s fcs_modules[] = { | 46 | static struct bfa_fcs_mod_s fcs_modules[] = { |
46 | BFA_FCS_MODULE(bfa_fcs_pport), | 47 | { bfa_fcs_pport_attach, NULL, NULL }, |
47 | BFA_FCS_MODULE(bfa_fcs_uf), | 48 | { bfa_fcs_uf_attach, NULL, NULL }, |
48 | BFA_FCS_MODULE(bfa_fcs_fabric), | 49 | { bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit, |
49 | BFA_FCS_MODULE(bfa_fcs_vport), | 50 | bfa_fcs_fabric_modexit }, |
50 | BFA_FCS_MODULE(bfa_fcs_rport), | ||
51 | BFA_FCS_MODULE(bfa_fcs_fcpim), | ||
52 | }; | 51 | }; |
53 | 52 | ||
54 | /** | 53 | /** |
@@ -71,16 +70,10 @@ bfa_fcs_exit_comp(void *fcs_cbarg) | |||
71 | */ | 70 | */ |
72 | 71 | ||
73 | /** | 72 | /** |
74 | * FCS instance initialization. | 73 | * fcs attach -- called once to initialize data structures at driver attach time |
75 | * | ||
76 | * param[in] fcs FCS instance | ||
77 | * param[in] bfa BFA instance | ||
78 | * param[in] bfad BFA driver instance | ||
79 | * | ||
80 | * return None | ||
81 | */ | 74 | */ |
82 | void | 75 | void |
83 | bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, | 76 | bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, |
84 | bfa_boolean_t min_cfg) | 77 | bfa_boolean_t min_cfg) |
85 | { | 78 | { |
86 | int i; | 79 | int i; |
@@ -95,7 +88,24 @@ bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, | |||
95 | 88 | ||
96 | for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) { | 89 | for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) { |
97 | mod = &fcs_modules[i]; | 90 | mod = &fcs_modules[i]; |
98 | mod->modinit(fcs); | 91 | if (mod->attach) |
92 | mod->attach(fcs); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | /** | ||
97 | * fcs initialization, called once after bfa initialization is complete | ||
98 | */ | ||
99 | void | ||
100 | bfa_fcs_init(struct bfa_fcs_s *fcs) | ||
101 | { | ||
102 | int i; | ||
103 | struct bfa_fcs_mod_s *mod; | ||
104 | |||
105 | for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) { | ||
106 | mod = &fcs_modules[i]; | ||
107 | if (mod->modinit) | ||
108 | mod->modinit(fcs); | ||
99 | } | 109 | } |
100 | } | 110 | } |
101 | 111 | ||
@@ -127,6 +137,23 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, | |||
127 | } | 137 | } |
128 | 138 | ||
129 | /** | 139 | /** |
140 | * @brief | ||
141 | * FCS FDMI Driver Parameter Initialization | ||
142 | * | ||
143 | * @param[in] fcs FCS instance | ||
144 | * @param[in] fdmi_enable TRUE/FALSE | ||
145 | * | ||
146 | * @return None | ||
147 | */ | ||
148 | void | ||
149 | bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable) | ||
150 | { | ||
151 | |||
152 | fcs->fdmi_enabled = fdmi_enable; | ||
153 | |||
154 | } | ||
155 | |||
156 | /** | ||
130 | * FCS instance cleanup and exit. | 157 | * FCS instance cleanup and exit. |
131 | * | 158 | * |
132 | * param[in] fcs FCS instance | 159 | * param[in] fcs FCS instance |
@@ -143,10 +170,12 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs) | |||
143 | nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]); | 170 | nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]); |
144 | 171 | ||
145 | for (i = 0; i < nmods; i++) { | 172 | for (i = 0; i < nmods; i++) { |
146 | bfa_wc_up(&fcs->wc); | ||
147 | 173 | ||
148 | mod = &fcs_modules[i]; | 174 | mod = &fcs_modules[i]; |
149 | mod->modexit(fcs); | 175 | if (mod->modexit) { |
176 | bfa_wc_up(&fcs->wc); | ||
177 | mod->modexit(fcs); | ||
178 | } | ||
150 | } | 179 | } |
151 | 180 | ||
152 | bfa_wc_wait(&fcs->wc); | 181 | bfa_wc_wait(&fcs->wc); |
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index c7ab257f10a7..7c1251c682d8 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c | |||
@@ -114,7 +114,7 @@ bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port, | |||
114 | break; | 114 | break; |
115 | 115 | ||
116 | default: | 116 | default: |
117 | bfa_assert(0); | 117 | bfa_sm_fault(port->fcs, event); |
118 | } | 118 | } |
119 | } | 119 | } |
120 | 120 | ||
@@ -136,7 +136,7 @@ bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event) | |||
136 | break; | 136 | break; |
137 | 137 | ||
138 | default: | 138 | default: |
139 | bfa_assert(0); | 139 | bfa_sm_fault(port->fcs, event); |
140 | } | 140 | } |
141 | } | 141 | } |
142 | 142 | ||
@@ -176,7 +176,7 @@ bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port, | |||
176 | break; | 176 | break; |
177 | 177 | ||
178 | default: | 178 | default: |
179 | bfa_assert(0); | 179 | bfa_sm_fault(port->fcs, event); |
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
@@ -214,7 +214,7 @@ bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port, | |||
214 | break; | 214 | break; |
215 | 215 | ||
216 | default: | 216 | default: |
217 | bfa_assert(0); | 217 | bfa_sm_fault(port->fcs, event); |
218 | } | 218 | } |
219 | } | 219 | } |
220 | 220 | ||
@@ -234,7 +234,7 @@ bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port, | |||
234 | break; | 234 | break; |
235 | 235 | ||
236 | default: | 236 | default: |
237 | bfa_assert(0); | 237 | bfa_sm_fault(port->fcs, event); |
238 | } | 238 | } |
239 | } | 239 | } |
240 | 240 | ||
@@ -263,30 +263,8 @@ bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port, | |||
263 | 263 | ||
264 | bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX); | 264 | bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX); |
265 | 265 | ||
266 | switch (event) { | 266 | bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr, |
267 | case BFA_LPORT_AEN_ONLINE: | 267 | role_str[role/2]); |
268 | bfa_log(logmod, BFA_AEN_LPORT_ONLINE, lpwwn_ptr, | ||
269 | role_str[role / 2]); | ||
270 | break; | ||
271 | case BFA_LPORT_AEN_OFFLINE: | ||
272 | bfa_log(logmod, BFA_AEN_LPORT_OFFLINE, lpwwn_ptr, | ||
273 | role_str[role / 2]); | ||
274 | break; | ||
275 | case BFA_LPORT_AEN_NEW: | ||
276 | bfa_log(logmod, BFA_AEN_LPORT_NEW, lpwwn_ptr, | ||
277 | role_str[role / 2]); | ||
278 | break; | ||
279 | case BFA_LPORT_AEN_DELETE: | ||
280 | bfa_log(logmod, BFA_AEN_LPORT_DELETE, lpwwn_ptr, | ||
281 | role_str[role / 2]); | ||
282 | break; | ||
283 | case BFA_LPORT_AEN_DISCONNECT: | ||
284 | bfa_log(logmod, BFA_AEN_LPORT_DISCONNECT, lpwwn_ptr, | ||
285 | role_str[role / 2]); | ||
286 | break; | ||
287 | default: | ||
288 | break; | ||
289 | } | ||
290 | 268 | ||
291 | aen_data.lport.vf_id = port->fabric->vf_id; | 269 | aen_data.lport.vf_id = port->fabric->vf_id; |
292 | aen_data.lport.roles = role; | 270 | aen_data.lport.roles = role; |
@@ -873,36 +851,46 @@ bfa_fcs_port_is_online(struct bfa_fcs_port_s *port) | |||
873 | } | 851 | } |
874 | 852 | ||
875 | /** | 853 | /** |
876 | * Logical port initialization of base or virtual port. | 854 | * Attach time initialization of logical ports. |
877 | * Called by fabric for base port or by vport for virtual ports. | ||
878 | */ | 855 | */ |
879 | void | 856 | void |
880 | bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, | 857 | bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, |
881 | u16 vf_id, struct bfa_port_cfg_s *port_cfg, | 858 | uint16_t vf_id, struct bfa_fcs_vport_s *vport) |
882 | struct bfa_fcs_vport_s *vport) | ||
883 | { | 859 | { |
884 | lport->fcs = fcs; | 860 | lport->fcs = fcs; |
885 | lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); | 861 | lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); |
886 | bfa_os_assign(lport->port_cfg, *port_cfg); | ||
887 | lport->vport = vport; | 862 | lport->vport = vport; |
888 | lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) : | 863 | lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) : |
889 | bfa_lps_get_tag(lport->fabric->lps); | 864 | bfa_lps_get_tag(lport->fabric->lps); |
890 | 865 | ||
891 | INIT_LIST_HEAD(&lport->rport_q); | 866 | INIT_LIST_HEAD(&lport->rport_q); |
892 | lport->num_rports = 0; | 867 | lport->num_rports = 0; |
868 | } | ||
869 | |||
870 | /** | ||
871 | * Logical port initialization of base or virtual port. | ||
872 | * Called by fabric for base port or by vport for virtual ports. | ||
873 | */ | ||
893 | 874 | ||
894 | lport->bfad_port = | 875 | void |
895 | bfa_fcb_port_new(fcs->bfad, lport, lport->port_cfg.roles, | 876 | bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, |
877 | struct bfa_port_cfg_s *port_cfg) | ||
878 | { | ||
879 | struct bfa_fcs_vport_s *vport = lport->vport; | ||
880 | |||
881 | bfa_os_assign(lport->port_cfg, *port_cfg); | ||
882 | |||
883 | lport->bfad_port = bfa_fcb_port_new(lport->fcs->bfad, lport, | ||
884 | lport->port_cfg.roles, | ||
896 | lport->fabric->vf_drv, | 885 | lport->fabric->vf_drv, |
897 | vport ? vport->vport_drv : NULL); | 886 | vport ? vport->vport_drv : NULL); |
887 | |||
898 | bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW); | 888 | bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW); |
899 | 889 | ||
900 | bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit); | 890 | bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit); |
901 | bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); | 891 | bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); |
902 | } | 892 | } |
903 | 893 | ||
904 | |||
905 | |||
906 | /** | 894 | /** |
907 | * fcs_lport_api | 895 | * fcs_lport_api |
908 | */ | 896 | */ |
@@ -921,13 +909,20 @@ bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port, | |||
921 | if (port->fabric) { | 909 | if (port->fabric) { |
922 | port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric); | 910 | port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric); |
923 | port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric); | 911 | port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric); |
912 | port_attr->authfail = | ||
913 | bfa_fcs_fabric_is_auth_failed(port->fabric); | ||
924 | port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port); | 914 | port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port); |
925 | memcpy(port_attr->fabric_ip_addr, | 915 | memcpy(port_attr->fabric_ip_addr, |
926 | bfa_fcs_port_get_fabric_ipaddr(port), | 916 | bfa_fcs_port_get_fabric_ipaddr(port), |
927 | BFA_FCS_FABRIC_IPADDR_SZ); | 917 | BFA_FCS_FABRIC_IPADDR_SZ); |
928 | 918 | ||
929 | if (port->vport != NULL) | 919 | if (port->vport != NULL) { |
930 | port_attr->port_type = BFA_PPORT_TYPE_VPORT; | 920 | port_attr->port_type = BFA_PPORT_TYPE_VPORT; |
921 | port_attr->fpma_mac = | ||
922 | bfa_lps_get_lp_mac(port->vport->lps); | ||
923 | } else | ||
924 | port_attr->fpma_mac = | ||
925 | bfa_lps_get_lp_mac(port->fabric->lps); | ||
931 | 926 | ||
932 | } else { | 927 | } else { |
933 | port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN; | 928 | port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN; |
diff --git a/drivers/scsi/bfa/bfa_fcs_port.c b/drivers/scsi/bfa/bfa_fcs_port.c index 9c4b24e62de1..3c27788cd527 100644 --- a/drivers/scsi/bfa/bfa_fcs_port.c +++ b/drivers/scsi/bfa/bfa_fcs_port.c | |||
@@ -55,14 +55,7 @@ bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event) | |||
55 | } | 55 | } |
56 | 56 | ||
57 | void | 57 | void |
58 | bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs) | 58 | bfa_fcs_pport_attach(struct bfa_fcs_s *fcs) |
59 | { | 59 | { |
60 | bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, | 60 | bfa_fcport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, fcs); |
61 | fcs); | ||
62 | } | ||
63 | |||
64 | void | ||
65 | bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs) | ||
66 | { | ||
67 | bfa_fcs_modexit_comp(fcs); | ||
68 | } | 61 | } |
diff --git a/drivers/scsi/bfa/bfa_fcs_uf.c b/drivers/scsi/bfa/bfa_fcs_uf.c index ad01db6444b2..3d57d48bbae4 100644 --- a/drivers/scsi/bfa/bfa_fcs_uf.c +++ b/drivers/scsi/bfa/bfa_fcs_uf.c | |||
@@ -93,13 +93,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | void | 95 | void |
96 | bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs) | 96 | bfa_fcs_uf_attach(struct bfa_fcs_s *fcs) |
97 | { | 97 | { |
98 | bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs); | 98 | bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs); |
99 | } | 99 | } |
100 | |||
101 | void | ||
102 | bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs) | ||
103 | { | ||
104 | bfa_fcs_modexit_comp(fcs); | ||
105 | } | ||
diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c index ede1438619e2..871a4e28575c 100644 --- a/drivers/scsi/bfa/bfa_hw_cb.c +++ b/drivers/scsi/bfa/bfa_hw_cb.c | |||
@@ -53,6 +53,18 @@ bfa_hwcb_reginit(struct bfa_s *bfa) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | void | 55 | void |
56 | bfa_hwcb_reqq_ack(struct bfa_s *bfa, int reqq) | ||
57 | { | ||
58 | } | ||
59 | |||
60 | static void | ||
61 | bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq) | ||
62 | { | ||
63 | bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, | ||
64 | __HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq)); | ||
65 | } | ||
66 | |||
67 | void | ||
56 | bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq) | 68 | bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq) |
57 | { | 69 | { |
58 | } | 70 | } |
@@ -136,6 +148,7 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa) | |||
136 | void | 148 | void |
137 | bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) | 149 | bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) |
138 | { | 150 | { |
151 | bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix; | ||
139 | bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix; | 152 | bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix; |
140 | } | 153 | } |
141 | 154 | ||
diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c index 51ae5740e6e9..76ceb9a4bf2f 100644 --- a/drivers/scsi/bfa/bfa_hw_ct.c +++ b/drivers/scsi/bfa/bfa_hw_ct.c | |||
@@ -85,6 +85,15 @@ bfa_hwct_reginit(struct bfa_s *bfa) | |||
85 | } | 85 | } |
86 | 86 | ||
87 | void | 87 | void |
88 | bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq) | ||
89 | { | ||
90 | u32 r32; | ||
91 | |||
92 | r32 = bfa_reg_read(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]); | ||
93 | bfa_reg_write(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq], r32); | ||
94 | } | ||
95 | |||
96 | void | ||
88 | bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq) | 97 | bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq) |
89 | { | 98 | { |
90 | u32 r32; | 99 | u32 r32; |
diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c index b36540e4ed76..0eba3f930d5b 100644 --- a/drivers/scsi/bfa/bfa_intr.c +++ b/drivers/scsi/bfa/bfa_intr.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * General Public License for more details. | 15 | * General Public License for more details. |
16 | */ | 16 | */ |
17 | #include <bfa.h> | 17 | #include <bfa.h> |
18 | #include <bfi/bfi_cbreg.h> | 18 | #include <bfi/bfi_ctreg.h> |
19 | #include <bfa_port_priv.h> | 19 | #include <bfa_port_priv.h> |
20 | #include <bfa_intr_priv.h> | 20 | #include <bfa_intr_priv.h> |
21 | #include <cs/bfa_debug.h> | 21 | #include <cs/bfa_debug.h> |
@@ -34,6 +34,26 @@ bfa_msix_lpu(struct bfa_s *bfa) | |||
34 | bfa_ioc_mbox_isr(&bfa->ioc); | 34 | bfa_ioc_mbox_isr(&bfa->ioc); |
35 | } | 35 | } |
36 | 36 | ||
37 | static void | ||
38 | bfa_reqq_resume(struct bfa_s *bfa, int qid) | ||
39 | { | ||
40 | struct list_head *waitq, *qe, *qen; | ||
41 | struct bfa_reqq_wait_s *wqe; | ||
42 | |||
43 | waitq = bfa_reqq(bfa, qid); | ||
44 | list_for_each_safe(qe, qen, waitq) { | ||
45 | /** | ||
46 | * Callback only as long as there is room in request queue | ||
47 | */ | ||
48 | if (bfa_reqq_full(bfa, qid)) | ||
49 | break; | ||
50 | |||
51 | list_del(qe); | ||
52 | wqe = (struct bfa_reqq_wait_s *) qe; | ||
53 | wqe->qresume(wqe->cbarg); | ||
54 | } | ||
55 | } | ||
56 | |||
37 | void | 57 | void |
38 | bfa_msix_all(struct bfa_s *bfa, int vec) | 58 | bfa_msix_all(struct bfa_s *bfa, int vec) |
39 | { | 59 | { |
@@ -96,7 +116,8 @@ bfa_isr_enable(struct bfa_s *bfa) | |||
96 | 116 | ||
97 | bfa_msix_install(bfa); | 117 | bfa_msix_install(bfa); |
98 | intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | | 118 | intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | |
99 | __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS); | 119 | __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | |
120 | __HFN_INT_LL_HALT); | ||
100 | 121 | ||
101 | if (pci_func == 0) | 122 | if (pci_func == 0) |
102 | intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 | | 123 | intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 | |
@@ -127,23 +148,18 @@ bfa_isr_disable(struct bfa_s *bfa) | |||
127 | void | 148 | void |
128 | bfa_msix_reqq(struct bfa_s *bfa, int qid) | 149 | bfa_msix_reqq(struct bfa_s *bfa, int qid) |
129 | { | 150 | { |
130 | struct list_head *waitq, *qe, *qen; | 151 | struct list_head *waitq; |
131 | struct bfa_reqq_wait_s *wqe; | ||
132 | 152 | ||
133 | qid &= (BFI_IOC_MAX_CQS - 1); | 153 | qid &= (BFI_IOC_MAX_CQS - 1); |
134 | 154 | ||
135 | waitq = bfa_reqq(bfa, qid); | 155 | bfa->iocfc.hwif.hw_reqq_ack(bfa, qid); |
136 | list_for_each_safe(qe, qen, waitq) { | ||
137 | /** | ||
138 | * Callback only as long as there is room in request queue | ||
139 | */ | ||
140 | if (bfa_reqq_full(bfa, qid)) | ||
141 | break; | ||
142 | 156 | ||
143 | list_del(qe); | 157 | /** |
144 | wqe = (struct bfa_reqq_wait_s *) qe; | 158 | * Resume any pending requests in the corresponding reqq. |
145 | wqe->qresume(wqe->cbarg); | 159 | */ |
146 | } | 160 | waitq = bfa_reqq(bfa, qid); |
161 | if (!list_empty(waitq)) | ||
162 | bfa_reqq_resume(bfa, qid); | ||
147 | } | 163 | } |
148 | 164 | ||
149 | void | 165 | void |
@@ -157,26 +173,27 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m) | |||
157 | } | 173 | } |
158 | 174 | ||
159 | void | 175 | void |
160 | bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid) | 176 | bfa_msix_rspq(struct bfa_s *bfa, int qid) |
161 | { | 177 | { |
162 | struct bfi_msg_s *m; | 178 | struct bfi_msg_s *m; |
163 | u32 pi, ci; | 179 | u32 pi, ci; |
180 | struct list_head *waitq; | ||
164 | 181 | ||
165 | bfa_trc_fp(bfa, rsp_qid); | 182 | bfa_trc_fp(bfa, qid); |
166 | 183 | ||
167 | rsp_qid &= (BFI_IOC_MAX_CQS - 1); | 184 | qid &= (BFI_IOC_MAX_CQS - 1); |
168 | 185 | ||
169 | bfa->iocfc.hwif.hw_rspq_ack(bfa, rsp_qid); | 186 | bfa->iocfc.hwif.hw_rspq_ack(bfa, qid); |
170 | 187 | ||
171 | ci = bfa_rspq_ci(bfa, rsp_qid); | 188 | ci = bfa_rspq_ci(bfa, qid); |
172 | pi = bfa_rspq_pi(bfa, rsp_qid); | 189 | pi = bfa_rspq_pi(bfa, qid); |
173 | 190 | ||
174 | bfa_trc_fp(bfa, ci); | 191 | bfa_trc_fp(bfa, ci); |
175 | bfa_trc_fp(bfa, pi); | 192 | bfa_trc_fp(bfa, pi); |
176 | 193 | ||
177 | if (bfa->rme_process) { | 194 | if (bfa->rme_process) { |
178 | while (ci != pi) { | 195 | while (ci != pi) { |
179 | m = bfa_rspq_elem(bfa, rsp_qid, ci); | 196 | m = bfa_rspq_elem(bfa, qid, ci); |
180 | bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX); | 197 | bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX); |
181 | 198 | ||
182 | bfa_isrs[m->mhdr.msg_class] (bfa, m); | 199 | bfa_isrs[m->mhdr.msg_class] (bfa, m); |
@@ -188,25 +205,59 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid) | |||
188 | /** | 205 | /** |
189 | * update CI | 206 | * update CI |
190 | */ | 207 | */ |
191 | bfa_rspq_ci(bfa, rsp_qid) = pi; | 208 | bfa_rspq_ci(bfa, qid) = pi; |
192 | bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi); | 209 | bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[qid], pi); |
193 | bfa_os_mmiowb(); | 210 | bfa_os_mmiowb(); |
211 | |||
212 | /** | ||
213 | * Resume any pending requests in the corresponding reqq. | ||
214 | */ | ||
215 | waitq = bfa_reqq(bfa, qid); | ||
216 | if (!list_empty(waitq)) | ||
217 | bfa_reqq_resume(bfa, qid); | ||
194 | } | 218 | } |
195 | 219 | ||
196 | void | 220 | void |
197 | bfa_msix_lpu_err(struct bfa_s *bfa, int vec) | 221 | bfa_msix_lpu_err(struct bfa_s *bfa, int vec) |
198 | { | 222 | { |
199 | u32 intr; | 223 | u32 intr, curr_value; |
200 | 224 | ||
201 | intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status); | 225 | intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status); |
202 | 226 | ||
203 | if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1)) | 227 | if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1)) |
204 | bfa_msix_lpu(bfa); | 228 | bfa_msix_lpu(bfa); |
205 | 229 | ||
206 | if (intr & (__HFN_INT_ERR_EMC | | 230 | intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | |
207 | __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 | | 231 | __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT); |
208 | __HFN_INT_ERR_PSS)) | 232 | |
233 | if (intr) { | ||
234 | if (intr & __HFN_INT_LL_HALT) { | ||
235 | /** | ||
236 | * If LL_HALT bit is set then FW Init Halt LL Port | ||
237 | * Register needs to be cleared as well so Interrupt | ||
238 | * Status Register will be cleared. | ||
239 | */ | ||
240 | curr_value = bfa_reg_read(bfa->ioc.ioc_regs.ll_halt); | ||
241 | curr_value &= ~__FW_INIT_HALT_P; | ||
242 | bfa_reg_write(bfa->ioc.ioc_regs.ll_halt, curr_value); | ||
243 | } | ||
244 | |||
245 | if (intr & __HFN_INT_ERR_PSS) { | ||
246 | /** | ||
247 | * ERR_PSS bit needs to be cleared as well in case | ||
248 | * interrups are shared so driver's interrupt handler is | ||
249 | * still called eventhough it is already masked out. | ||
250 | */ | ||
251 | curr_value = bfa_reg_read( | ||
252 | bfa->ioc.ioc_regs.pss_err_status_reg); | ||
253 | curr_value &= __PSS_ERR_STATUS_SET; | ||
254 | bfa_reg_write(bfa->ioc.ioc_regs.pss_err_status_reg, | ||
255 | curr_value); | ||
256 | } | ||
257 | |||
258 | bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr); | ||
209 | bfa_msix_errint(bfa, intr); | 259 | bfa_msix_errint(bfa, intr); |
260 | } | ||
210 | } | 261 | } |
211 | 262 | ||
212 | void | 263 | void |
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 397d7e9eade5..e038bc9769f6 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <bfa.h> | 18 | #include <bfa.h> |
19 | #include <bfa_ioc.h> | 19 | #include <bfa_ioc.h> |
20 | #include <bfa_fwimg_priv.h> | 20 | #include <bfa_fwimg_priv.h> |
21 | #include <bfa_trcmod_priv.h> | 21 | #include <cna/bfa_cna_trcmod.h> |
22 | #include <cs/bfa_debug.h> | 22 | #include <cs/bfa_debug.h> |
23 | #include <bfi/bfi_ioc.h> | 23 | #include <bfi/bfi_ioc.h> |
24 | #include <bfi/bfi_ctreg.h> | 24 | #include <bfi/bfi_ctreg.h> |
@@ -27,18 +27,17 @@ | |||
27 | #include <log/bfa_log_hal.h> | 27 | #include <log/bfa_log_hal.h> |
28 | #include <defs/bfa_defs_pci.h> | 28 | #include <defs/bfa_defs_pci.h> |
29 | 29 | ||
30 | BFA_TRC_FILE(HAL, IOC); | 30 | BFA_TRC_FILE(CNA, IOC); |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * IOC local definitions | 33 | * IOC local definitions |
34 | */ | 34 | */ |
35 | #define BFA_IOC_TOV 2000 /* msecs */ | 35 | #define BFA_IOC_TOV 2000 /* msecs */ |
36 | #define BFA_IOC_HB_TOV 1000 /* msecs */ | 36 | #define BFA_IOC_HWSEM_TOV 500 /* msecs */ |
37 | #define BFA_IOC_HB_FAIL_MAX 4 | 37 | #define BFA_IOC_HB_TOV 500 /* msecs */ |
38 | #define BFA_IOC_HWINIT_MAX 2 | 38 | #define BFA_IOC_HWINIT_MAX 2 |
39 | #define BFA_IOC_FWIMG_MINSZ (16 * 1024) | 39 | #define BFA_IOC_FWIMG_MINSZ (16 * 1024) |
40 | #define BFA_IOC_TOV_RECOVER (BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \ | 40 | #define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV |
41 | + BFA_IOC_TOV) | ||
42 | 41 | ||
43 | #define bfa_ioc_timer_start(__ioc) \ | 42 | #define bfa_ioc_timer_start(__ioc) \ |
44 | bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ | 43 | bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ |
@@ -51,12 +50,25 @@ BFA_TRC_FILE(HAL, IOC); | |||
51 | (sizeof(struct bfa_trc_mod_s) - \ | 50 | (sizeof(struct bfa_trc_mod_s) - \ |
52 | BFA_TRC_MAX * sizeof(struct bfa_trc_s))) | 51 | BFA_TRC_MAX * sizeof(struct bfa_trc_s))) |
53 | #define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn)) | 52 | #define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn)) |
54 | #define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++) | ||
55 | 53 | ||
56 | #define BFA_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS) | 54 | /** |
57 | #define BFA_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS) | 55 | * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details. |
58 | #define BFA_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS) | 56 | */ |
59 | bfa_boolean_t bfa_auto_recover = BFA_FALSE; | 57 | |
58 | #define bfa_ioc_firmware_lock(__ioc) \ | ||
59 | ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc)) | ||
60 | #define bfa_ioc_firmware_unlock(__ioc) \ | ||
61 | ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc)) | ||
62 | #define bfa_ioc_fwimg_get_chunk(__ioc, __off) \ | ||
63 | ((__ioc)->ioc_hwif->ioc_fwimg_get_chunk(__ioc, __off)) | ||
64 | #define bfa_ioc_fwimg_get_size(__ioc) \ | ||
65 | ((__ioc)->ioc_hwif->ioc_fwimg_get_size(__ioc)) | ||
66 | #define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc)) | ||
67 | #define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc)) | ||
68 | #define bfa_ioc_notify_hbfail(__ioc) \ | ||
69 | ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc)) | ||
70 | |||
71 | bfa_boolean_t bfa_auto_recover = BFA_TRUE; | ||
60 | 72 | ||
61 | /* | 73 | /* |
62 | * forward declarations | 74 | * forward declarations |
@@ -64,7 +76,6 @@ bfa_boolean_t bfa_auto_recover = BFA_FALSE; | |||
64 | static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa, | 76 | static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa, |
65 | enum bfa_ioc_aen_event event); | 77 | enum bfa_ioc_aen_event event); |
66 | static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc); | 78 | static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc); |
67 | static void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc); | ||
68 | static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc); | 79 | static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc); |
69 | static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force); | 80 | static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force); |
70 | static void bfa_ioc_timeout(void *ioc); | 81 | static void bfa_ioc_timeout(void *ioc); |
@@ -77,8 +88,6 @@ static void bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force); | |||
77 | static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc); | 88 | static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc); |
78 | static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc); | 89 | static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc); |
79 | static void bfa_ioc_recover(struct bfa_ioc_s *ioc); | 90 | static void bfa_ioc_recover(struct bfa_ioc_s *ioc); |
80 | static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc); | ||
81 | static void bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc); | ||
82 | static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc); | 91 | static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc); |
83 | static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc); | 92 | static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc); |
84 | 93 | ||
@@ -508,14 +517,19 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event) | |||
508 | bfa_trc(ioc, event); | 517 | bfa_trc(ioc, event); |
509 | 518 | ||
510 | switch (event) { | 519 | switch (event) { |
511 | case IOC_E_HWERROR: | ||
512 | case IOC_E_FWRSP_DISABLE: | 520 | case IOC_E_FWRSP_DISABLE: |
513 | bfa_ioc_timer_stop(ioc); | 521 | bfa_ioc_timer_stop(ioc); |
522 | bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); | ||
523 | break; | ||
524 | |||
525 | case IOC_E_HWERROR: | ||
526 | bfa_ioc_timer_stop(ioc); | ||
514 | /* | 527 | /* |
515 | * !!! fall through !!! | 528 | * !!! fall through !!! |
516 | */ | 529 | */ |
517 | 530 | ||
518 | case IOC_E_TIMEOUT: | 531 | case IOC_E_TIMEOUT: |
532 | bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL); | ||
519 | bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); | 533 | bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); |
520 | break; | 534 | break; |
521 | 535 | ||
@@ -608,15 +622,12 @@ bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s *ioc) | |||
608 | * Mark IOC as failed in hardware and stop firmware. | 622 | * Mark IOC as failed in hardware and stop firmware. |
609 | */ | 623 | */ |
610 | bfa_ioc_lpu_stop(ioc); | 624 | bfa_ioc_lpu_stop(ioc); |
611 | bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL); | 625 | bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL); |
612 | 626 | ||
613 | if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) { | 627 | /** |
614 | bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P); | 628 | * Notify other functions on HB failure. |
615 | /* | 629 | */ |
616 | * Wait for halt to take effect | 630 | bfa_ioc_notify_hbfail(ioc); |
617 | */ | ||
618 | bfa_reg_read(ioc->ioc_regs.ll_halt); | ||
619 | } | ||
620 | 631 | ||
621 | /** | 632 | /** |
622 | * Notify driver and common modules registered for notification. | 633 | * Notify driver and common modules registered for notification. |
@@ -672,6 +683,12 @@ bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc, enum ioc_event event) | |||
672 | */ | 683 | */ |
673 | break; | 684 | break; |
674 | 685 | ||
686 | case IOC_E_HWERROR: | ||
687 | /* | ||
688 | * HB failure notification, ignore. | ||
689 | */ | ||
690 | break; | ||
691 | |||
675 | default: | 692 | default: |
676 | bfa_sm_fault(ioc, event); | 693 | bfa_sm_fault(ioc, event); |
677 | } | 694 | } |
@@ -700,7 +717,7 @@ bfa_ioc_disable_comp(struct bfa_ioc_s *ioc) | |||
700 | } | 717 | } |
701 | } | 718 | } |
702 | 719 | ||
703 | static void | 720 | void |
704 | bfa_ioc_sem_timeout(void *ioc_arg) | 721 | bfa_ioc_sem_timeout(void *ioc_arg) |
705 | { | 722 | { |
706 | struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg; | 723 | struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg; |
@@ -708,26 +725,32 @@ bfa_ioc_sem_timeout(void *ioc_arg) | |||
708 | bfa_ioc_hw_sem_get(ioc); | 725 | bfa_ioc_hw_sem_get(ioc); |
709 | } | 726 | } |
710 | 727 | ||
711 | static void | 728 | bfa_boolean_t |
712 | bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc) | 729 | bfa_ioc_sem_get(bfa_os_addr_t sem_reg) |
713 | { | 730 | { |
714 | u32 r32; | 731 | u32 r32; |
715 | int cnt = 0; | 732 | int cnt = 0; |
716 | #define BFA_SEM_SPINCNT 1000 | 733 | #define BFA_SEM_SPINCNT 3000 |
717 | 734 | ||
718 | do { | 735 | r32 = bfa_reg_read(sem_reg); |
719 | r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg); | 736 | |
737 | while (r32 && (cnt < BFA_SEM_SPINCNT)) { | ||
720 | cnt++; | 738 | cnt++; |
721 | if (cnt > BFA_SEM_SPINCNT) | 739 | bfa_os_udelay(2); |
722 | break; | 740 | r32 = bfa_reg_read(sem_reg); |
723 | } while (r32 != 0); | 741 | } |
742 | |||
743 | if (r32 == 0) | ||
744 | return BFA_TRUE; | ||
745 | |||
724 | bfa_assert(cnt < BFA_SEM_SPINCNT); | 746 | bfa_assert(cnt < BFA_SEM_SPINCNT); |
747 | return BFA_FALSE; | ||
725 | } | 748 | } |
726 | 749 | ||
727 | static void | 750 | void |
728 | bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc) | 751 | bfa_ioc_sem_release(bfa_os_addr_t sem_reg) |
729 | { | 752 | { |
730 | bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1); | 753 | bfa_reg_write(sem_reg, 1); |
731 | } | 754 | } |
732 | 755 | ||
733 | static void | 756 | static void |
@@ -737,7 +760,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc) | |||
737 | 760 | ||
738 | /** | 761 | /** |
739 | * First read to the semaphore register will return 0, subsequent reads | 762 | * First read to the semaphore register will return 0, subsequent reads |
740 | * will return 1. Semaphore is released by writing 0 to the register | 763 | * will return 1. Semaphore is released by writing 1 to the register |
741 | */ | 764 | */ |
742 | r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg); | 765 | r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg); |
743 | if (r32 == 0) { | 766 | if (r32 == 0) { |
@@ -746,10 +769,10 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc) | |||
746 | } | 769 | } |
747 | 770 | ||
748 | bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout, | 771 | bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout, |
749 | ioc, BFA_IOC_TOV); | 772 | ioc, BFA_IOC_HWSEM_TOV); |
750 | } | 773 | } |
751 | 774 | ||
752 | static void | 775 | void |
753 | bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc) | 776 | bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc) |
754 | { | 777 | { |
755 | bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1); | 778 | bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1); |
@@ -828,7 +851,7 @@ bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc) | |||
828 | /** | 851 | /** |
829 | * Get driver and firmware versions. | 852 | * Get driver and firmware versions. |
830 | */ | 853 | */ |
831 | static void | 854 | void |
832 | bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) | 855 | bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) |
833 | { | 856 | { |
834 | u32 pgnum, pgoff; | 857 | u32 pgnum, pgoff; |
@@ -847,24 +870,10 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) | |||
847 | } | 870 | } |
848 | } | 871 | } |
849 | 872 | ||
850 | static u32 * | ||
851 | bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off) | ||
852 | { | ||
853 | if (ioc->ctdev) | ||
854 | return bfi_image_ct_get_chunk(off); | ||
855 | return bfi_image_cb_get_chunk(off); | ||
856 | } | ||
857 | |||
858 | static u32 | ||
859 | bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc) | ||
860 | { | ||
861 | return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size; | ||
862 | } | ||
863 | |||
864 | /** | 873 | /** |
865 | * Returns TRUE if same. | 874 | * Returns TRUE if same. |
866 | */ | 875 | */ |
867 | static bfa_boolean_t | 876 | bfa_boolean_t |
868 | bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) | 877 | bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) |
869 | { | 878 | { |
870 | struct bfi_ioc_image_hdr_s *drv_fwhdr; | 879 | struct bfi_ioc_image_hdr_s *drv_fwhdr; |
@@ -921,95 +930,6 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc) | |||
921 | } | 930 | } |
922 | 931 | ||
923 | /** | 932 | /** |
924 | * Return true if firmware of current driver matches the running firmware. | ||
925 | */ | ||
926 | static bfa_boolean_t | ||
927 | bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc) | ||
928 | { | ||
929 | enum bfi_ioc_state ioc_fwstate; | ||
930 | u32 usecnt; | ||
931 | struct bfi_ioc_image_hdr_s fwhdr; | ||
932 | |||
933 | /** | ||
934 | * Firmware match check is relevant only for CNA. | ||
935 | */ | ||
936 | if (!ioc->cna) | ||
937 | return BFA_TRUE; | ||
938 | |||
939 | /** | ||
940 | * If bios boot (flash based) -- do not increment usage count | ||
941 | */ | ||
942 | if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) | ||
943 | return BFA_TRUE; | ||
944 | |||
945 | bfa_ioc_usage_sem_get(ioc); | ||
946 | usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); | ||
947 | |||
948 | /** | ||
949 | * If usage count is 0, always return TRUE. | ||
950 | */ | ||
951 | if (usecnt == 0) { | ||
952 | bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1); | ||
953 | bfa_ioc_usage_sem_release(ioc); | ||
954 | bfa_trc(ioc, usecnt); | ||
955 | return BFA_TRUE; | ||
956 | } | ||
957 | |||
958 | ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate); | ||
959 | bfa_trc(ioc, ioc_fwstate); | ||
960 | |||
961 | /** | ||
962 | * Use count cannot be non-zero and chip in uninitialized state. | ||
963 | */ | ||
964 | bfa_assert(ioc_fwstate != BFI_IOC_UNINIT); | ||
965 | |||
966 | /** | ||
967 | * Check if another driver with a different firmware is active | ||
968 | */ | ||
969 | bfa_ioc_fwver_get(ioc, &fwhdr); | ||
970 | if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { | ||
971 | bfa_ioc_usage_sem_release(ioc); | ||
972 | bfa_trc(ioc, usecnt); | ||
973 | return BFA_FALSE; | ||
974 | } | ||
975 | |||
976 | /** | ||
977 | * Same firmware version. Increment the reference count. | ||
978 | */ | ||
979 | usecnt++; | ||
980 | bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); | ||
981 | bfa_ioc_usage_sem_release(ioc); | ||
982 | bfa_trc(ioc, usecnt); | ||
983 | return BFA_TRUE; | ||
984 | } | ||
985 | |||
986 | static void | ||
987 | bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc) | ||
988 | { | ||
989 | u32 usecnt; | ||
990 | |||
991 | /** | ||
992 | * Firmware lock is relevant only for CNA. | ||
993 | * If bios boot (flash based) -- do not decrement usage count | ||
994 | */ | ||
995 | if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)) | ||
996 | return; | ||
997 | |||
998 | /** | ||
999 | * decrement usage count | ||
1000 | */ | ||
1001 | bfa_ioc_usage_sem_get(ioc); | ||
1002 | usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); | ||
1003 | bfa_assert(usecnt > 0); | ||
1004 | |||
1005 | usecnt--; | ||
1006 | bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); | ||
1007 | bfa_trc(ioc, usecnt); | ||
1008 | |||
1009 | bfa_ioc_usage_sem_release(ioc); | ||
1010 | } | ||
1011 | |||
1012 | /** | ||
1013 | * Conditionally flush any pending message from firmware at start. | 933 | * Conditionally flush any pending message from firmware at start. |
1014 | */ | 934 | */ |
1015 | static void | 935 | static void |
@@ -1152,33 +1072,27 @@ bfa_ioc_send_getattr(struct bfa_ioc_s *ioc) | |||
1152 | static void | 1072 | static void |
1153 | bfa_ioc_hb_check(void *cbarg) | 1073 | bfa_ioc_hb_check(void *cbarg) |
1154 | { | 1074 | { |
1155 | struct bfa_ioc_s *ioc = cbarg; | 1075 | struct bfa_ioc_s *ioc = cbarg; |
1156 | u32 hb_count; | 1076 | u32 hb_count; |
1157 | 1077 | ||
1158 | hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat); | 1078 | hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat); |
1159 | if (ioc->hb_count == hb_count) { | 1079 | if (ioc->hb_count == hb_count) { |
1160 | ioc->hb_fail++; | 1080 | bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, |
1161 | } else { | 1081 | hb_count); |
1162 | ioc->hb_count = hb_count; | ||
1163 | ioc->hb_fail = 0; | ||
1164 | } | ||
1165 | |||
1166 | if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) { | ||
1167 | bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, hb_count); | ||
1168 | ioc->hb_fail = 0; | ||
1169 | bfa_ioc_recover(ioc); | 1082 | bfa_ioc_recover(ioc); |
1170 | return; | 1083 | return; |
1084 | } else { | ||
1085 | ioc->hb_count = hb_count; | ||
1171 | } | 1086 | } |
1172 | 1087 | ||
1173 | bfa_ioc_mbox_poll(ioc); | 1088 | bfa_ioc_mbox_poll(ioc); |
1174 | bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc, | 1089 | bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, |
1175 | BFA_IOC_HB_TOV); | 1090 | ioc, BFA_IOC_HB_TOV); |
1176 | } | 1091 | } |
1177 | 1092 | ||
1178 | static void | 1093 | static void |
1179 | bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc) | 1094 | bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc) |
1180 | { | 1095 | { |
1181 | ioc->hb_fail = 0; | ||
1182 | ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat); | 1096 | ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat); |
1183 | bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc, | 1097 | bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc, |
1184 | BFA_IOC_HB_TOV); | 1098 | BFA_IOC_HB_TOV); |
@@ -1191,112 +1105,6 @@ bfa_ioc_hb_stop(struct bfa_ioc_s *ioc) | |||
1191 | } | 1105 | } |
1192 | 1106 | ||
1193 | /** | 1107 | /** |
1194 | * Host to LPU mailbox message addresses | ||
1195 | */ | ||
1196 | static struct { | ||
1197 | u32 hfn_mbox, lpu_mbox, hfn_pgn; | ||
1198 | } iocreg_fnreg[] = { | ||
1199 | { | ||
1200 | HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, { | ||
1201 | HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, { | ||
1202 | HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, { | ||
1203 | HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3} | ||
1204 | }; | ||
1205 | |||
1206 | /** | ||
1207 | * Host <-> LPU mailbox command/status registers - port 0 | ||
1208 | */ | ||
1209 | static struct { | ||
1210 | u32 hfn, lpu; | ||
1211 | } iocreg_mbcmd_p0[] = { | ||
1212 | { | ||
1213 | HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, { | ||
1214 | HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, { | ||
1215 | HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, { | ||
1216 | HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT} | ||
1217 | }; | ||
1218 | |||
1219 | /** | ||
1220 | * Host <-> LPU mailbox command/status registers - port 1 | ||
1221 | */ | ||
1222 | static struct { | ||
1223 | u32 hfn, lpu; | ||
1224 | } iocreg_mbcmd_p1[] = { | ||
1225 | { | ||
1226 | HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, { | ||
1227 | HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, { | ||
1228 | HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, { | ||
1229 | HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT} | ||
1230 | }; | ||
1231 | |||
1232 | /** | ||
1233 | * Shared IRQ handling in INTX mode | ||
1234 | */ | ||
1235 | static struct { | ||
1236 | u32 isr, msk; | ||
1237 | } iocreg_shirq_next[] = { | ||
1238 | { | ||
1239 | HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, { | ||
1240 | HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, { | ||
1241 | HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, { | ||
1242 | HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},}; | ||
1243 | |||
1244 | static void | ||
1245 | bfa_ioc_reg_init(struct bfa_ioc_s *ioc) | ||
1246 | { | ||
1247 | bfa_os_addr_t rb; | ||
1248 | int pcifn = bfa_ioc_pcifn(ioc); | ||
1249 | |||
1250 | rb = bfa_ioc_bar0(ioc); | ||
1251 | |||
1252 | ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox; | ||
1253 | ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox; | ||
1254 | ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn; | ||
1255 | |||
1256 | if (ioc->port_id == 0) { | ||
1257 | ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; | ||
1258 | ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; | ||
1259 | ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn; | ||
1260 | ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu; | ||
1261 | ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; | ||
1262 | } else { | ||
1263 | ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); | ||
1264 | ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); | ||
1265 | ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn; | ||
1266 | ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu; | ||
1267 | ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; | ||
1268 | } | ||
1269 | |||
1270 | /** | ||
1271 | * Shared IRQ handling in INTX mode | ||
1272 | */ | ||
1273 | ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr; | ||
1274 | ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk; | ||
1275 | |||
1276 | /* | ||
1277 | * PSS control registers | ||
1278 | */ | ||
1279 | ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); | ||
1280 | ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG); | ||
1281 | ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG); | ||
1282 | |||
1283 | /* | ||
1284 | * IOC semaphore registers and serialization | ||
1285 | */ | ||
1286 | ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); | ||
1287 | ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG); | ||
1288 | ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT); | ||
1289 | |||
1290 | /** | ||
1291 | * sram memory access | ||
1292 | */ | ||
1293 | ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); | ||
1294 | ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB; | ||
1295 | if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) | ||
1296 | ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; | ||
1297 | } | ||
1298 | |||
1299 | /** | ||
1300 | * Initiate a full firmware download. | 1108 | * Initiate a full firmware download. |
1301 | */ | 1109 | */ |
1302 | static void | 1110 | static void |
@@ -1321,9 +1129,6 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, | |||
1321 | if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) | 1129 | if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) |
1322 | boot_type = BFI_BOOT_TYPE_FLASH; | 1130 | boot_type = BFI_BOOT_TYPE_FLASH; |
1323 | fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno); | 1131 | fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno); |
1324 | fwimg[BFI_BOOT_TYPE_OFF / sizeof(u32)] = bfa_os_swap32(boot_type); | ||
1325 | fwimg[BFI_BOOT_PARAM_OFF / sizeof(u32)] = | ||
1326 | bfa_os_swap32(boot_param); | ||
1327 | 1132 | ||
1328 | pgnum = bfa_ioc_smem_pgnum(ioc, loff); | 1133 | pgnum = bfa_ioc_smem_pgnum(ioc, loff); |
1329 | pgoff = bfa_ioc_smem_pgoff(ioc, loff); | 1134 | pgoff = bfa_ioc_smem_pgoff(ioc, loff); |
@@ -1332,17 +1137,17 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, | |||
1332 | 1137 | ||
1333 | for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) { | 1138 | for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) { |
1334 | 1139 | ||
1335 | if (BFA_FLASH_CHUNK_NO(i) != chunkno) { | 1140 | if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) { |
1336 | chunkno = BFA_FLASH_CHUNK_NO(i); | 1141 | chunkno = BFA_IOC_FLASH_CHUNK_NO(i); |
1337 | fwimg = bfa_ioc_fwimg_get_chunk(ioc, | 1142 | fwimg = bfa_ioc_fwimg_get_chunk(ioc, |
1338 | BFA_FLASH_CHUNK_ADDR(chunkno)); | 1143 | BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); |
1339 | } | 1144 | } |
1340 | 1145 | ||
1341 | /** | 1146 | /** |
1342 | * write smem | 1147 | * write smem |
1343 | */ | 1148 | */ |
1344 | bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, | 1149 | bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, |
1345 | fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]); | 1150 | fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]); |
1346 | 1151 | ||
1347 | loff += sizeof(u32); | 1152 | loff += sizeof(u32); |
1348 | 1153 | ||
@@ -1358,6 +1163,14 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, | |||
1358 | 1163 | ||
1359 | bfa_reg_write(ioc->ioc_regs.host_page_num_fn, | 1164 | bfa_reg_write(ioc->ioc_regs.host_page_num_fn, |
1360 | bfa_ioc_smem_pgnum(ioc, 0)); | 1165 | bfa_ioc_smem_pgnum(ioc, 0)); |
1166 | |||
1167 | /* | ||
1168 | * Set boot type and boot param at the end. | ||
1169 | */ | ||
1170 | bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_TYPE_OFF, | ||
1171 | bfa_os_swap32(boot_type)); | ||
1172 | bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_PARAM_OFF, | ||
1173 | bfa_os_swap32(boot_param)); | ||
1361 | } | 1174 | } |
1362 | 1175 | ||
1363 | static void | 1176 | static void |
@@ -1440,168 +1253,10 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc) | |||
1440 | } | 1253 | } |
1441 | 1254 | ||
1442 | /** | 1255 | /** |
1443 | * Initialize IOC to port mapping. | ||
1444 | */ | ||
1445 | |||
1446 | #define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8) | ||
1447 | static void | ||
1448 | bfa_ioc_map_port(struct bfa_ioc_s *ioc) | ||
1449 | { | ||
1450 | bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; | ||
1451 | u32 r32; | ||
1452 | |||
1453 | /** | ||
1454 | * For crossbow, port id is same as pci function. | ||
1455 | */ | ||
1456 | if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) { | ||
1457 | ioc->port_id = bfa_ioc_pcifn(ioc); | ||
1458 | return; | ||
1459 | } | ||
1460 | |||
1461 | /** | ||
1462 | * For catapult, base port id on personality register and IOC type | ||
1463 | */ | ||
1464 | r32 = bfa_reg_read(rb + FNC_PERS_REG); | ||
1465 | r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)); | ||
1466 | ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH; | ||
1467 | |||
1468 | bfa_trc(ioc, bfa_ioc_pcifn(ioc)); | ||
1469 | bfa_trc(ioc, ioc->port_id); | ||
1470 | } | ||
1471 | |||
1472 | |||
1473 | |||
1474 | /** | ||
1475 | * bfa_ioc_public | 1256 | * bfa_ioc_public |
1476 | */ | 1257 | */ |
1477 | 1258 | ||
1478 | /** | 1259 | /** |
1479 | * Set interrupt mode for a function: INTX or MSIX | ||
1480 | */ | ||
1481 | void | ||
1482 | bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) | ||
1483 | { | ||
1484 | bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; | ||
1485 | u32 r32, mode; | ||
1486 | |||
1487 | r32 = bfa_reg_read(rb + FNC_PERS_REG); | ||
1488 | bfa_trc(ioc, r32); | ||
1489 | |||
1490 | mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) & | ||
1491 | __F0_INTX_STATUS; | ||
1492 | |||
1493 | /** | ||
1494 | * If already in desired mode, do not change anything | ||
1495 | */ | ||
1496 | if (!msix && mode) | ||
1497 | return; | ||
1498 | |||
1499 | if (msix) | ||
1500 | mode = __F0_INTX_STATUS_MSIX; | ||
1501 | else | ||
1502 | mode = __F0_INTX_STATUS_INTA; | ||
1503 | |||
1504 | r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); | ||
1505 | r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); | ||
1506 | bfa_trc(ioc, r32); | ||
1507 | |||
1508 | bfa_reg_write(rb + FNC_PERS_REG, r32); | ||
1509 | } | ||
1510 | |||
1511 | bfa_status_t | ||
1512 | bfa_ioc_pll_init(struct bfa_ioc_s *ioc) | ||
1513 | { | ||
1514 | bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; | ||
1515 | u32 pll_sclk, pll_fclk, r32; | ||
1516 | |||
1517 | if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) { | ||
1518 | pll_sclk = | ||
1519 | __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN | | ||
1520 | __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) | | ||
1521 | __APP_PLL_312_JITLMT0_1(3U) | | ||
1522 | __APP_PLL_312_CNTLMT0_1(1U); | ||
1523 | pll_fclk = | ||
1524 | __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN | | ||
1525 | __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) | | ||
1526 | __APP_PLL_425_JITLMT0_1(3U) | | ||
1527 | __APP_PLL_425_CNTLMT0_1(1U); | ||
1528 | |||
1529 | /** | ||
1530 | * For catapult, choose operational mode FC/FCoE | ||
1531 | */ | ||
1532 | if (ioc->fcmode) { | ||
1533 | bfa_reg_write((rb + OP_MODE), 0); | ||
1534 | bfa_reg_write((rb + ETH_MAC_SER_REG), | ||
1535 | __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2 | ||
1536 | | __APP_EMS_CHANNEL_SEL); | ||
1537 | } else { | ||
1538 | ioc->pllinit = BFA_TRUE; | ||
1539 | bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE); | ||
1540 | bfa_reg_write((rb + ETH_MAC_SER_REG), | ||
1541 | __APP_EMS_REFCKBUFEN1); | ||
1542 | } | ||
1543 | } else { | ||
1544 | pll_sclk = | ||
1545 | __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN | | ||
1546 | __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) | | ||
1547 | __APP_PLL_312_CNTLMT0_1(3U); | ||
1548 | pll_fclk = | ||
1549 | __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN | | ||
1550 | __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) | | ||
1551 | __APP_PLL_425_JITLMT0_1(3U) | | ||
1552 | __APP_PLL_425_CNTLMT0_1(3U); | ||
1553 | } | ||
1554 | |||
1555 | bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT); | ||
1556 | bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT); | ||
1557 | |||
1558 | bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); | ||
1559 | bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); | ||
1560 | bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); | ||
1561 | bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); | ||
1562 | bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); | ||
1563 | bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); | ||
1564 | |||
1565 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, | ||
1566 | __APP_PLL_312_LOGIC_SOFT_RESET); | ||
1567 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, | ||
1568 | __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET); | ||
1569 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, | ||
1570 | __APP_PLL_425_LOGIC_SOFT_RESET); | ||
1571 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, | ||
1572 | __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET); | ||
1573 | bfa_os_udelay(2); | ||
1574 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, | ||
1575 | __APP_PLL_312_LOGIC_SOFT_RESET); | ||
1576 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, | ||
1577 | __APP_PLL_425_LOGIC_SOFT_RESET); | ||
1578 | |||
1579 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, | ||
1580 | pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET); | ||
1581 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, | ||
1582 | pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET); | ||
1583 | |||
1584 | /** | ||
1585 | * Wait for PLLs to lock. | ||
1586 | */ | ||
1587 | bfa_os_udelay(2000); | ||
1588 | bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); | ||
1589 | bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); | ||
1590 | |||
1591 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk); | ||
1592 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk); | ||
1593 | |||
1594 | if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) { | ||
1595 | bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START); | ||
1596 | bfa_os_udelay(1000); | ||
1597 | r32 = bfa_reg_read((rb + MBIST_STAT_REG)); | ||
1598 | bfa_trc(ioc, r32); | ||
1599 | } | ||
1600 | |||
1601 | return BFA_STATUS_OK; | ||
1602 | } | ||
1603 | |||
1604 | /** | ||
1605 | * Interface used by diag module to do firmware boot with memory test | 1260 | * Interface used by diag module to do firmware boot with memory test |
1606 | * as the entry vector. | 1261 | * as the entry vector. |
1607 | */ | 1262 | */ |
@@ -1642,7 +1297,7 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param) | |||
1642 | void | 1297 | void |
1643 | bfa_ioc_auto_recover(bfa_boolean_t auto_recover) | 1298 | bfa_ioc_auto_recover(bfa_boolean_t auto_recover) |
1644 | { | 1299 | { |
1645 | bfa_auto_recover = BFA_FALSE; | 1300 | bfa_auto_recover = auto_recover; |
1646 | } | 1301 | } |
1647 | 1302 | ||
1648 | 1303 | ||
@@ -1764,6 +1419,14 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev, | |||
1764 | ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT); | 1419 | ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT); |
1765 | ioc->cna = ioc->ctdev && !ioc->fcmode; | 1420 | ioc->cna = ioc->ctdev && !ioc->fcmode; |
1766 | 1421 | ||
1422 | /** | ||
1423 | * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c | ||
1424 | */ | ||
1425 | if (ioc->ctdev) | ||
1426 | bfa_ioc_set_ct_hwif(ioc); | ||
1427 | else | ||
1428 | bfa_ioc_set_cb_hwif(ioc); | ||
1429 | |||
1767 | bfa_ioc_map_port(ioc); | 1430 | bfa_ioc_map_port(ioc); |
1768 | bfa_ioc_reg_init(ioc); | 1431 | bfa_ioc_reg_init(ioc); |
1769 | } | 1432 | } |
@@ -1830,7 +1493,6 @@ return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0; | |||
1830 | void | 1493 | void |
1831 | bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave) | 1494 | bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave) |
1832 | { | 1495 | { |
1833 | bfa_assert(ioc->auto_recover); | ||
1834 | ioc->dbg_fwsave = dbg_fwsave; | 1496 | ioc->dbg_fwsave = dbg_fwsave; |
1835 | ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover); | 1497 | ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover); |
1836 | } | 1498 | } |
@@ -1973,7 +1635,7 @@ bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc) | |||
1973 | ((__sm) == BFI_IOC_INITING) || \ | 1635 | ((__sm) == BFI_IOC_INITING) || \ |
1974 | ((__sm) == BFI_IOC_HWINIT) || \ | 1636 | ((__sm) == BFI_IOC_HWINIT) || \ |
1975 | ((__sm) == BFI_IOC_DISABLED) || \ | 1637 | ((__sm) == BFI_IOC_DISABLED) || \ |
1976 | ((__sm) == BFI_IOC_HBFAIL) || \ | 1638 | ((__sm) == BFI_IOC_FAIL) || \ |
1977 | ((__sm) == BFI_IOC_CFG_DISABLED)) | 1639 | ((__sm) == BFI_IOC_CFG_DISABLED)) |
1978 | 1640 | ||
1979 | /** | 1641 | /** |
@@ -2017,46 +1679,28 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, | |||
2017 | struct bfa_adapter_attr_s *ad_attr) | 1679 | struct bfa_adapter_attr_s *ad_attr) |
2018 | { | 1680 | { |
2019 | struct bfi_ioc_attr_s *ioc_attr; | 1681 | struct bfi_ioc_attr_s *ioc_attr; |
2020 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; | ||
2021 | 1682 | ||
2022 | ioc_attr = ioc->attr; | 1683 | ioc_attr = ioc->attr; |
2023 | bfa_os_memcpy((void *)&ad_attr->serial_num, | 1684 | |
2024 | (void *)ioc_attr->brcd_serialnum, | 1685 | bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num); |
2025 | BFA_ADAPTER_SERIAL_NUM_LEN); | 1686 | bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver); |
2026 | 1687 | bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver); | |
2027 | bfa_os_memcpy(&ad_attr->fw_ver, ioc_attr->fw_version, BFA_VERSION_LEN); | 1688 | bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer); |
2028 | bfa_os_memcpy(&ad_attr->optrom_ver, ioc_attr->optrom_version, | ||
2029 | BFA_VERSION_LEN); | ||
2030 | bfa_os_memcpy(&ad_attr->manufacturer, BFA_MFG_NAME, | ||
2031 | BFA_ADAPTER_MFG_NAME_LEN); | ||
2032 | bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd, | 1689 | bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd, |
2033 | sizeof(struct bfa_mfg_vpd_s)); | 1690 | sizeof(struct bfa_mfg_vpd_s)); |
2034 | 1691 | ||
2035 | ad_attr->nports = BFI_ADAPTER_GETP(NPORTS, ioc_attr->adapter_prop); | 1692 | ad_attr->nports = bfa_ioc_get_nports(ioc); |
2036 | ad_attr->max_speed = BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop); | 1693 | ad_attr->max_speed = bfa_ioc_speed_sup(ioc); |
2037 | 1694 | ||
2038 | /** | 1695 | bfa_ioc_get_adapter_model(ioc, ad_attr->model); |
2039 | * model name | 1696 | /* For now, model descr uses same model string */ |
2040 | */ | 1697 | bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr); |
2041 | if (BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop) == 10) { | ||
2042 | strcpy(model, "BR-10?0"); | ||
2043 | model[5] = '0' + ad_attr->nports; | ||
2044 | } else { | ||
2045 | strcpy(model, "Brocade-??5"); | ||
2046 | model[8] = | ||
2047 | '0' + BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop); | ||
2048 | model[9] = '0' + ad_attr->nports; | ||
2049 | } | ||
2050 | 1698 | ||
2051 | if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop)) | 1699 | if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop)) |
2052 | ad_attr->prototype = 1; | 1700 | ad_attr->prototype = 1; |
2053 | else | 1701 | else |
2054 | ad_attr->prototype = 0; | 1702 | ad_attr->prototype = 0; |
2055 | 1703 | ||
2056 | bfa_os_memcpy(&ad_attr->model, model, BFA_ADAPTER_MODEL_NAME_LEN); | ||
2057 | bfa_os_memcpy(&ad_attr->model_descr, &ad_attr->model, | ||
2058 | BFA_ADAPTER_MODEL_NAME_LEN); | ||
2059 | |||
2060 | ad_attr->pwwn = bfa_ioc_get_pwwn(ioc); | 1704 | ad_attr->pwwn = bfa_ioc_get_pwwn(ioc); |
2061 | ad_attr->mac = bfa_ioc_get_mac(ioc); | 1705 | ad_attr->mac = bfa_ioc_get_mac(ioc); |
2062 | 1706 | ||
@@ -2064,41 +1708,122 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, | |||
2064 | ad_attr->pcie_lanes = ioc_attr->pcie_lanes; | 1708 | ad_attr->pcie_lanes = ioc_attr->pcie_lanes; |
2065 | ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig; | 1709 | ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig; |
2066 | ad_attr->asic_rev = ioc_attr->asic_rev; | 1710 | ad_attr->asic_rev = ioc_attr->asic_rev; |
2067 | ad_attr->hw_ver[0] = 'R'; | 1711 | |
2068 | ad_attr->hw_ver[1] = 'e'; | 1712 | bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver); |
2069 | ad_attr->hw_ver[2] = 'v'; | ||
2070 | ad_attr->hw_ver[3] = '-'; | ||
2071 | ad_attr->hw_ver[4] = ioc_attr->asic_rev; | ||
2072 | ad_attr->hw_ver[5] = '\0'; | ||
2073 | 1713 | ||
2074 | ad_attr->cna_capable = ioc->cna; | 1714 | ad_attr->cna_capable = ioc->cna; |
2075 | } | 1715 | } |
2076 | 1716 | ||
1717 | enum bfa_ioc_type_e | ||
1718 | bfa_ioc_get_type(struct bfa_ioc_s *ioc) | ||
1719 | { | ||
1720 | if (!ioc->ctdev || ioc->fcmode) | ||
1721 | return BFA_IOC_TYPE_FC; | ||
1722 | else if (ioc->ioc_mc == BFI_MC_IOCFC) | ||
1723 | return BFA_IOC_TYPE_FCoE; | ||
1724 | else if (ioc->ioc_mc == BFI_MC_LL) | ||
1725 | return BFA_IOC_TYPE_LL; | ||
1726 | else { | ||
1727 | bfa_assert(ioc->ioc_mc == BFI_MC_LL); | ||
1728 | return BFA_IOC_TYPE_LL; | ||
1729 | } | ||
1730 | } | ||
1731 | |||
1732 | void | ||
1733 | bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num) | ||
1734 | { | ||
1735 | bfa_os_memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN); | ||
1736 | bfa_os_memcpy((void *)serial_num, | ||
1737 | (void *)ioc->attr->brcd_serialnum, | ||
1738 | BFA_ADAPTER_SERIAL_NUM_LEN); | ||
1739 | } | ||
1740 | |||
1741 | void | ||
1742 | bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver) | ||
1743 | { | ||
1744 | bfa_os_memset((void *)fw_ver, 0, BFA_VERSION_LEN); | ||
1745 | bfa_os_memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN); | ||
1746 | } | ||
1747 | |||
1748 | void | ||
1749 | bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev) | ||
1750 | { | ||
1751 | bfa_assert(chip_rev); | ||
1752 | |||
1753 | bfa_os_memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN); | ||
1754 | |||
1755 | chip_rev[0] = 'R'; | ||
1756 | chip_rev[1] = 'e'; | ||
1757 | chip_rev[2] = 'v'; | ||
1758 | chip_rev[3] = '-'; | ||
1759 | chip_rev[4] = ioc->attr->asic_rev; | ||
1760 | chip_rev[5] = '\0'; | ||
1761 | } | ||
1762 | |||
1763 | void | ||
1764 | bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver) | ||
1765 | { | ||
1766 | bfa_os_memset((void *)optrom_ver, 0, BFA_VERSION_LEN); | ||
1767 | bfa_os_memcpy(optrom_ver, ioc->attr->optrom_version, | ||
1768 | BFA_VERSION_LEN); | ||
1769 | } | ||
1770 | |||
1771 | void | ||
1772 | bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer) | ||
1773 | { | ||
1774 | bfa_os_memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN); | ||
1775 | bfa_os_memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); | ||
1776 | } | ||
1777 | |||
1778 | void | ||
1779 | bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model) | ||
1780 | { | ||
1781 | struct bfi_ioc_attr_s *ioc_attr; | ||
1782 | u8 nports; | ||
1783 | u8 max_speed; | ||
1784 | |||
1785 | bfa_assert(model); | ||
1786 | bfa_os_memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN); | ||
1787 | |||
1788 | ioc_attr = ioc->attr; | ||
1789 | |||
1790 | nports = bfa_ioc_get_nports(ioc); | ||
1791 | max_speed = bfa_ioc_speed_sup(ioc); | ||
1792 | |||
1793 | /** | ||
1794 | * model name | ||
1795 | */ | ||
1796 | if (max_speed == 10) { | ||
1797 | strcpy(model, "BR-10?0"); | ||
1798 | model[5] = '0' + nports; | ||
1799 | } else { | ||
1800 | strcpy(model, "Brocade-??5"); | ||
1801 | model[8] = '0' + max_speed; | ||
1802 | model[9] = '0' + nports; | ||
1803 | } | ||
1804 | } | ||
1805 | |||
1806 | enum bfa_ioc_state | ||
1807 | bfa_ioc_get_state(struct bfa_ioc_s *ioc) | ||
1808 | { | ||
1809 | return bfa_sm_to_state(ioc_sm_table, ioc->fsm); | ||
1810 | } | ||
1811 | |||
2077 | void | 1812 | void |
2078 | bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) | 1813 | bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) |
2079 | { | 1814 | { |
2080 | bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s)); | 1815 | bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s)); |
2081 | 1816 | ||
2082 | ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm); | 1817 | ioc_attr->state = bfa_ioc_get_state(ioc); |
2083 | ioc_attr->port_id = ioc->port_id; | 1818 | ioc_attr->port_id = ioc->port_id; |
2084 | 1819 | ||
2085 | if (!ioc->ctdev) | 1820 | ioc_attr->ioc_type = bfa_ioc_get_type(ioc); |
2086 | ioc_attr->ioc_type = BFA_IOC_TYPE_FC; | ||
2087 | else if (ioc->ioc_mc == BFI_MC_IOCFC) | ||
2088 | ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE; | ||
2089 | else if (ioc->ioc_mc == BFI_MC_LL) | ||
2090 | ioc_attr->ioc_type = BFA_IOC_TYPE_LL; | ||
2091 | 1821 | ||
2092 | bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); | 1822 | bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); |
2093 | 1823 | ||
2094 | ioc_attr->pci_attr.device_id = ioc->pcidev.device_id; | 1824 | ioc_attr->pci_attr.device_id = ioc->pcidev.device_id; |
2095 | ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func; | 1825 | ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func; |
2096 | ioc_attr->pci_attr.chip_rev[0] = 'R'; | 1826 | bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev); |
2097 | ioc_attr->pci_attr.chip_rev[1] = 'e'; | ||
2098 | ioc_attr->pci_attr.chip_rev[2] = 'v'; | ||
2099 | ioc_attr->pci_attr.chip_rev[3] = '-'; | ||
2100 | ioc_attr->pci_attr.chip_rev[4] = ioc_attr->adapter_attr.asic_rev; | ||
2101 | ioc_attr->pci_attr.chip_rev[5] = '\0'; | ||
2102 | } | 1827 | } |
2103 | 1828 | ||
2104 | /** | 1829 | /** |
@@ -2195,29 +1920,6 @@ bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc) | |||
2195 | } | 1920 | } |
2196 | 1921 | ||
2197 | /** | 1922 | /** |
2198 | * Return true if interrupt should be claimed. | ||
2199 | */ | ||
2200 | bfa_boolean_t | ||
2201 | bfa_ioc_intx_claim(struct bfa_ioc_s *ioc) | ||
2202 | { | ||
2203 | u32 isr, msk; | ||
2204 | |||
2205 | /** | ||
2206 | * Always claim if not catapult. | ||
2207 | */ | ||
2208 | if (!ioc->ctdev) | ||
2209 | return BFA_TRUE; | ||
2210 | |||
2211 | /** | ||
2212 | * FALSE if next device is claiming interrupt. | ||
2213 | * TRUE if next device is not interrupting or not present. | ||
2214 | */ | ||
2215 | msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next); | ||
2216 | isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next); | ||
2217 | return !(isr & ~msk); | ||
2218 | } | ||
2219 | |||
2220 | /** | ||
2221 | * Send AEN notification | 1923 | * Send AEN notification |
2222 | */ | 1924 | */ |
2223 | static void | 1925 | static void |
@@ -2226,32 +1928,14 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event) | |||
2226 | union bfa_aen_data_u aen_data; | 1928 | union bfa_aen_data_u aen_data; |
2227 | struct bfa_log_mod_s *logmod = ioc->logm; | 1929 | struct bfa_log_mod_s *logmod = ioc->logm; |
2228 | s32 inst_num = 0; | 1930 | s32 inst_num = 0; |
2229 | struct bfa_ioc_attr_s ioc_attr; | 1931 | enum bfa_ioc_type_e ioc_type; |
2230 | 1932 | ||
2231 | switch (event) { | 1933 | bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, event), inst_num); |
2232 | case BFA_IOC_AEN_HBGOOD: | ||
2233 | bfa_log(logmod, BFA_AEN_IOC_HBGOOD, inst_num); | ||
2234 | break; | ||
2235 | case BFA_IOC_AEN_HBFAIL: | ||
2236 | bfa_log(logmod, BFA_AEN_IOC_HBFAIL, inst_num); | ||
2237 | break; | ||
2238 | case BFA_IOC_AEN_ENABLE: | ||
2239 | bfa_log(logmod, BFA_AEN_IOC_ENABLE, inst_num); | ||
2240 | break; | ||
2241 | case BFA_IOC_AEN_DISABLE: | ||
2242 | bfa_log(logmod, BFA_AEN_IOC_DISABLE, inst_num); | ||
2243 | break; | ||
2244 | case BFA_IOC_AEN_FWMISMATCH: | ||
2245 | bfa_log(logmod, BFA_AEN_IOC_FWMISMATCH, inst_num); | ||
2246 | break; | ||
2247 | default: | ||
2248 | break; | ||
2249 | } | ||
2250 | 1934 | ||
2251 | memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn)); | 1935 | memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn)); |
2252 | memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac)); | 1936 | memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac)); |
2253 | bfa_ioc_get_attr(ioc, &ioc_attr); | 1937 | ioc_type = bfa_ioc_get_type(ioc); |
2254 | switch (ioc_attr.ioc_type) { | 1938 | switch (ioc_type) { |
2255 | case BFA_IOC_TYPE_FC: | 1939 | case BFA_IOC_TYPE_FC: |
2256 | aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc); | 1940 | aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc); |
2257 | break; | 1941 | break; |
@@ -2263,10 +1947,10 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event) | |||
2263 | aen_data.ioc.mac = bfa_ioc_get_mac(ioc); | 1947 | aen_data.ioc.mac = bfa_ioc_get_mac(ioc); |
2264 | break; | 1948 | break; |
2265 | default: | 1949 | default: |
2266 | bfa_assert(ioc_attr.ioc_type == BFA_IOC_TYPE_FC); | 1950 | bfa_assert(ioc_type == BFA_IOC_TYPE_FC); |
2267 | break; | 1951 | break; |
2268 | } | 1952 | } |
2269 | aen_data.ioc.ioc_type = ioc_attr.ioc_type; | 1953 | aen_data.ioc.ioc_type = ioc_type; |
2270 | } | 1954 | } |
2271 | 1955 | ||
2272 | /** | 1956 | /** |
@@ -2290,6 +1974,15 @@ bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) | |||
2290 | } | 1974 | } |
2291 | 1975 | ||
2292 | /** | 1976 | /** |
1977 | * Clear saved firmware trace | ||
1978 | */ | ||
1979 | void | ||
1980 | bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc) | ||
1981 | { | ||
1982 | ioc->dbg_fwsave_once = BFA_TRUE; | ||
1983 | } | ||
1984 | |||
1985 | /** | ||
2293 | * Retrieve saved firmware trace from a prior IOC failure. | 1986 | * Retrieve saved firmware trace from a prior IOC failure. |
2294 | */ | 1987 | */ |
2295 | bfa_status_t | 1988 | bfa_status_t |
@@ -2304,6 +1997,13 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) | |||
2304 | 1997 | ||
2305 | pgnum = bfa_ioc_smem_pgnum(ioc, loff); | 1998 | pgnum = bfa_ioc_smem_pgnum(ioc, loff); |
2306 | loff = bfa_ioc_smem_pgoff(ioc, loff); | 1999 | loff = bfa_ioc_smem_pgoff(ioc, loff); |
2000 | |||
2001 | /* | ||
2002 | * Hold semaphore to serialize pll init and fwtrc. | ||
2003 | */ | ||
2004 | if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) | ||
2005 | return BFA_STATUS_FAILED; | ||
2006 | |||
2307 | bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum); | 2007 | bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum); |
2308 | 2008 | ||
2309 | tlen = *trclen; | 2009 | tlen = *trclen; |
@@ -2329,6 +2029,12 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) | |||
2329 | } | 2029 | } |
2330 | bfa_reg_write(ioc->ioc_regs.host_page_num_fn, | 2030 | bfa_reg_write(ioc->ioc_regs.host_page_num_fn, |
2331 | bfa_ioc_smem_pgnum(ioc, 0)); | 2031 | bfa_ioc_smem_pgnum(ioc, 0)); |
2032 | |||
2033 | /* | ||
2034 | * release semaphore. | ||
2035 | */ | ||
2036 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); | ||
2037 | |||
2332 | bfa_trc(ioc, pgnum); | 2038 | bfa_trc(ioc, pgnum); |
2333 | 2039 | ||
2334 | *trclen = tlen * sizeof(u32); | 2040 | *trclen = tlen * sizeof(u32); |
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index 7c30f05ab137..d0804406ea1a 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h | |||
@@ -74,15 +74,18 @@ struct bfa_ioc_regs_s { | |||
74 | bfa_os_addr_t lpu_mbox_cmd; | 74 | bfa_os_addr_t lpu_mbox_cmd; |
75 | bfa_os_addr_t lpu_mbox; | 75 | bfa_os_addr_t lpu_mbox; |
76 | bfa_os_addr_t pss_ctl_reg; | 76 | bfa_os_addr_t pss_ctl_reg; |
77 | bfa_os_addr_t pss_err_status_reg; | ||
77 | bfa_os_addr_t app_pll_fast_ctl_reg; | 78 | bfa_os_addr_t app_pll_fast_ctl_reg; |
78 | bfa_os_addr_t app_pll_slow_ctl_reg; | 79 | bfa_os_addr_t app_pll_slow_ctl_reg; |
79 | bfa_os_addr_t ioc_sem_reg; | 80 | bfa_os_addr_t ioc_sem_reg; |
80 | bfa_os_addr_t ioc_usage_sem_reg; | 81 | bfa_os_addr_t ioc_usage_sem_reg; |
82 | bfa_os_addr_t ioc_init_sem_reg; | ||
81 | bfa_os_addr_t ioc_usage_reg; | 83 | bfa_os_addr_t ioc_usage_reg; |
82 | bfa_os_addr_t host_page_num_fn; | 84 | bfa_os_addr_t host_page_num_fn; |
83 | bfa_os_addr_t heartbeat; | 85 | bfa_os_addr_t heartbeat; |
84 | bfa_os_addr_t ioc_fwstate; | 86 | bfa_os_addr_t ioc_fwstate; |
85 | bfa_os_addr_t ll_halt; | 87 | bfa_os_addr_t ll_halt; |
88 | bfa_os_addr_t err_set; | ||
86 | bfa_os_addr_t shirq_isr_next; | 89 | bfa_os_addr_t shirq_isr_next; |
87 | bfa_os_addr_t shirq_msk_next; | 90 | bfa_os_addr_t shirq_msk_next; |
88 | bfa_os_addr_t smem_page_start; | 91 | bfa_os_addr_t smem_page_start; |
@@ -154,7 +157,6 @@ struct bfa_ioc_s { | |||
154 | struct bfa_timer_s ioc_timer; | 157 | struct bfa_timer_s ioc_timer; |
155 | struct bfa_timer_s sem_timer; | 158 | struct bfa_timer_s sem_timer; |
156 | u32 hb_count; | 159 | u32 hb_count; |
157 | u32 hb_fail; | ||
158 | u32 retry_count; | 160 | u32 retry_count; |
159 | struct list_head hb_notify_q; | 161 | struct list_head hb_notify_q; |
160 | void *dbg_fwsave; | 162 | void *dbg_fwsave; |
@@ -177,6 +179,22 @@ struct bfa_ioc_s { | |||
177 | struct bfi_ioc_attr_s *attr; | 179 | struct bfi_ioc_attr_s *attr; |
178 | struct bfa_ioc_cbfn_s *cbfn; | 180 | struct bfa_ioc_cbfn_s *cbfn; |
179 | struct bfa_ioc_mbox_mod_s mbox_mod; | 181 | struct bfa_ioc_mbox_mod_s mbox_mod; |
182 | struct bfa_ioc_hwif_s *ioc_hwif; | ||
183 | }; | ||
184 | |||
185 | struct bfa_ioc_hwif_s { | ||
186 | bfa_status_t (*ioc_pll_init) (struct bfa_ioc_s *ioc); | ||
187 | bfa_boolean_t (*ioc_firmware_lock) (struct bfa_ioc_s *ioc); | ||
188 | void (*ioc_firmware_unlock) (struct bfa_ioc_s *ioc); | ||
189 | u32 * (*ioc_fwimg_get_chunk) (struct bfa_ioc_s *ioc, | ||
190 | u32 off); | ||
191 | u32 (*ioc_fwimg_get_size) (struct bfa_ioc_s *ioc); | ||
192 | void (*ioc_reg_init) (struct bfa_ioc_s *ioc); | ||
193 | void (*ioc_map_port) (struct bfa_ioc_s *ioc); | ||
194 | void (*ioc_isr_mode_set) (struct bfa_ioc_s *ioc, | ||
195 | bfa_boolean_t msix); | ||
196 | void (*ioc_notify_hbfail) (struct bfa_ioc_s *ioc); | ||
197 | void (*ioc_ownership_reset) (struct bfa_ioc_s *ioc); | ||
180 | }; | 198 | }; |
181 | 199 | ||
182 | #define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) | 200 | #define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) |
@@ -191,6 +209,15 @@ struct bfa_ioc_s { | |||
191 | #define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit) | 209 | #define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit) |
192 | #define bfa_ioc_speed_sup(__ioc) \ | 210 | #define bfa_ioc_speed_sup(__ioc) \ |
193 | BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop) | 211 | BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop) |
212 | #define bfa_ioc_get_nports(__ioc) \ | ||
213 | BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop) | ||
214 | |||
215 | #define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++) | ||
216 | #define BFA_IOC_FWIMG_MINSZ (16 * 1024) | ||
217 | |||
218 | #define BFA_IOC_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS) | ||
219 | #define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS) | ||
220 | #define BFA_IOC_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS) | ||
194 | 221 | ||
195 | /** | 222 | /** |
196 | * IOC mailbox interface | 223 | * IOC mailbox interface |
@@ -207,6 +234,14 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc, | |||
207 | /** | 234 | /** |
208 | * IOC interfaces | 235 | * IOC interfaces |
209 | */ | 236 | */ |
237 | #define bfa_ioc_pll_init(__ioc) ((__ioc)->ioc_hwif->ioc_pll_init(__ioc)) | ||
238 | #define bfa_ioc_isr_mode_set(__ioc, __msix) \ | ||
239 | ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix)) | ||
240 | #define bfa_ioc_ownership_reset(__ioc) \ | ||
241 | ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc)) | ||
242 | |||
243 | void bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc); | ||
244 | void bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc); | ||
210 | void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, | 245 | void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, |
211 | struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod, | 246 | struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod, |
212 | struct bfa_trc_mod_s *trcmod, | 247 | struct bfa_trc_mod_s *trcmod, |
@@ -223,13 +258,21 @@ bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc); | |||
223 | void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param); | 258 | void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param); |
224 | void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg); | 259 | void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg); |
225 | void bfa_ioc_error_isr(struct bfa_ioc_s *ioc); | 260 | void bfa_ioc_error_isr(struct bfa_ioc_s *ioc); |
226 | void bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t intx); | ||
227 | bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc); | ||
228 | bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc); | 261 | bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc); |
229 | bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc); | 262 | bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc); |
230 | bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc); | 263 | bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc); |
231 | bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc); | 264 | bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc); |
232 | void bfa_ioc_cfg_complete(struct bfa_ioc_s *ioc); | 265 | void bfa_ioc_cfg_complete(struct bfa_ioc_s *ioc); |
266 | enum bfa_ioc_type_e bfa_ioc_get_type(struct bfa_ioc_s *ioc); | ||
267 | void bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num); | ||
268 | void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver); | ||
269 | void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver); | ||
270 | void bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model); | ||
271 | void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, | ||
272 | char *manufacturer); | ||
273 | void bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev); | ||
274 | enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc_s *ioc); | ||
275 | |||
233 | void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr); | 276 | void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr); |
234 | void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, | 277 | void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, |
235 | struct bfa_adapter_attr_s *ad_attr); | 278 | struct bfa_adapter_attr_s *ad_attr); |
@@ -237,6 +280,7 @@ int bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover); | |||
237 | void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave); | 280 | void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave); |
238 | bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, | 281 | bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, |
239 | int *trclen); | 282 | int *trclen); |
283 | void bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc); | ||
240 | bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, | 284 | bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, |
241 | int *trclen); | 285 | int *trclen); |
242 | u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr); | 286 | u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr); |
@@ -245,6 +289,13 @@ void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc); | |||
245 | bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc); | 289 | bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc); |
246 | void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc, | 290 | void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc, |
247 | struct bfa_ioc_hbfail_notify_s *notify); | 291 | struct bfa_ioc_hbfail_notify_s *notify); |
292 | bfa_boolean_t bfa_ioc_sem_get(bfa_os_addr_t sem_reg); | ||
293 | void bfa_ioc_sem_release(bfa_os_addr_t sem_reg); | ||
294 | void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc); | ||
295 | void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, | ||
296 | struct bfi_ioc_image_hdr_s *fwhdr); | ||
297 | bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, | ||
298 | struct bfi_ioc_image_hdr_s *fwhdr); | ||
248 | 299 | ||
249 | /* | 300 | /* |
250 | * bfa mfg wwn API functions | 301 | * bfa mfg wwn API functions |
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c new file mode 100644 index 000000000000..3ce85319f739 --- /dev/null +++ b/drivers/scsi/bfa/bfa_ioc_cb.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. | ||
3 | * All rights reserved | ||
4 | * www.brocade.com | ||
5 | * | ||
6 | * Linux driver for Brocade Fibre Channel Host Bus Adapter. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License (GPL) Version 2 as | ||
10 | * published by the Free Software Foundation | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <bfa.h> | ||
19 | #include <bfa_ioc.h> | ||
20 | #include <bfa_fwimg_priv.h> | ||
21 | #include <cna/bfa_cna_trcmod.h> | ||
22 | #include <cs/bfa_debug.h> | ||
23 | #include <bfi/bfi_ioc.h> | ||
24 | #include <bfi/bfi_cbreg.h> | ||
25 | #include <log/bfa_log_hal.h> | ||
26 | #include <defs/bfa_defs_pci.h> | ||
27 | |||
28 | BFA_TRC_FILE(CNA, IOC_CB); | ||
29 | |||
30 | /* | ||
31 | * forward declarations | ||
32 | */ | ||
33 | static bfa_status_t bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc); | ||
34 | static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc); | ||
35 | static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc); | ||
36 | static u32 *bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off); | ||
37 | static u32 bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc); | ||
38 | static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc); | ||
39 | static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc); | ||
40 | static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); | ||
41 | static void bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc); | ||
42 | static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc); | ||
43 | |||
44 | struct bfa_ioc_hwif_s hwif_cb = { | ||
45 | bfa_ioc_cb_pll_init, | ||
46 | bfa_ioc_cb_firmware_lock, | ||
47 | bfa_ioc_cb_firmware_unlock, | ||
48 | bfa_ioc_cb_fwimg_get_chunk, | ||
49 | bfa_ioc_cb_fwimg_get_size, | ||
50 | bfa_ioc_cb_reg_init, | ||
51 | bfa_ioc_cb_map_port, | ||
52 | bfa_ioc_cb_isr_mode_set, | ||
53 | bfa_ioc_cb_notify_hbfail, | ||
54 | bfa_ioc_cb_ownership_reset, | ||
55 | }; | ||
56 | |||
57 | /** | ||
58 | * Called from bfa_ioc_attach() to map asic specific calls. | ||
59 | */ | ||
60 | void | ||
61 | bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc) | ||
62 | { | ||
63 | ioc->ioc_hwif = &hwif_cb; | ||
64 | } | ||
65 | |||
66 | static u32 * | ||
67 | bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off) | ||
68 | { | ||
69 | return bfi_image_cb_get_chunk(off); | ||
70 | } | ||
71 | |||
72 | static u32 | ||
73 | bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc) | ||
74 | { | ||
75 | return bfi_image_cb_size; | ||
76 | } | ||
77 | |||
78 | /** | ||
79 | * Return true if firmware of current driver matches the running firmware. | ||
80 | */ | ||
81 | static bfa_boolean_t | ||
82 | bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc) | ||
83 | { | ||
84 | return BFA_TRUE; | ||
85 | } | ||
86 | |||
87 | static void | ||
88 | bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc) | ||
89 | { | ||
90 | } | ||
91 | |||
92 | /** | ||
93 | * Notify other functions on HB failure. | ||
94 | */ | ||
95 | static void | ||
96 | bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc) | ||
97 | { | ||
98 | bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET); | ||
99 | bfa_reg_read(ioc->ioc_regs.err_set); | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * Host to LPU mailbox message addresses | ||
104 | */ | ||
105 | static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { | ||
106 | { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, | ||
107 | { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 } | ||
108 | }; | ||
109 | |||
110 | /** | ||
111 | * Host <-> LPU mailbox command/status registers | ||
112 | */ | ||
113 | static struct { u32 hfn, lpu; } iocreg_mbcmd[] = { | ||
114 | { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT }, | ||
115 | { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT } | ||
116 | }; | ||
117 | |||
118 | static void | ||
119 | bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc) | ||
120 | { | ||
121 | bfa_os_addr_t rb; | ||
122 | int pcifn = bfa_ioc_pcifn(ioc); | ||
123 | |||
124 | rb = bfa_ioc_bar0(ioc); | ||
125 | |||
126 | ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox; | ||
127 | ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox; | ||
128 | ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn; | ||
129 | |||
130 | if (ioc->port_id == 0) { | ||
131 | ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; | ||
132 | ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; | ||
133 | } else { | ||
134 | ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); | ||
135 | ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * Host <-> LPU mailbox command/status registers | ||
140 | */ | ||
141 | ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd[pcifn].hfn; | ||
142 | ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd[pcifn].lpu; | ||
143 | |||
144 | /* | ||
145 | * PSS control registers | ||
146 | */ | ||
147 | ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); | ||
148 | ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG); | ||
149 | ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_400_CTL_REG); | ||
150 | ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_212_CTL_REG); | ||
151 | |||
152 | /* | ||
153 | * IOC semaphore registers and serialization | ||
154 | */ | ||
155 | ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); | ||
156 | ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG); | ||
157 | |||
158 | /** | ||
159 | * sram memory access | ||
160 | */ | ||
161 | ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); | ||
162 | ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB; | ||
163 | |||
164 | /* | ||
165 | * err set reg : for notification of hb failure | ||
166 | */ | ||
167 | ioc->ioc_regs.err_set = (rb + ERR_SET_REG); | ||
168 | } | ||
169 | |||
170 | /** | ||
171 | * Initialize IOC to port mapping. | ||
172 | */ | ||
173 | static void | ||
174 | bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc) | ||
175 | { | ||
176 | /** | ||
177 | * For crossbow, port id is same as pci function. | ||
178 | */ | ||
179 | ioc->port_id = bfa_ioc_pcifn(ioc); | ||
180 | bfa_trc(ioc, ioc->port_id); | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * Set interrupt mode for a function: INTX or MSIX | ||
185 | */ | ||
186 | static void | ||
187 | bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) | ||
188 | { | ||
189 | } | ||
190 | |||
191 | static bfa_status_t | ||
192 | bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc) | ||
193 | { | ||
194 | bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; | ||
195 | u32 pll_sclk, pll_fclk; | ||
196 | |||
197 | /* | ||
198 | * Hold semaphore so that nobody can access the chip during init. | ||
199 | */ | ||
200 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); | ||
201 | |||
202 | pll_sclk = __APP_PLL_212_ENABLE | __APP_PLL_212_LRESETN | | ||
203 | __APP_PLL_212_P0_1(3U) | | ||
204 | __APP_PLL_212_JITLMT0_1(3U) | | ||
205 | __APP_PLL_212_CNTLMT0_1(3U); | ||
206 | pll_fclk = __APP_PLL_400_ENABLE | __APP_PLL_400_LRESETN | | ||
207 | __APP_PLL_400_RSEL200500 | __APP_PLL_400_P0_1(3U) | | ||
208 | __APP_PLL_400_JITLMT0_1(3U) | | ||
209 | __APP_PLL_400_CNTLMT0_1(3U); | ||
210 | |||
211 | bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT); | ||
212 | bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT); | ||
213 | |||
214 | bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); | ||
215 | bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); | ||
216 | bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); | ||
217 | bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); | ||
218 | bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); | ||
219 | bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); | ||
220 | |||
221 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, | ||
222 | __APP_PLL_212_LOGIC_SOFT_RESET); | ||
223 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, | ||
224 | __APP_PLL_212_BYPASS | | ||
225 | __APP_PLL_212_LOGIC_SOFT_RESET); | ||
226 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, | ||
227 | __APP_PLL_400_LOGIC_SOFT_RESET); | ||
228 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, | ||
229 | __APP_PLL_400_BYPASS | | ||
230 | __APP_PLL_400_LOGIC_SOFT_RESET); | ||
231 | bfa_os_udelay(2); | ||
232 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, | ||
233 | __APP_PLL_212_LOGIC_SOFT_RESET); | ||
234 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, | ||
235 | __APP_PLL_400_LOGIC_SOFT_RESET); | ||
236 | |||
237 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, | ||
238 | pll_sclk | __APP_PLL_212_LOGIC_SOFT_RESET); | ||
239 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, | ||
240 | pll_fclk | __APP_PLL_400_LOGIC_SOFT_RESET); | ||
241 | |||
242 | /** | ||
243 | * Wait for PLLs to lock. | ||
244 | */ | ||
245 | bfa_os_udelay(2000); | ||
246 | bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); | ||
247 | bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); | ||
248 | |||
249 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk); | ||
250 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk); | ||
251 | |||
252 | /* | ||
253 | * release semaphore. | ||
254 | */ | ||
255 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); | ||
256 | |||
257 | return BFA_STATUS_OK; | ||
258 | } | ||
259 | |||
260 | /** | ||
261 | * Cleanup hw semaphore and usecnt registers | ||
262 | */ | ||
263 | static void | ||
264 | bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc) | ||
265 | { | ||
266 | |||
267 | /* | ||
268 | * Read the hw sem reg to make sure that it is locked | ||
269 | * before we clear it. If it is not locked, writing 1 | ||
270 | * will lock it instead of clearing it. | ||
271 | */ | ||
272 | bfa_reg_read(ioc->ioc_regs.ioc_sem_reg); | ||
273 | bfa_ioc_hw_sem_release(ioc); | ||
274 | } | ||
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c new file mode 100644 index 000000000000..20b58ad5f95c --- /dev/null +++ b/drivers/scsi/bfa/bfa_ioc_ct.c | |||
@@ -0,0 +1,423 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. | ||
3 | * All rights reserved | ||
4 | * www.brocade.com | ||
5 | * | ||
6 | * Linux driver for Brocade Fibre Channel Host Bus Adapter. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License (GPL) Version 2 as | ||
10 | * published by the Free Software Foundation | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <bfa.h> | ||
19 | #include <bfa_ioc.h> | ||
20 | #include <bfa_fwimg_priv.h> | ||
21 | #include <cna/bfa_cna_trcmod.h> | ||
22 | #include <cs/bfa_debug.h> | ||
23 | #include <bfi/bfi_ioc.h> | ||
24 | #include <bfi/bfi_ctreg.h> | ||
25 | #include <log/bfa_log_hal.h> | ||
26 | #include <defs/bfa_defs_pci.h> | ||
27 | |||
28 | BFA_TRC_FILE(CNA, IOC_CT); | ||
29 | |||
30 | /* | ||
31 | * forward declarations | ||
32 | */ | ||
33 | static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc); | ||
34 | static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc); | ||
35 | static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc); | ||
36 | static u32* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, | ||
37 | u32 off); | ||
38 | static u32 bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc); | ||
39 | static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc); | ||
40 | static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc); | ||
41 | static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); | ||
42 | static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc); | ||
43 | static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc); | ||
44 | |||
45 | struct bfa_ioc_hwif_s hwif_ct = { | ||
46 | bfa_ioc_ct_pll_init, | ||
47 | bfa_ioc_ct_firmware_lock, | ||
48 | bfa_ioc_ct_firmware_unlock, | ||
49 | bfa_ioc_ct_fwimg_get_chunk, | ||
50 | bfa_ioc_ct_fwimg_get_size, | ||
51 | bfa_ioc_ct_reg_init, | ||
52 | bfa_ioc_ct_map_port, | ||
53 | bfa_ioc_ct_isr_mode_set, | ||
54 | bfa_ioc_ct_notify_hbfail, | ||
55 | bfa_ioc_ct_ownership_reset, | ||
56 | }; | ||
57 | |||
58 | /** | ||
59 | * Called from bfa_ioc_attach() to map asic specific calls. | ||
60 | */ | ||
61 | void | ||
62 | bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc) | ||
63 | { | ||
64 | ioc->ioc_hwif = &hwif_ct; | ||
65 | } | ||
66 | |||
67 | static u32* | ||
68 | bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off) | ||
69 | { | ||
70 | return bfi_image_ct_get_chunk(off); | ||
71 | } | ||
72 | |||
73 | static u32 | ||
74 | bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc) | ||
75 | { | ||
76 | return bfi_image_ct_size; | ||
77 | } | ||
78 | |||
79 | /** | ||
80 | * Return true if firmware of current driver matches the running firmware. | ||
81 | */ | ||
82 | static bfa_boolean_t | ||
83 | bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) | ||
84 | { | ||
85 | enum bfi_ioc_state ioc_fwstate; | ||
86 | u32 usecnt; | ||
87 | struct bfi_ioc_image_hdr_s fwhdr; | ||
88 | |||
89 | /** | ||
90 | * Firmware match check is relevant only for CNA. | ||
91 | */ | ||
92 | if (!ioc->cna) | ||
93 | return BFA_TRUE; | ||
94 | |||
95 | /** | ||
96 | * If bios boot (flash based) -- do not increment usage count | ||
97 | */ | ||
98 | if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) | ||
99 | return BFA_TRUE; | ||
100 | |||
101 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); | ||
102 | usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); | ||
103 | |||
104 | /** | ||
105 | * If usage count is 0, always return TRUE. | ||
106 | */ | ||
107 | if (usecnt == 0) { | ||
108 | bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1); | ||
109 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); | ||
110 | bfa_trc(ioc, usecnt); | ||
111 | return BFA_TRUE; | ||
112 | } | ||
113 | |||
114 | ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate); | ||
115 | bfa_trc(ioc, ioc_fwstate); | ||
116 | |||
117 | /** | ||
118 | * Use count cannot be non-zero and chip in uninitialized state. | ||
119 | */ | ||
120 | bfa_assert(ioc_fwstate != BFI_IOC_UNINIT); | ||
121 | |||
122 | /** | ||
123 | * Check if another driver with a different firmware is active | ||
124 | */ | ||
125 | bfa_ioc_fwver_get(ioc, &fwhdr); | ||
126 | if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { | ||
127 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); | ||
128 | bfa_trc(ioc, usecnt); | ||
129 | return BFA_FALSE; | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * Same firmware version. Increment the reference count. | ||
134 | */ | ||
135 | usecnt++; | ||
136 | bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); | ||
137 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); | ||
138 | bfa_trc(ioc, usecnt); | ||
139 | return BFA_TRUE; | ||
140 | } | ||
141 | |||
142 | static void | ||
143 | bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc) | ||
144 | { | ||
145 | u32 usecnt; | ||
146 | |||
147 | /** | ||
148 | * Firmware lock is relevant only for CNA. | ||
149 | * If bios boot (flash based) -- do not decrement usage count | ||
150 | */ | ||
151 | if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) | ||
152 | return; | ||
153 | |||
154 | /** | ||
155 | * decrement usage count | ||
156 | */ | ||
157 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); | ||
158 | usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); | ||
159 | bfa_assert(usecnt > 0); | ||
160 | |||
161 | usecnt--; | ||
162 | bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); | ||
163 | bfa_trc(ioc, usecnt); | ||
164 | |||
165 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * Notify other functions on HB failure. | ||
170 | */ | ||
171 | static void | ||
172 | bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc) | ||
173 | { | ||
174 | if (ioc->cna) { | ||
175 | bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P); | ||
176 | /* Wait for halt to take effect */ | ||
177 | bfa_reg_read(ioc->ioc_regs.ll_halt); | ||
178 | } else { | ||
179 | bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET); | ||
180 | bfa_reg_read(ioc->ioc_regs.err_set); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | /** | ||
185 | * Host to LPU mailbox message addresses | ||
186 | */ | ||
187 | static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { | ||
188 | { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, | ||
189 | { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }, | ||
190 | { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 }, | ||
191 | { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 } | ||
192 | }; | ||
193 | |||
194 | /** | ||
195 | * Host <-> LPU mailbox command/status registers - port 0 | ||
196 | */ | ||
197 | static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = { | ||
198 | { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT }, | ||
199 | { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT }, | ||
200 | { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT }, | ||
201 | { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT } | ||
202 | }; | ||
203 | |||
204 | /** | ||
205 | * Host <-> LPU mailbox command/status registers - port 1 | ||
206 | */ | ||
207 | static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = { | ||
208 | { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT }, | ||
209 | { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT }, | ||
210 | { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT }, | ||
211 | { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT } | ||
212 | }; | ||
213 | |||
214 | static void | ||
215 | bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc) | ||
216 | { | ||
217 | bfa_os_addr_t rb; | ||
218 | int pcifn = bfa_ioc_pcifn(ioc); | ||
219 | |||
220 | rb = bfa_ioc_bar0(ioc); | ||
221 | |||
222 | ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox; | ||
223 | ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox; | ||
224 | ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn; | ||
225 | |||
226 | if (ioc->port_id == 0) { | ||
227 | ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; | ||
228 | ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; | ||
229 | ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn; | ||
230 | ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu; | ||
231 | ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; | ||
232 | } else { | ||
233 | ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); | ||
234 | ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); | ||
235 | ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn; | ||
236 | ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu; | ||
237 | ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; | ||
238 | } | ||
239 | |||
240 | /* | ||
241 | * PSS control registers | ||
242 | */ | ||
243 | ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); | ||
244 | ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG); | ||
245 | ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG); | ||
246 | ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG); | ||
247 | |||
248 | /* | ||
249 | * IOC semaphore registers and serialization | ||
250 | */ | ||
251 | ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); | ||
252 | ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG); | ||
253 | ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG); | ||
254 | ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT); | ||
255 | |||
256 | /** | ||
257 | * sram memory access | ||
258 | */ | ||
259 | ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); | ||
260 | ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; | ||
261 | |||
262 | /* | ||
263 | * err set reg : for notification of hb failure in fcmode | ||
264 | */ | ||
265 | ioc->ioc_regs.err_set = (rb + ERR_SET_REG); | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * Initialize IOC to port mapping. | ||
270 | */ | ||
271 | |||
272 | #define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8) | ||
273 | static void | ||
274 | bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc) | ||
275 | { | ||
276 | bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; | ||
277 | u32 r32; | ||
278 | |||
279 | /** | ||
280 | * For catapult, base port id on personality register and IOC type | ||
281 | */ | ||
282 | r32 = bfa_reg_read(rb + FNC_PERS_REG); | ||
283 | r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)); | ||
284 | ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH; | ||
285 | |||
286 | bfa_trc(ioc, bfa_ioc_pcifn(ioc)); | ||
287 | bfa_trc(ioc, ioc->port_id); | ||
288 | } | ||
289 | |||
290 | /** | ||
291 | * Set interrupt mode for a function: INTX or MSIX | ||
292 | */ | ||
293 | static void | ||
294 | bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) | ||
295 | { | ||
296 | bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; | ||
297 | u32 r32, mode; | ||
298 | |||
299 | r32 = bfa_reg_read(rb + FNC_PERS_REG); | ||
300 | bfa_trc(ioc, r32); | ||
301 | |||
302 | mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) & | ||
303 | __F0_INTX_STATUS; | ||
304 | |||
305 | /** | ||
306 | * If already in desired mode, do not change anything | ||
307 | */ | ||
308 | if (!msix && mode) | ||
309 | return; | ||
310 | |||
311 | if (msix) | ||
312 | mode = __F0_INTX_STATUS_MSIX; | ||
313 | else | ||
314 | mode = __F0_INTX_STATUS_INTA; | ||
315 | |||
316 | r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); | ||
317 | r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); | ||
318 | bfa_trc(ioc, r32); | ||
319 | |||
320 | bfa_reg_write(rb + FNC_PERS_REG, r32); | ||
321 | } | ||
322 | |||
323 | static bfa_status_t | ||
324 | bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc) | ||
325 | { | ||
326 | bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; | ||
327 | u32 pll_sclk, pll_fclk, r32; | ||
328 | |||
329 | /* | ||
330 | * Hold semaphore so that nobody can access the chip during init. | ||
331 | */ | ||
332 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); | ||
333 | |||
334 | pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST | | ||
335 | __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) | | ||
336 | __APP_PLL_312_JITLMT0_1(3U) | | ||
337 | __APP_PLL_312_CNTLMT0_1(1U); | ||
338 | pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST | | ||
339 | __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) | | ||
340 | __APP_PLL_425_JITLMT0_1(3U) | | ||
341 | __APP_PLL_425_CNTLMT0_1(1U); | ||
342 | |||
343 | /** | ||
344 | * For catapult, choose operational mode FC/FCoE | ||
345 | */ | ||
346 | if (ioc->fcmode) { | ||
347 | bfa_reg_write((rb + OP_MODE), 0); | ||
348 | bfa_reg_write((rb + ETH_MAC_SER_REG), | ||
349 | __APP_EMS_CMLCKSEL | | ||
350 | __APP_EMS_REFCKBUFEN2 | | ||
351 | __APP_EMS_CHANNEL_SEL); | ||
352 | } else { | ||
353 | ioc->pllinit = BFA_TRUE; | ||
354 | bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE); | ||
355 | bfa_reg_write((rb + ETH_MAC_SER_REG), | ||
356 | __APP_EMS_REFCKBUFEN1); | ||
357 | } | ||
358 | |||
359 | bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT); | ||
360 | bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT); | ||
361 | |||
362 | bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); | ||
363 | bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); | ||
364 | bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); | ||
365 | bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); | ||
366 | bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); | ||
367 | bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); | ||
368 | |||
369 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk | | ||
370 | __APP_PLL_312_LOGIC_SOFT_RESET); | ||
371 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk | | ||
372 | __APP_PLL_425_LOGIC_SOFT_RESET); | ||
373 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk | | ||
374 | __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE); | ||
375 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk | | ||
376 | __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE); | ||
377 | |||
378 | /** | ||
379 | * Wait for PLLs to lock. | ||
380 | */ | ||
381 | bfa_reg_read(rb + HOSTFN0_INT_MSK); | ||
382 | bfa_os_udelay(2000); | ||
383 | bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); | ||
384 | bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); | ||
385 | |||
386 | bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk | | ||
387 | __APP_PLL_312_ENABLE); | ||
388 | bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk | | ||
389 | __APP_PLL_425_ENABLE); | ||
390 | |||
391 | bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START); | ||
392 | bfa_os_udelay(1000); | ||
393 | r32 = bfa_reg_read((rb + MBIST_STAT_REG)); | ||
394 | bfa_trc(ioc, r32); | ||
395 | /* | ||
396 | * release semaphore. | ||
397 | */ | ||
398 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); | ||
399 | |||
400 | return BFA_STATUS_OK; | ||
401 | } | ||
402 | |||
403 | /** | ||
404 | * Cleanup hw semaphore and usecnt registers | ||
405 | */ | ||
406 | static void | ||
407 | bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc) | ||
408 | { | ||
409 | |||
410 | if (ioc->cna) { | ||
411 | bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); | ||
412 | bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0); | ||
413 | bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); | ||
414 | } | ||
415 | |||
416 | /* | ||
417 | * Read the hw sem reg to make sure that it is locked | ||
418 | * before we clear it. If it is not locked, writing 1 | ||
419 | * will lock it instead of clearing it. | ||
420 | */ | ||
421 | bfa_reg_read(ioc->ioc_regs.ioc_sem_reg); | ||
422 | bfa_ioc_hw_sem_release(ioc); | ||
423 | } | ||
diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c index d7ab792a9e54..a76de2669bfc 100644 --- a/drivers/scsi/bfa/bfa_iocfc.c +++ b/drivers/scsi/bfa/bfa_iocfc.c | |||
@@ -172,6 +172,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
172 | */ | 172 | */ |
173 | if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) { | 173 | if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) { |
174 | iocfc->hwif.hw_reginit = bfa_hwct_reginit; | 174 | iocfc->hwif.hw_reginit = bfa_hwct_reginit; |
175 | iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack; | ||
175 | iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack; | 176 | iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack; |
176 | iocfc->hwif.hw_msix_init = bfa_hwct_msix_init; | 177 | iocfc->hwif.hw_msix_init = bfa_hwct_msix_init; |
177 | iocfc->hwif.hw_msix_install = bfa_hwct_msix_install; | 178 | iocfc->hwif.hw_msix_install = bfa_hwct_msix_install; |
@@ -180,6 +181,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
180 | iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs; | 181 | iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs; |
181 | } else { | 182 | } else { |
182 | iocfc->hwif.hw_reginit = bfa_hwcb_reginit; | 183 | iocfc->hwif.hw_reginit = bfa_hwcb_reginit; |
184 | iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack; | ||
183 | iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack; | 185 | iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack; |
184 | iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init; | 186 | iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init; |
185 | iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install; | 187 | iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install; |
@@ -336,8 +338,10 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete) | |||
336 | bfa_cb_init(bfa->bfad, BFA_STATUS_OK); | 338 | bfa_cb_init(bfa->bfad, BFA_STATUS_OK); |
337 | else | 339 | else |
338 | bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED); | 340 | bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED); |
339 | } else | 341 | } else { |
340 | bfa->iocfc.action = BFA_IOCFC_ACT_NONE; | 342 | if (bfa->iocfc.cfgdone) |
343 | bfa->iocfc.action = BFA_IOCFC_ACT_NONE; | ||
344 | } | ||
341 | } | 345 | } |
342 | 346 | ||
343 | static void | 347 | static void |
@@ -619,8 +623,6 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
619 | 623 | ||
620 | bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod, | 624 | bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod, |
621 | bfa->trcmod, bfa->aen, bfa->logm); | 625 | bfa->trcmod, bfa->aen, bfa->logm); |
622 | bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC); | ||
623 | bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs); | ||
624 | 626 | ||
625 | /** | 627 | /** |
626 | * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode. | 628 | * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode. |
@@ -628,6 +630,9 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
628 | if (0) | 630 | if (0) |
629 | bfa_ioc_set_fcmode(&bfa->ioc); | 631 | bfa_ioc_set_fcmode(&bfa->ioc); |
630 | 632 | ||
633 | bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC); | ||
634 | bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs); | ||
635 | |||
631 | bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev); | 636 | bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev); |
632 | bfa_iocfc_mem_claim(bfa, cfg, meminfo); | 637 | bfa_iocfc_mem_claim(bfa, cfg, meminfo); |
633 | bfa_timer_init(&bfa->timer_mod); | 638 | bfa_timer_init(&bfa->timer_mod); |
@@ -654,7 +659,6 @@ bfa_iocfc_init(struct bfa_s *bfa) | |||
654 | { | 659 | { |
655 | bfa->iocfc.action = BFA_IOCFC_ACT_INIT; | 660 | bfa->iocfc.action = BFA_IOCFC_ACT_INIT; |
656 | bfa_ioc_enable(&bfa->ioc); | 661 | bfa_ioc_enable(&bfa->ioc); |
657 | bfa_msix_install(bfa); | ||
658 | } | 662 | } |
659 | 663 | ||
660 | /** | 664 | /** |
@@ -797,6 +801,11 @@ bfa_iocfc_get_stats(struct bfa_s *bfa, struct bfa_iocfc_stats_s *stats, | |||
797 | return BFA_STATUS_DEVBUSY; | 801 | return BFA_STATUS_DEVBUSY; |
798 | } | 802 | } |
799 | 803 | ||
804 | if (!bfa_iocfc_is_operational(bfa)) { | ||
805 | bfa_trc(bfa, 0); | ||
806 | return BFA_STATUS_IOC_NON_OP; | ||
807 | } | ||
808 | |||
800 | iocfc->stats_busy = BFA_TRUE; | 809 | iocfc->stats_busy = BFA_TRUE; |
801 | iocfc->stats_ret = stats; | 810 | iocfc->stats_ret = stats; |
802 | iocfc->stats_cbfn = cbfn; | 811 | iocfc->stats_cbfn = cbfn; |
@@ -817,6 +826,11 @@ bfa_iocfc_clear_stats(struct bfa_s *bfa, bfa_cb_ioc_t cbfn, void *cbarg) | |||
817 | return BFA_STATUS_DEVBUSY; | 826 | return BFA_STATUS_DEVBUSY; |
818 | } | 827 | } |
819 | 828 | ||
829 | if (!bfa_iocfc_is_operational(bfa)) { | ||
830 | bfa_trc(bfa, 0); | ||
831 | return BFA_STATUS_IOC_NON_OP; | ||
832 | } | ||
833 | |||
820 | iocfc->stats_busy = BFA_TRUE; | 834 | iocfc->stats_busy = BFA_TRUE; |
821 | iocfc->stats_cbfn = cbfn; | 835 | iocfc->stats_cbfn = cbfn; |
822 | iocfc->stats_cbarg = cbarg; | 836 | iocfc->stats_cbarg = cbarg; |
diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h index ce9a830a4207..fbb4bdc9d600 100644 --- a/drivers/scsi/bfa/bfa_iocfc.h +++ b/drivers/scsi/bfa/bfa_iocfc.h | |||
@@ -54,6 +54,7 @@ struct bfa_msix_s { | |||
54 | */ | 54 | */ |
55 | struct bfa_hwif_s { | 55 | struct bfa_hwif_s { |
56 | void (*hw_reginit)(struct bfa_s *bfa); | 56 | void (*hw_reginit)(struct bfa_s *bfa); |
57 | void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq); | ||
57 | void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq); | 58 | void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq); |
58 | void (*hw_msix_init)(struct bfa_s *bfa, int nvecs); | 59 | void (*hw_msix_init)(struct bfa_s *bfa, int nvecs); |
59 | void (*hw_msix_install)(struct bfa_s *bfa); | 60 | void (*hw_msix_install)(struct bfa_s *bfa); |
@@ -143,6 +144,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec); | |||
143 | void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); | 144 | void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); |
144 | 145 | ||
145 | void bfa_hwcb_reginit(struct bfa_s *bfa); | 146 | void bfa_hwcb_reginit(struct bfa_s *bfa); |
147 | void bfa_hwcb_reqq_ack(struct bfa_s *bfa, int rspq); | ||
146 | void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq); | 148 | void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq); |
147 | void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); | 149 | void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); |
148 | void bfa_hwcb_msix_install(struct bfa_s *bfa); | 150 | void bfa_hwcb_msix_install(struct bfa_s *bfa); |
@@ -151,6 +153,7 @@ void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix); | |||
151 | void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, | 153 | void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, |
152 | u32 *nvecs, u32 *maxvec); | 154 | u32 *nvecs, u32 *maxvec); |
153 | void bfa_hwct_reginit(struct bfa_s *bfa); | 155 | void bfa_hwct_reginit(struct bfa_s *bfa); |
156 | void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq); | ||
154 | void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq); | 157 | void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq); |
155 | void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); | 158 | void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); |
156 | void bfa_hwct_msix_install(struct bfa_s *bfa); | 159 | void bfa_hwct_msix_install(struct bfa_s *bfa); |
diff --git a/drivers/scsi/bfa/bfa_ioim.c b/drivers/scsi/bfa/bfa_ioim.c index f81d359b7089..5b107abe46e5 100644 --- a/drivers/scsi/bfa/bfa_ioim.c +++ b/drivers/scsi/bfa/bfa_ioim.c | |||
@@ -149,7 +149,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
149 | break; | 149 | break; |
150 | 150 | ||
151 | default: | 151 | default: |
152 | bfa_assert(0); | 152 | bfa_sm_fault(ioim->bfa, event); |
153 | } | 153 | } |
154 | } | 154 | } |
155 | 155 | ||
@@ -194,7 +194,7 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
194 | break; | 194 | break; |
195 | 195 | ||
196 | default: | 196 | default: |
197 | bfa_assert(0); | 197 | bfa_sm_fault(ioim->bfa, event); |
198 | } | 198 | } |
199 | } | 199 | } |
200 | 200 | ||
@@ -259,7 +259,7 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
259 | break; | 259 | break; |
260 | 260 | ||
261 | default: | 261 | default: |
262 | bfa_assert(0); | 262 | bfa_sm_fault(ioim->bfa, event); |
263 | } | 263 | } |
264 | } | 264 | } |
265 | 265 | ||
@@ -317,7 +317,7 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
317 | break; | 317 | break; |
318 | 318 | ||
319 | default: | 319 | default: |
320 | bfa_assert(0); | 320 | bfa_sm_fault(ioim->bfa, event); |
321 | } | 321 | } |
322 | } | 322 | } |
323 | 323 | ||
@@ -377,7 +377,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
377 | break; | 377 | break; |
378 | 378 | ||
379 | default: | 379 | default: |
380 | bfa_assert(0); | 380 | bfa_sm_fault(ioim->bfa, event); |
381 | } | 381 | } |
382 | } | 382 | } |
383 | 383 | ||
@@ -419,7 +419,7 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
419 | break; | 419 | break; |
420 | 420 | ||
421 | default: | 421 | default: |
422 | bfa_assert(0); | 422 | bfa_sm_fault(ioim->bfa, event); |
423 | } | 423 | } |
424 | } | 424 | } |
425 | 425 | ||
@@ -467,7 +467,7 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
467 | break; | 467 | break; |
468 | 468 | ||
469 | default: | 469 | default: |
470 | bfa_assert(0); | 470 | bfa_sm_fault(ioim->bfa, event); |
471 | } | 471 | } |
472 | } | 472 | } |
473 | 473 | ||
@@ -516,7 +516,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
516 | break; | 516 | break; |
517 | 517 | ||
518 | default: | 518 | default: |
519 | bfa_assert(0); | 519 | bfa_sm_fault(ioim->bfa, event); |
520 | } | 520 | } |
521 | } | 521 | } |
522 | 522 | ||
@@ -544,7 +544,7 @@ bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
544 | break; | 544 | break; |
545 | 545 | ||
546 | default: | 546 | default: |
547 | bfa_assert(0); | 547 | bfa_sm_fault(ioim->bfa, event); |
548 | } | 548 | } |
549 | } | 549 | } |
550 | 550 | ||
@@ -577,7 +577,7 @@ bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
577 | break; | 577 | break; |
578 | 578 | ||
579 | default: | 579 | default: |
580 | bfa_assert(0); | 580 | bfa_sm_fault(ioim->bfa, event); |
581 | } | 581 | } |
582 | } | 582 | } |
583 | 583 | ||
@@ -605,7 +605,7 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) | |||
605 | break; | 605 | break; |
606 | 606 | ||
607 | default: | 607 | default: |
608 | bfa_assert(0); | 608 | bfa_sm_fault(ioim->bfa, event); |
609 | } | 609 | } |
610 | } | 610 | } |
611 | 611 | ||
diff --git a/drivers/scsi/bfa/bfa_itnim.c b/drivers/scsi/bfa/bfa_itnim.c index eabf7d38bd09..a914ff255135 100644 --- a/drivers/scsi/bfa/bfa_itnim.c +++ b/drivers/scsi/bfa/bfa_itnim.c | |||
@@ -144,7 +144,7 @@ bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | |||
144 | break; | 144 | break; |
145 | 145 | ||
146 | default: | 146 | default: |
147 | bfa_assert(0); | 147 | bfa_sm_fault(itnim->bfa, event); |
148 | } | 148 | } |
149 | } | 149 | } |
150 | 150 | ||
@@ -175,7 +175,7 @@ bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | |||
175 | break; | 175 | break; |
176 | 176 | ||
177 | default: | 177 | default: |
178 | bfa_assert(0); | 178 | bfa_sm_fault(itnim->bfa, event); |
179 | } | 179 | } |
180 | } | 180 | } |
181 | 181 | ||
@@ -212,7 +212,7 @@ bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | |||
212 | break; | 212 | break; |
213 | 213 | ||
214 | default: | 214 | default: |
215 | bfa_assert(0); | 215 | bfa_sm_fault(itnim->bfa, event); |
216 | } | 216 | } |
217 | } | 217 | } |
218 | 218 | ||
@@ -247,7 +247,7 @@ bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim, | |||
247 | break; | 247 | break; |
248 | 248 | ||
249 | default: | 249 | default: |
250 | bfa_assert(0); | 250 | bfa_sm_fault(itnim->bfa, event); |
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
@@ -275,7 +275,7 @@ bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim, | |||
275 | break; | 275 | break; |
276 | 276 | ||
277 | default: | 277 | default: |
278 | bfa_assert(0); | 278 | bfa_sm_fault(itnim->bfa, event); |
279 | } | 279 | } |
280 | } | 280 | } |
281 | 281 | ||
@@ -317,7 +317,7 @@ bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | |||
317 | break; | 317 | break; |
318 | 318 | ||
319 | default: | 319 | default: |
320 | bfa_assert(0); | 320 | bfa_sm_fault(itnim->bfa, event); |
321 | } | 321 | } |
322 | } | 322 | } |
323 | 323 | ||
@@ -348,7 +348,7 @@ bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | |||
348 | break; | 348 | break; |
349 | 349 | ||
350 | default: | 350 | default: |
351 | bfa_assert(0); | 351 | bfa_sm_fault(itnim->bfa, event); |
352 | } | 352 | } |
353 | } | 353 | } |
354 | 354 | ||
@@ -385,7 +385,7 @@ bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim, | |||
385 | break; | 385 | break; |
386 | 386 | ||
387 | default: | 387 | default: |
388 | bfa_assert(0); | 388 | bfa_sm_fault(itnim->bfa, event); |
389 | } | 389 | } |
390 | } | 390 | } |
391 | 391 | ||
@@ -413,7 +413,7 @@ bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim, | |||
413 | break; | 413 | break; |
414 | 414 | ||
415 | default: | 415 | default: |
416 | bfa_assert(0); | 416 | bfa_sm_fault(itnim->bfa, event); |
417 | } | 417 | } |
418 | } | 418 | } |
419 | 419 | ||
@@ -442,7 +442,7 @@ bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | |||
442 | break; | 442 | break; |
443 | 443 | ||
444 | default: | 444 | default: |
445 | bfa_assert(0); | 445 | bfa_sm_fault(itnim->bfa, event); |
446 | } | 446 | } |
447 | } | 447 | } |
448 | 448 | ||
@@ -470,7 +470,7 @@ bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim, | |||
470 | break; | 470 | break; |
471 | 471 | ||
472 | default: | 472 | default: |
473 | bfa_assert(0); | 473 | bfa_sm_fault(itnim->bfa, event); |
474 | } | 474 | } |
475 | } | 475 | } |
476 | 476 | ||
@@ -502,7 +502,7 @@ bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | |||
502 | break; | 502 | break; |
503 | 503 | ||
504 | default: | 504 | default: |
505 | bfa_assert(0); | 505 | bfa_sm_fault(itnim->bfa, event); |
506 | } | 506 | } |
507 | } | 507 | } |
508 | 508 | ||
@@ -538,7 +538,7 @@ bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim, | |||
538 | break; | 538 | break; |
539 | 539 | ||
540 | default: | 540 | default: |
541 | bfa_assert(0); | 541 | bfa_sm_fault(itnim->bfa, event); |
542 | } | 542 | } |
543 | } | 543 | } |
544 | 544 | ||
@@ -559,7 +559,7 @@ bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | |||
559 | break; | 559 | break; |
560 | 560 | ||
561 | default: | 561 | default: |
562 | bfa_assert(0); | 562 | bfa_sm_fault(itnim->bfa, event); |
563 | } | 563 | } |
564 | } | 564 | } |
565 | 565 | ||
@@ -583,7 +583,7 @@ bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim, | |||
583 | break; | 583 | break; |
584 | 584 | ||
585 | default: | 585 | default: |
586 | bfa_assert(0); | 586 | bfa_sm_fault(itnim->bfa, event); |
587 | } | 587 | } |
588 | } | 588 | } |
589 | 589 | ||
diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c index 9844b45412b6..ad06f6189092 100644 --- a/drivers/scsi/bfa/bfa_lps.c +++ b/drivers/scsi/bfa/bfa_lps.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <bfa.h> | 18 | #include <bfa.h> |
19 | #include <bfi/bfi_lps.h> | 19 | #include <bfi/bfi_lps.h> |
20 | #include <cs/bfa_debug.h> | 20 | #include <cs/bfa_debug.h> |
21 | #include <defs/bfa_defs_pci.h> | ||
21 | 22 | ||
22 | BFA_TRC_FILE(HAL, LPS); | 23 | BFA_TRC_FILE(HAL, LPS); |
23 | BFA_MODULE(lps); | 24 | BFA_MODULE(lps); |
@@ -25,6 +26,12 @@ BFA_MODULE(lps); | |||
25 | #define BFA_LPS_MIN_LPORTS (1) | 26 | #define BFA_LPS_MIN_LPORTS (1) |
26 | #define BFA_LPS_MAX_LPORTS (256) | 27 | #define BFA_LPS_MAX_LPORTS (256) |
27 | 28 | ||
29 | /* | ||
30 | * Maximum Vports supported per physical port or vf. | ||
31 | */ | ||
32 | #define BFA_LPS_MAX_VPORTS_SUPP_CB 255 | ||
33 | #define BFA_LPS_MAX_VPORTS_SUPP_CT 190 | ||
34 | |||
28 | /** | 35 | /** |
29 | * forward declarations | 36 | * forward declarations |
30 | */ | 37 | */ |
@@ -49,7 +56,7 @@ static void bfa_lps_send_login(struct bfa_lps_s *lps); | |||
49 | static void bfa_lps_send_logout(struct bfa_lps_s *lps); | 56 | static void bfa_lps_send_logout(struct bfa_lps_s *lps); |
50 | static void bfa_lps_login_comp(struct bfa_lps_s *lps); | 57 | static void bfa_lps_login_comp(struct bfa_lps_s *lps); |
51 | static void bfa_lps_logout_comp(struct bfa_lps_s *lps); | 58 | static void bfa_lps_logout_comp(struct bfa_lps_s *lps); |
52 | 59 | static void bfa_lps_cvl_event(struct bfa_lps_s *lps); | |
53 | 60 | ||
54 | /** | 61 | /** |
55 | * lps_pvt BFA LPS private functions | 62 | * lps_pvt BFA LPS private functions |
@@ -62,6 +69,7 @@ enum bfa_lps_event { | |||
62 | BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */ | 69 | BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */ |
63 | BFA_LPS_SM_DELETE = 5, /* lps delete from user */ | 70 | BFA_LPS_SM_DELETE = 5, /* lps delete from user */ |
64 | BFA_LPS_SM_OFFLINE = 6, /* Link is offline */ | 71 | BFA_LPS_SM_OFFLINE = 6, /* Link is offline */ |
72 | BFA_LPS_SM_RX_CVL = 7, /* Rx clear virtual link */ | ||
65 | }; | 73 | }; |
66 | 74 | ||
67 | static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event); | 75 | static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event); |
@@ -91,6 +99,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
91 | bfa_sm_set_state(lps, bfa_lps_sm_login); | 99 | bfa_sm_set_state(lps, bfa_lps_sm_login); |
92 | bfa_lps_send_login(lps); | 100 | bfa_lps_send_login(lps); |
93 | } | 101 | } |
102 | if (lps->fdisc) | ||
103 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, | ||
104 | BFA_PL_EID_LOGIN, 0, "FDISC Request"); | ||
105 | else | ||
106 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, | ||
107 | BFA_PL_EID_LOGIN, 0, "FLOGI Request"); | ||
94 | break; | 108 | break; |
95 | 109 | ||
96 | case BFA_LPS_SM_LOGOUT: | 110 | case BFA_LPS_SM_LOGOUT: |
@@ -101,6 +115,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
101 | bfa_lps_free(lps); | 115 | bfa_lps_free(lps); |
102 | break; | 116 | break; |
103 | 117 | ||
118 | case BFA_LPS_SM_RX_CVL: | ||
104 | case BFA_LPS_SM_OFFLINE: | 119 | case BFA_LPS_SM_OFFLINE: |
105 | break; | 120 | break; |
106 | 121 | ||
@@ -112,7 +127,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
112 | break; | 127 | break; |
113 | 128 | ||
114 | default: | 129 | default: |
115 | bfa_assert(0); | 130 | bfa_sm_fault(lps->bfa, event); |
116 | } | 131 | } |
117 | } | 132 | } |
118 | 133 | ||
@@ -127,10 +142,25 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
127 | 142 | ||
128 | switch (event) { | 143 | switch (event) { |
129 | case BFA_LPS_SM_FWRSP: | 144 | case BFA_LPS_SM_FWRSP: |
130 | if (lps->status == BFA_STATUS_OK) | 145 | if (lps->status == BFA_STATUS_OK) { |
131 | bfa_sm_set_state(lps, bfa_lps_sm_online); | 146 | bfa_sm_set_state(lps, bfa_lps_sm_online); |
132 | else | 147 | if (lps->fdisc) |
148 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, | ||
149 | BFA_PL_EID_LOGIN, 0, "FDISC Accept"); | ||
150 | else | ||
151 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, | ||
152 | BFA_PL_EID_LOGIN, 0, "FLOGI Accept"); | ||
153 | } else { | ||
133 | bfa_sm_set_state(lps, bfa_lps_sm_init); | 154 | bfa_sm_set_state(lps, bfa_lps_sm_init); |
155 | if (lps->fdisc) | ||
156 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, | ||
157 | BFA_PL_EID_LOGIN, 0, | ||
158 | "FDISC Fail (RJT or timeout)"); | ||
159 | else | ||
160 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, | ||
161 | BFA_PL_EID_LOGIN, 0, | ||
162 | "FLOGI Fail (RJT or timeout)"); | ||
163 | } | ||
134 | bfa_lps_login_comp(lps); | 164 | bfa_lps_login_comp(lps); |
135 | break; | 165 | break; |
136 | 166 | ||
@@ -139,7 +169,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
139 | break; | 169 | break; |
140 | 170 | ||
141 | default: | 171 | default: |
142 | bfa_assert(0); | 172 | bfa_sm_fault(lps->bfa, event); |
143 | } | 173 | } |
144 | } | 174 | } |
145 | 175 | ||
@@ -162,8 +192,16 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
162 | bfa_reqq_wcancel(&lps->wqe); | 192 | bfa_reqq_wcancel(&lps->wqe); |
163 | break; | 193 | break; |
164 | 194 | ||
195 | case BFA_LPS_SM_RX_CVL: | ||
196 | /* | ||
197 | * Login was not even sent out; so when getting out | ||
198 | * of this state, it will appear like a login retry | ||
199 | * after Clear virtual link | ||
200 | */ | ||
201 | break; | ||
202 | |||
165 | default: | 203 | default: |
166 | bfa_assert(0); | 204 | bfa_sm_fault(lps->bfa, event); |
167 | } | 205 | } |
168 | } | 206 | } |
169 | 207 | ||
@@ -185,6 +223,17 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
185 | bfa_sm_set_state(lps, bfa_lps_sm_logout); | 223 | bfa_sm_set_state(lps, bfa_lps_sm_logout); |
186 | bfa_lps_send_logout(lps); | 224 | bfa_lps_send_logout(lps); |
187 | } | 225 | } |
226 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, | ||
227 | BFA_PL_EID_LOGO, 0, "Logout"); | ||
228 | break; | ||
229 | |||
230 | case BFA_LPS_SM_RX_CVL: | ||
231 | bfa_sm_set_state(lps, bfa_lps_sm_init); | ||
232 | |||
233 | /* Let the vport module know about this event */ | ||
234 | bfa_lps_cvl_event(lps); | ||
235 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, | ||
236 | BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); | ||
188 | break; | 237 | break; |
189 | 238 | ||
190 | case BFA_LPS_SM_OFFLINE: | 239 | case BFA_LPS_SM_OFFLINE: |
@@ -193,7 +242,7 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
193 | break; | 242 | break; |
194 | 243 | ||
195 | default: | 244 | default: |
196 | bfa_assert(0); | 245 | bfa_sm_fault(lps->bfa, event); |
197 | } | 246 | } |
198 | } | 247 | } |
199 | 248 | ||
@@ -217,7 +266,7 @@ bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
217 | break; | 266 | break; |
218 | 267 | ||
219 | default: | 268 | default: |
220 | bfa_assert(0); | 269 | bfa_sm_fault(lps->bfa, event); |
221 | } | 270 | } |
222 | } | 271 | } |
223 | 272 | ||
@@ -242,7 +291,7 @@ bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
242 | break; | 291 | break; |
243 | 292 | ||
244 | default: | 293 | default: |
245 | bfa_assert(0); | 294 | bfa_sm_fault(lps->bfa, event); |
246 | } | 295 | } |
247 | } | 296 | } |
248 | 297 | ||
@@ -396,6 +445,20 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp) | |||
396 | } | 445 | } |
397 | 446 | ||
398 | /** | 447 | /** |
448 | * Firmware received a Clear virtual link request (for FCoE) | ||
449 | */ | ||
450 | static void | ||
451 | bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl) | ||
452 | { | ||
453 | struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); | ||
454 | struct bfa_lps_s *lps; | ||
455 | |||
456 | lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag); | ||
457 | |||
458 | bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL); | ||
459 | } | ||
460 | |||
461 | /** | ||
399 | * Space is available in request queue, resume queueing request to firmware. | 462 | * Space is available in request queue, resume queueing request to firmware. |
400 | */ | 463 | */ |
401 | static void | 464 | static void |
@@ -531,7 +594,48 @@ bfa_lps_logout_comp(struct bfa_lps_s *lps) | |||
531 | bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg); | 594 | bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg); |
532 | } | 595 | } |
533 | 596 | ||
597 | /** | ||
598 | * Clear virtual link completion handler for non-fcs | ||
599 | */ | ||
600 | static void | ||
601 | bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete) | ||
602 | { | ||
603 | struct bfa_lps_s *lps = arg; | ||
604 | |||
605 | if (!complete) | ||
606 | return; | ||
607 | |||
608 | /* Clear virtual link to base port will result in link down */ | ||
609 | if (lps->fdisc) | ||
610 | bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); | ||
611 | } | ||
612 | |||
613 | /** | ||
614 | * Received Clear virtual link event --direct call for fcs, | ||
615 | * queue for others | ||
616 | */ | ||
617 | static void | ||
618 | bfa_lps_cvl_event(struct bfa_lps_s *lps) | ||
619 | { | ||
620 | if (!lps->bfa->fcs) { | ||
621 | bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb, | ||
622 | lps); | ||
623 | return; | ||
624 | } | ||
625 | |||
626 | /* Clear virtual link to base port will result in link down */ | ||
627 | if (lps->fdisc) | ||
628 | bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); | ||
629 | } | ||
534 | 630 | ||
631 | u32 | ||
632 | bfa_lps_get_max_vport(struct bfa_s *bfa) | ||
633 | { | ||
634 | if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) | ||
635 | return BFA_LPS_MAX_VPORTS_SUPP_CT; | ||
636 | else | ||
637 | return BFA_LPS_MAX_VPORTS_SUPP_CB; | ||
638 | } | ||
535 | 639 | ||
536 | /** | 640 | /** |
537 | * lps_public BFA LPS public functions | 641 | * lps_public BFA LPS public functions |
@@ -752,6 +856,14 @@ bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps) | |||
752 | return lps->lsrjt_expl; | 856 | return lps->lsrjt_expl; |
753 | } | 857 | } |
754 | 858 | ||
859 | /** | ||
860 | * Return fpma/spma MAC for lport | ||
861 | */ | ||
862 | struct mac_s | ||
863 | bfa_lps_get_lp_mac(struct bfa_lps_s *lps) | ||
864 | { | ||
865 | return lps->lp_mac; | ||
866 | } | ||
755 | 867 | ||
756 | /** | 868 | /** |
757 | * LPS firmware message class handler. | 869 | * LPS firmware message class handler. |
@@ -773,6 +885,10 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m) | |||
773 | bfa_lps_logout_rsp(bfa, msg.logout_rsp); | 885 | bfa_lps_logout_rsp(bfa, msg.logout_rsp); |
774 | break; | 886 | break; |
775 | 887 | ||
888 | case BFI_LPS_H2I_CVL_EVENT: | ||
889 | bfa_lps_rx_cvl_event(bfa, msg.cvl_event); | ||
890 | break; | ||
891 | |||
776 | default: | 892 | default: |
777 | bfa_trc(bfa, m->mhdr.msg_id); | 893 | bfa_trc(bfa, m->mhdr.msg_id); |
778 | bfa_assert(0); | 894 | bfa_assert(0); |
diff --git a/drivers/scsi/bfa/bfa_module.c b/drivers/scsi/bfa/bfa_module.c index 32eda8e1ec65..a7fcc80c177e 100644 --- a/drivers/scsi/bfa/bfa_module.c +++ b/drivers/scsi/bfa/bfa_module.c | |||
@@ -24,7 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | struct bfa_module_s *hal_mods[] = { | 25 | struct bfa_module_s *hal_mods[] = { |
26 | &hal_mod_sgpg, | 26 | &hal_mod_sgpg, |
27 | &hal_mod_pport, | 27 | &hal_mod_fcport, |
28 | &hal_mod_fcxp, | 28 | &hal_mod_fcxp, |
29 | &hal_mod_lps, | 29 | &hal_mod_lps, |
30 | &hal_mod_uf, | 30 | &hal_mod_uf, |
@@ -45,7 +45,7 @@ bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = { | |||
45 | bfa_isr_unhandled, /* BFI_MC_DIAG */ | 45 | bfa_isr_unhandled, /* BFI_MC_DIAG */ |
46 | bfa_isr_unhandled, /* BFI_MC_FLASH */ | 46 | bfa_isr_unhandled, /* BFI_MC_FLASH */ |
47 | bfa_isr_unhandled, /* BFI_MC_CEE */ | 47 | bfa_isr_unhandled, /* BFI_MC_CEE */ |
48 | bfa_pport_isr, /* BFI_MC_PORT */ | 48 | bfa_fcport_isr, /* BFI_MC_FCPORT */ |
49 | bfa_isr_unhandled, /* BFI_MC_IOCFC */ | 49 | bfa_isr_unhandled, /* BFI_MC_IOCFC */ |
50 | bfa_isr_unhandled, /* BFI_MC_LL */ | 50 | bfa_isr_unhandled, /* BFI_MC_LL */ |
51 | bfa_uf_isr, /* BFI_MC_UF */ | 51 | bfa_uf_isr, /* BFI_MC_UF */ |
diff --git a/drivers/scsi/bfa/bfa_modules_priv.h b/drivers/scsi/bfa/bfa_modules_priv.h index 96f70534593c..f554c2fad6a9 100644 --- a/drivers/scsi/bfa/bfa_modules_priv.h +++ b/drivers/scsi/bfa/bfa_modules_priv.h | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | 30 | ||
31 | struct bfa_modules_s { | 31 | struct bfa_modules_s { |
32 | struct bfa_pport_s pport; /* physical port module */ | 32 | struct bfa_fcport_s fcport; /* fc port module */ |
33 | struct bfa_fcxp_mod_s fcxp_mod; /* fcxp module */ | 33 | struct bfa_fcxp_mod_s fcxp_mod; /* fcxp module */ |
34 | struct bfa_lps_mod_s lps_mod; /* fcxp module */ | 34 | struct bfa_lps_mod_s lps_mod; /* fcxp module */ |
35 | struct bfa_uf_mod_s uf_mod; /* unsolicited frame module */ | 35 | struct bfa_uf_mod_s uf_mod; /* unsolicited frame module */ |
diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h index 51f698a06b6d..40e256ec67ff 100644 --- a/drivers/scsi/bfa/bfa_port_priv.h +++ b/drivers/scsi/bfa/bfa_port_priv.h | |||
@@ -23,9 +23,19 @@ | |||
23 | #include "bfa_intr_priv.h" | 23 | #include "bfa_intr_priv.h" |
24 | 24 | ||
25 | /** | 25 | /** |
26 | * BFA physical port data structure | 26 | * Link notification data structure |
27 | */ | 27 | */ |
28 | struct bfa_pport_s { | 28 | struct bfa_fcport_ln_s { |
29 | struct bfa_fcport_s *fcport; | ||
30 | bfa_sm_t sm; | ||
31 | struct bfa_cb_qe_s ln_qe; /* BFA callback queue elem for ln */ | ||
32 | enum bfa_pport_linkstate ln_event; /* ln event for callback */ | ||
33 | }; | ||
34 | |||
35 | /** | ||
36 | * BFA FC port data structure | ||
37 | */ | ||
38 | struct bfa_fcport_s { | ||
29 | struct bfa_s *bfa; /* parent BFA instance */ | 39 | struct bfa_s *bfa; /* parent BFA instance */ |
30 | bfa_sm_t sm; /* port state machine */ | 40 | bfa_sm_t sm; /* port state machine */ |
31 | wwn_t nwwn; /* node wwn of physical port */ | 41 | wwn_t nwwn; /* node wwn of physical port */ |
@@ -36,6 +46,8 @@ struct bfa_pport_s { | |||
36 | enum bfa_pport_topology topology; /* current topology */ | 46 | enum bfa_pport_topology topology; /* current topology */ |
37 | u8 myalpa; /* my ALPA in LOOP topology */ | 47 | u8 myalpa; /* my ALPA in LOOP topology */ |
38 | u8 rsvd[3]; | 48 | u8 rsvd[3]; |
49 | u32 mypid:24; | ||
50 | u32 rsvd_b:8; | ||
39 | struct bfa_pport_cfg_s cfg; /* current port configuration */ | 51 | struct bfa_pport_cfg_s cfg; /* current port configuration */ |
40 | struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ | 52 | struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ |
41 | struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */ | 53 | struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */ |
@@ -49,42 +61,31 @@ struct bfa_pport_s { | |||
49 | void (*event_cbfn) (void *cbarg, | 61 | void (*event_cbfn) (void *cbarg, |
50 | bfa_pport_event_t event); | 62 | bfa_pport_event_t event); |
51 | union { | 63 | union { |
52 | union bfi_pport_i2h_msg_u i2hmsg; | 64 | union bfi_fcport_i2h_msg_u i2hmsg; |
53 | } event_arg; | 65 | } event_arg; |
54 | void *bfad; /* BFA driver handle */ | 66 | void *bfad; /* BFA driver handle */ |
67 | struct bfa_fcport_ln_s ln; /* Link Notification */ | ||
55 | struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */ | 68 | struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */ |
56 | enum bfa_pport_linkstate hcb_event; | 69 | struct bfa_timer_s timer; /* timer */ |
57 | /* link event for callback */ | ||
58 | u32 msgtag; /* fimrware msg tag for reply */ | 70 | u32 msgtag; /* fimrware msg tag for reply */ |
59 | u8 *stats_kva; | 71 | u8 *stats_kva; |
60 | u64 stats_pa; | 72 | u64 stats_pa; |
61 | union bfa_pport_stats_u *stats; /* pport stats */ | 73 | union bfa_fcport_stats_u *stats; |
62 | u32 mypid:24; | 74 | union bfa_fcport_stats_u *stats_ret; /* driver stats location */ |
63 | u32 rsvd_b:8; | 75 | bfa_status_t stats_status; /* stats/statsclr status */ |
64 | struct bfa_timer_s timer; /* timer */ | 76 | bfa_boolean_t stats_busy; /* outstanding stats/statsclr */ |
65 | union bfa_pport_stats_u *stats_ret; | 77 | bfa_boolean_t stats_qfull; |
66 | /* driver stats location */ | 78 | bfa_cb_pport_t stats_cbfn; /* driver callback function */ |
67 | bfa_status_t stats_status; | 79 | void *stats_cbarg; /* *!< user callback arg */ |
68 | /* stats/statsclr status */ | 80 | bfa_boolean_t diag_busy; /* diag busy status */ |
69 | bfa_boolean_t stats_busy; | 81 | bfa_boolean_t beacon; /* port beacon status */ |
70 | /* outstanding stats/statsclr */ | 82 | bfa_boolean_t link_e2e_beacon; /* link beacon status */ |
71 | bfa_boolean_t stats_qfull; | ||
72 | bfa_boolean_t diag_busy; | ||
73 | /* diag busy status */ | ||
74 | bfa_boolean_t beacon; | ||
75 | /* port beacon status */ | ||
76 | bfa_boolean_t link_e2e_beacon; | ||
77 | /* link beacon status */ | ||
78 | bfa_cb_pport_t stats_cbfn; | ||
79 | /* driver callback function */ | ||
80 | void *stats_cbarg; | ||
81 | /* *!< user callback arg */ | ||
82 | }; | 83 | }; |
83 | 84 | ||
84 | #define BFA_PORT_MOD(__bfa) (&(__bfa)->modules.pport) | 85 | #define BFA_FCPORT_MOD(__bfa) (&(__bfa)->modules.fcport) |
85 | 86 | ||
86 | /* | 87 | /* |
87 | * public functions | 88 | * public functions |
88 | */ | 89 | */ |
89 | void bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); | 90 | void bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); |
90 | #endif /* __BFA_PORT_PRIV_H__ */ | 91 | #endif /* __BFA_PORT_PRIV_H__ */ |
diff --git a/drivers/scsi/bfa/bfa_priv.h b/drivers/scsi/bfa/bfa_priv.h index 0747a6b26f7b..be80fc7e1b0e 100644 --- a/drivers/scsi/bfa/bfa_priv.h +++ b/drivers/scsi/bfa/bfa_priv.h | |||
@@ -101,7 +101,7 @@ extern bfa_boolean_t bfa_auto_recover; | |||
101 | extern struct bfa_module_s hal_mod_flash; | 101 | extern struct bfa_module_s hal_mod_flash; |
102 | extern struct bfa_module_s hal_mod_fcdiag; | 102 | extern struct bfa_module_s hal_mod_fcdiag; |
103 | extern struct bfa_module_s hal_mod_sgpg; | 103 | extern struct bfa_module_s hal_mod_sgpg; |
104 | extern struct bfa_module_s hal_mod_pport; | 104 | extern struct bfa_module_s hal_mod_fcport; |
105 | extern struct bfa_module_s hal_mod_fcxp; | 105 | extern struct bfa_module_s hal_mod_fcxp; |
106 | extern struct bfa_module_s hal_mod_lps; | 106 | extern struct bfa_module_s hal_mod_lps; |
107 | extern struct bfa_module_s hal_mod_uf; | 107 | extern struct bfa_module_s hal_mod_uf; |
diff --git a/drivers/scsi/bfa/bfa_rport.c b/drivers/scsi/bfa/bfa_rport.c index 3e1990a74258..7c509fa244e4 100644 --- a/drivers/scsi/bfa/bfa_rport.c +++ b/drivers/scsi/bfa/bfa_rport.c | |||
@@ -114,7 +114,7 @@ bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event) | |||
114 | 114 | ||
115 | default: | 115 | default: |
116 | bfa_stats(rp, sm_un_unexp); | 116 | bfa_stats(rp, sm_un_unexp); |
117 | bfa_assert(0); | 117 | bfa_sm_fault(rp->bfa, event); |
118 | } | 118 | } |
119 | } | 119 | } |
120 | 120 | ||
@@ -146,7 +146,7 @@ bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event) | |||
146 | 146 | ||
147 | default: | 147 | default: |
148 | bfa_stats(rp, sm_cr_unexp); | 148 | bfa_stats(rp, sm_cr_unexp); |
149 | bfa_assert(0); | 149 | bfa_sm_fault(rp->bfa, event); |
150 | } | 150 | } |
151 | } | 151 | } |
152 | 152 | ||
@@ -183,7 +183,7 @@ bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event) | |||
183 | 183 | ||
184 | default: | 184 | default: |
185 | bfa_stats(rp, sm_fwc_unexp); | 185 | bfa_stats(rp, sm_fwc_unexp); |
186 | bfa_assert(0); | 186 | bfa_sm_fault(rp->bfa, event); |
187 | } | 187 | } |
188 | } | 188 | } |
189 | 189 | ||
@@ -224,7 +224,7 @@ bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) | |||
224 | 224 | ||
225 | default: | 225 | default: |
226 | bfa_stats(rp, sm_fwc_unexp); | 226 | bfa_stats(rp, sm_fwc_unexp); |
227 | bfa_assert(0); | 227 | bfa_sm_fault(rp->bfa, event); |
228 | } | 228 | } |
229 | } | 229 | } |
230 | 230 | ||
@@ -296,7 +296,7 @@ bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event) | |||
296 | 296 | ||
297 | default: | 297 | default: |
298 | bfa_stats(rp, sm_on_unexp); | 298 | bfa_stats(rp, sm_on_unexp); |
299 | bfa_assert(0); | 299 | bfa_sm_fault(rp->bfa, event); |
300 | } | 300 | } |
301 | } | 301 | } |
302 | 302 | ||
@@ -329,7 +329,7 @@ bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event) | |||
329 | 329 | ||
330 | default: | 330 | default: |
331 | bfa_stats(rp, sm_fwd_unexp); | 331 | bfa_stats(rp, sm_fwd_unexp); |
332 | bfa_assert(0); | 332 | bfa_sm_fault(rp->bfa, event); |
333 | } | 333 | } |
334 | } | 334 | } |
335 | 335 | ||
@@ -359,7 +359,7 @@ bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) | |||
359 | 359 | ||
360 | default: | 360 | default: |
361 | bfa_stats(rp, sm_fwd_unexp); | 361 | bfa_stats(rp, sm_fwd_unexp); |
362 | bfa_assert(0); | 362 | bfa_sm_fault(rp->bfa, event); |
363 | } | 363 | } |
364 | } | 364 | } |
365 | 365 | ||
@@ -394,7 +394,7 @@ bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event) | |||
394 | 394 | ||
395 | default: | 395 | default: |
396 | bfa_stats(rp, sm_off_unexp); | 396 | bfa_stats(rp, sm_off_unexp); |
397 | bfa_assert(0); | 397 | bfa_sm_fault(rp->bfa, event); |
398 | } | 398 | } |
399 | } | 399 | } |
400 | 400 | ||
@@ -421,7 +421,7 @@ bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event) | |||
421 | break; | 421 | break; |
422 | 422 | ||
423 | default: | 423 | default: |
424 | bfa_assert(0); | 424 | bfa_sm_fault(rp->bfa, event); |
425 | } | 425 | } |
426 | } | 426 | } |
427 | 427 | ||
@@ -446,7 +446,7 @@ bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) | |||
446 | break; | 446 | break; |
447 | 447 | ||
448 | default: | 448 | default: |
449 | bfa_assert(0); | 449 | bfa_sm_fault(rp->bfa, event); |
450 | } | 450 | } |
451 | } | 451 | } |
452 | 452 | ||
@@ -477,7 +477,7 @@ bfa_rport_sm_delete_pending(struct bfa_rport_s *rp, | |||
477 | 477 | ||
478 | default: | 478 | default: |
479 | bfa_stats(rp, sm_delp_unexp); | 479 | bfa_stats(rp, sm_delp_unexp); |
480 | bfa_assert(0); | 480 | bfa_sm_fault(rp->bfa, event); |
481 | } | 481 | } |
482 | } | 482 | } |
483 | 483 | ||
@@ -512,7 +512,7 @@ bfa_rport_sm_offline_pending(struct bfa_rport_s *rp, | |||
512 | 512 | ||
513 | default: | 513 | default: |
514 | bfa_stats(rp, sm_offp_unexp); | 514 | bfa_stats(rp, sm_offp_unexp); |
515 | bfa_assert(0); | 515 | bfa_sm_fault(rp->bfa, event); |
516 | } | 516 | } |
517 | } | 517 | } |
518 | 518 | ||
@@ -550,7 +550,7 @@ bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event) | |||
550 | 550 | ||
551 | default: | 551 | default: |
552 | bfa_stats(rp, sm_iocd_unexp); | 552 | bfa_stats(rp, sm_iocd_unexp); |
553 | bfa_assert(0); | 553 | bfa_sm_fault(rp->bfa, event); |
554 | } | 554 | } |
555 | } | 555 | } |
556 | 556 | ||
diff --git a/drivers/scsi/bfa/bfa_trcmod_priv.h b/drivers/scsi/bfa/bfa_trcmod_priv.h index b3562dce7e9f..a7a82610db85 100644 --- a/drivers/scsi/bfa/bfa_trcmod_priv.h +++ b/drivers/scsi/bfa/bfa_trcmod_priv.h | |||
@@ -29,38 +29,36 @@ | |||
29 | * !!! needed between trace utility and driver version | 29 | * !!! needed between trace utility and driver version |
30 | */ | 30 | */ |
31 | enum { | 31 | enum { |
32 | BFA_TRC_HAL_IOC = 1, | 32 | BFA_TRC_HAL_INTR = 1, |
33 | BFA_TRC_HAL_INTR = 2, | 33 | BFA_TRC_HAL_FCXP = 2, |
34 | BFA_TRC_HAL_FCXP = 3, | 34 | BFA_TRC_HAL_UF = 3, |
35 | BFA_TRC_HAL_UF = 4, | 35 | BFA_TRC_HAL_RPORT = 4, |
36 | BFA_TRC_HAL_DIAG = 5, | 36 | BFA_TRC_HAL_FCPIM = 5, |
37 | BFA_TRC_HAL_RPORT = 6, | 37 | BFA_TRC_HAL_IOIM = 6, |
38 | BFA_TRC_HAL_FCPIM = 7, | 38 | BFA_TRC_HAL_TSKIM = 7, |
39 | BFA_TRC_HAL_IOIM = 8, | 39 | BFA_TRC_HAL_ITNIM = 8, |
40 | BFA_TRC_HAL_TSKIM = 9, | 40 | BFA_TRC_HAL_FCPORT = 9, |
41 | BFA_TRC_HAL_ITNIM = 10, | 41 | BFA_TRC_HAL_SGPG = 10, |
42 | BFA_TRC_HAL_PPORT = 11, | 42 | BFA_TRC_HAL_FLASH = 11, |
43 | BFA_TRC_HAL_SGPG = 12, | 43 | BFA_TRC_HAL_DEBUG = 12, |
44 | BFA_TRC_HAL_FLASH = 13, | 44 | BFA_TRC_HAL_WWN = 13, |
45 | BFA_TRC_HAL_DEBUG = 14, | 45 | BFA_TRC_HAL_FLASH_RAW = 14, |
46 | BFA_TRC_HAL_WWN = 15, | 46 | BFA_TRC_HAL_SBOOT = 15, |
47 | BFA_TRC_HAL_FLASH_RAW = 16, | 47 | BFA_TRC_HAL_SBOOT_IO = 16, |
48 | BFA_TRC_HAL_SBOOT = 17, | 48 | BFA_TRC_HAL_SBOOT_INTR = 17, |
49 | BFA_TRC_HAL_SBOOT_IO = 18, | 49 | BFA_TRC_HAL_SBTEST = 18, |
50 | BFA_TRC_HAL_SBOOT_INTR = 19, | 50 | BFA_TRC_HAL_IPFC = 19, |
51 | BFA_TRC_HAL_SBTEST = 20, | 51 | BFA_TRC_HAL_IOCFC = 20, |
52 | BFA_TRC_HAL_IPFC = 21, | 52 | BFA_TRC_HAL_FCPTM = 21, |
53 | BFA_TRC_HAL_IOCFC = 22, | 53 | BFA_TRC_HAL_IOTM = 22, |
54 | BFA_TRC_HAL_FCPTM = 23, | 54 | BFA_TRC_HAL_TSKTM = 23, |
55 | BFA_TRC_HAL_IOTM = 24, | 55 | BFA_TRC_HAL_TIN = 24, |
56 | BFA_TRC_HAL_TSKTM = 25, | 56 | BFA_TRC_HAL_LPS = 25, |
57 | BFA_TRC_HAL_TIN = 26, | 57 | BFA_TRC_HAL_FCDIAG = 26, |
58 | BFA_TRC_HAL_LPS = 27, | 58 | BFA_TRC_HAL_PBIND = 27, |
59 | BFA_TRC_HAL_FCDIAG = 28, | 59 | BFA_TRC_HAL_IOCFC_CT = 28, |
60 | BFA_TRC_HAL_PBIND = 29, | 60 | BFA_TRC_HAL_IOCFC_CB = 29, |
61 | BFA_TRC_HAL_IOCFC_CT = 30, | 61 | BFA_TRC_HAL_IOCFC_Q = 30, |
62 | BFA_TRC_HAL_IOCFC_CB = 31, | ||
63 | BFA_TRC_HAL_IOCFC_Q = 32, | ||
64 | }; | 62 | }; |
65 | 63 | ||
66 | #endif /* __BFA_TRCMOD_PRIV_H__ */ | 64 | #endif /* __BFA_TRCMOD_PRIV_H__ */ |
diff --git a/drivers/scsi/bfa/bfa_tskim.c b/drivers/scsi/bfa/bfa_tskim.c index ff7a4dc0bf3c..ad9aaaedd3f1 100644 --- a/drivers/scsi/bfa/bfa_tskim.c +++ b/drivers/scsi/bfa/bfa_tskim.c | |||
@@ -110,7 +110,7 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | |||
110 | break; | 110 | break; |
111 | 111 | ||
112 | default: | 112 | default: |
113 | bfa_assert(0); | 113 | bfa_sm_fault(tskim->bfa, event); |
114 | } | 114 | } |
115 | } | 115 | } |
116 | 116 | ||
@@ -146,7 +146,7 @@ bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | |||
146 | break; | 146 | break; |
147 | 147 | ||
148 | default: | 148 | default: |
149 | bfa_assert(0); | 149 | bfa_sm_fault(tskim->bfa, event); |
150 | } | 150 | } |
151 | } | 151 | } |
152 | 152 | ||
@@ -178,7 +178,7 @@ bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | |||
178 | break; | 178 | break; |
179 | 179 | ||
180 | default: | 180 | default: |
181 | bfa_assert(0); | 181 | bfa_sm_fault(tskim->bfa, event); |
182 | } | 182 | } |
183 | } | 183 | } |
184 | 184 | ||
@@ -207,7 +207,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | |||
207 | break; | 207 | break; |
208 | 208 | ||
209 | default: | 209 | default: |
210 | bfa_assert(0); | 210 | bfa_sm_fault(tskim->bfa, event); |
211 | } | 211 | } |
212 | } | 212 | } |
213 | 213 | ||
@@ -242,7 +242,7 @@ bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | |||
242 | break; | 242 | break; |
243 | 243 | ||
244 | default: | 244 | default: |
245 | bfa_assert(0); | 245 | bfa_sm_fault(tskim->bfa, event); |
246 | } | 246 | } |
247 | } | 247 | } |
248 | 248 | ||
@@ -277,7 +277,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim, | |||
277 | break; | 277 | break; |
278 | 278 | ||
279 | default: | 279 | default: |
280 | bfa_assert(0); | 280 | bfa_sm_fault(tskim->bfa, event); |
281 | } | 281 | } |
282 | } | 282 | } |
283 | 283 | ||
@@ -303,7 +303,7 @@ bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) | |||
303 | break; | 303 | break; |
304 | 304 | ||
305 | default: | 305 | default: |
306 | bfa_assert(0); | 306 | bfa_sm_fault(tskim->bfa, event); |
307 | } | 307 | } |
308 | } | 308 | } |
309 | 309 | ||
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index b52b773d49d9..6bff08ea4029 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c | |||
@@ -20,6 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/kthread.h> | ||
23 | #include "bfad_drv.h" | 24 | #include "bfad_drv.h" |
24 | #include "bfad_im.h" | 25 | #include "bfad_im.h" |
25 | #include "bfad_tm.h" | 26 | #include "bfad_tm.h" |
@@ -53,6 +54,7 @@ static int log_level = BFA_LOG_WARNING; | |||
53 | static int ioc_auto_recover = BFA_TRUE; | 54 | static int ioc_auto_recover = BFA_TRUE; |
54 | static int ipfc_enable = BFA_FALSE; | 55 | static int ipfc_enable = BFA_FALSE; |
55 | static int ipfc_mtu = -1; | 56 | static int ipfc_mtu = -1; |
57 | static int fdmi_enable = BFA_TRUE; | ||
56 | int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH; | 58 | int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH; |
57 | int bfa_linkup_delay = -1; | 59 | int bfa_linkup_delay = -1; |
58 | 60 | ||
@@ -74,6 +76,7 @@ module_param(log_level, int, S_IRUGO | S_IWUSR); | |||
74 | module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR); | 76 | module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR); |
75 | module_param(ipfc_enable, int, S_IRUGO | S_IWUSR); | 77 | module_param(ipfc_enable, int, S_IRUGO | S_IWUSR); |
76 | module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR); | 78 | module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR); |
79 | module_param(fdmi_enable, int, S_IRUGO | S_IWUSR); | ||
77 | module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR); | 80 | module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR); |
78 | 81 | ||
79 | /* | 82 | /* |
@@ -95,6 +98,8 @@ bfad_fc4_probe(struct bfad_s *bfad) | |||
95 | 98 | ||
96 | if (ipfc_enable) | 99 | if (ipfc_enable) |
97 | bfad_ipfc_probe(bfad); | 100 | bfad_ipfc_probe(bfad); |
101 | |||
102 | bfad->bfad_flags |= BFAD_FC4_PROBE_DONE; | ||
98 | ext: | 103 | ext: |
99 | return rc; | 104 | return rc; |
100 | } | 105 | } |
@@ -106,6 +111,7 @@ bfad_fc4_probe_undo(struct bfad_s *bfad) | |||
106 | bfad_tm_probe_undo(bfad); | 111 | bfad_tm_probe_undo(bfad); |
107 | if (ipfc_enable) | 112 | if (ipfc_enable) |
108 | bfad_ipfc_probe_undo(bfad); | 113 | bfad_ipfc_probe_undo(bfad); |
114 | bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE; | ||
109 | } | 115 | } |
110 | 116 | ||
111 | static void | 117 | static void |
@@ -173,9 +179,19 @@ bfa_cb_init(void *drv, bfa_status_t init_status) | |||
173 | { | 179 | { |
174 | struct bfad_s *bfad = drv; | 180 | struct bfad_s *bfad = drv; |
175 | 181 | ||
176 | if (init_status == BFA_STATUS_OK) | 182 | if (init_status == BFA_STATUS_OK) { |
177 | bfad->bfad_flags |= BFAD_HAL_INIT_DONE; | 183 | bfad->bfad_flags |= BFAD_HAL_INIT_DONE; |
178 | 184 | ||
185 | /* If BFAD_HAL_INIT_FAIL flag is set: | ||
186 | * Wake up the kernel thread to start | ||
187 | * the bfad operations after HAL init done | ||
188 | */ | ||
189 | if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) { | ||
190 | bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL; | ||
191 | wake_up_process(bfad->bfad_tsk); | ||
192 | } | ||
193 | } | ||
194 | |||
179 | complete(&bfad->comp); | 195 | complete(&bfad->comp); |
180 | } | 196 | } |
181 | 197 | ||
@@ -648,7 +664,7 @@ bfad_fcs_port_cfg(struct bfad_s *bfad) | |||
648 | 664 | ||
649 | sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no); | 665 | sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no); |
650 | memcpy(port_cfg.sym_name.symname, symname, strlen(symname)); | 666 | memcpy(port_cfg.sym_name.symname, symname, strlen(symname)); |
651 | bfa_pport_get_attr(&bfad->bfa, &attr); | 667 | bfa_fcport_get_attr(&bfad->bfa, &attr); |
652 | port_cfg.nwwn = attr.nwwn; | 668 | port_cfg.nwwn = attr.nwwn; |
653 | port_cfg.pwwn = attr.pwwn; | 669 | port_cfg.pwwn = attr.pwwn; |
654 | 670 | ||
@@ -661,7 +677,6 @@ bfad_drv_init(struct bfad_s *bfad) | |||
661 | bfa_status_t rc; | 677 | bfa_status_t rc; |
662 | unsigned long flags; | 678 | unsigned long flags; |
663 | struct bfa_fcs_driver_info_s driver_info; | 679 | struct bfa_fcs_driver_info_s driver_info; |
664 | int i; | ||
665 | 680 | ||
666 | bfad->cfg_data.rport_del_timeout = rport_del_timeout; | 681 | bfad->cfg_data.rport_del_timeout = rport_del_timeout; |
667 | bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth; | 682 | bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth; |
@@ -681,12 +696,7 @@ bfad_drv_init(struct bfad_s *bfad) | |||
681 | bfa_init_log(&bfad->bfa, bfad->logmod); | 696 | bfa_init_log(&bfad->bfa, bfad->logmod); |
682 | bfa_init_trc(&bfad->bfa, bfad->trcmod); | 697 | bfa_init_trc(&bfad->bfa, bfad->trcmod); |
683 | bfa_init_aen(&bfad->bfa, bfad->aen); | 698 | bfa_init_aen(&bfad->bfa, bfad->aen); |
684 | INIT_LIST_HEAD(&bfad->file_q); | 699 | memset(bfad->file_map, 0, sizeof(bfad->file_map)); |
685 | INIT_LIST_HEAD(&bfad->file_free_q); | ||
686 | for (i = 0; i < BFAD_AEN_MAX_APPS; i++) { | ||
687 | bfa_q_qe_init(&bfad->file_buf[i].qe); | ||
688 | list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q); | ||
689 | } | ||
690 | bfa_init_plog(&bfad->bfa, &bfad->plog_buf); | 700 | bfa_init_plog(&bfad->bfa, &bfad->plog_buf); |
691 | bfa_plog_init(&bfad->plog_buf); | 701 | bfa_plog_init(&bfad->plog_buf); |
692 | bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START, | 702 | bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START, |
@@ -746,8 +756,16 @@ bfad_drv_init(struct bfad_s *bfad) | |||
746 | bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod); | 756 | bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod); |
747 | bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod); | 757 | bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod); |
748 | bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen); | 758 | bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen); |
749 | bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE); | 759 | bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE); |
760 | |||
761 | /* Do FCS init only when HAL init is done */ | ||
762 | if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { | ||
763 | bfa_fcs_init(&bfad->bfa_fcs); | ||
764 | bfad->bfad_flags |= BFAD_FCS_INIT_DONE; | ||
765 | } | ||
766 | |||
750 | bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info); | 767 | bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info); |
768 | bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable); | ||
751 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 769 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
752 | 770 | ||
753 | bfad->bfad_flags |= BFAD_DRV_INIT_DONE; | 771 | bfad->bfad_flags |= BFAD_DRV_INIT_DONE; |
@@ -763,12 +781,21 @@ out_hal_mem_alloc_failure: | |||
763 | void | 781 | void |
764 | bfad_drv_uninit(struct bfad_s *bfad) | 782 | bfad_drv_uninit(struct bfad_s *bfad) |
765 | { | 783 | { |
784 | unsigned long flags; | ||
785 | |||
786 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
787 | init_completion(&bfad->comp); | ||
788 | bfa_stop(&bfad->bfa); | ||
789 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
790 | wait_for_completion(&bfad->comp); | ||
791 | |||
766 | del_timer_sync(&bfad->hal_tmo); | 792 | del_timer_sync(&bfad->hal_tmo); |
767 | bfa_isr_disable(&bfad->bfa); | 793 | bfa_isr_disable(&bfad->bfa); |
768 | bfa_detach(&bfad->bfa); | 794 | bfa_detach(&bfad->bfa); |
769 | bfad_remove_intr(bfad); | 795 | bfad_remove_intr(bfad); |
770 | bfa_assert(list_empty(&bfad->file_q)); | ||
771 | bfad_hal_mem_release(bfad); | 796 | bfad_hal_mem_release(bfad); |
797 | |||
798 | bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE; | ||
772 | } | 799 | } |
773 | 800 | ||
774 | void | 801 | void |
@@ -859,6 +886,86 @@ bfad_drv_log_level_set(struct bfad_s *bfad) | |||
859 | bfa_log_set_level_all(&bfad->log_data, log_level); | 886 | bfa_log_set_level_all(&bfad->log_data, log_level); |
860 | } | 887 | } |
861 | 888 | ||
889 | bfa_status_t | ||
890 | bfad_start_ops(struct bfad_s *bfad) | ||
891 | { | ||
892 | int retval; | ||
893 | |||
894 | /* PPORT FCS config */ | ||
895 | bfad_fcs_port_cfg(bfad); | ||
896 | |||
897 | retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM); | ||
898 | if (retval != BFA_STATUS_OK) | ||
899 | goto out_cfg_pport_failure; | ||
900 | |||
901 | /* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */ | ||
902 | retval = bfad_fc4_probe(bfad); | ||
903 | if (retval != BFA_STATUS_OK) { | ||
904 | printk(KERN_WARNING "bfad_fc4_probe failed\n"); | ||
905 | goto out_fc4_probe_failure; | ||
906 | } | ||
907 | |||
908 | bfad_drv_start(bfad); | ||
909 | |||
910 | /* | ||
911 | * If bfa_linkup_delay is set to -1 default; try to retrive the | ||
912 | * value using the bfad_os_get_linkup_delay(); else use the | ||
913 | * passed in module param value as the bfa_linkup_delay. | ||
914 | */ | ||
915 | if (bfa_linkup_delay < 0) { | ||
916 | |||
917 | bfa_linkup_delay = bfad_os_get_linkup_delay(bfad); | ||
918 | bfad_os_rport_online_wait(bfad); | ||
919 | bfa_linkup_delay = -1; | ||
920 | |||
921 | } else { | ||
922 | bfad_os_rport_online_wait(bfad); | ||
923 | } | ||
924 | |||
925 | bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name); | ||
926 | |||
927 | return BFA_STATUS_OK; | ||
928 | |||
929 | out_fc4_probe_failure: | ||
930 | bfad_fc4_probe_undo(bfad); | ||
931 | bfad_uncfg_pport(bfad); | ||
932 | out_cfg_pport_failure: | ||
933 | return BFA_STATUS_FAILED; | ||
934 | } | ||
935 | |||
936 | int | ||
937 | bfad_worker (void *ptr) | ||
938 | { | ||
939 | struct bfad_s *bfad; | ||
940 | unsigned long flags; | ||
941 | |||
942 | bfad = (struct bfad_s *)ptr; | ||
943 | |||
944 | while (!kthread_should_stop()) { | ||
945 | |||
946 | /* Check if the FCS init is done from bfad_drv_init; | ||
947 | * if not done do FCS init and set the flag. | ||
948 | */ | ||
949 | if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) { | ||
950 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
951 | bfa_fcs_init(&bfad->bfa_fcs); | ||
952 | bfad->bfad_flags |= BFAD_FCS_INIT_DONE; | ||
953 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
954 | } | ||
955 | |||
956 | /* Start the bfad operations after HAL init done */ | ||
957 | bfad_start_ops(bfad); | ||
958 | |||
959 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
960 | bfad->bfad_tsk = NULL; | ||
961 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
962 | |||
963 | break; | ||
964 | } | ||
965 | |||
966 | return 0; | ||
967 | } | ||
968 | |||
862 | /* | 969 | /* |
863 | * PCI_entry PCI driver entries * { | 970 | * PCI_entry PCI driver entries * { |
864 | */ | 971 | */ |
@@ -871,7 +978,6 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
871 | { | 978 | { |
872 | struct bfad_s *bfad; | 979 | struct bfad_s *bfad; |
873 | int error = -ENODEV, retval; | 980 | int error = -ENODEV, retval; |
874 | char buf[16]; | ||
875 | 981 | ||
876 | /* | 982 | /* |
877 | * For single port cards - only claim function 0 | 983 | * For single port cards - only claim function 0 |
@@ -902,8 +1008,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
902 | bfa_trc(bfad, bfad_inst); | 1008 | bfa_trc(bfad, bfad_inst); |
903 | 1009 | ||
904 | bfad->logmod = &bfad->log_data; | 1010 | bfad->logmod = &bfad->log_data; |
905 | sprintf(buf, "%d", bfad_inst); | 1011 | bfa_log_init(bfad->logmod, (char *)pci_name(pdev), bfa_os_printf); |
906 | bfa_log_init(bfad->logmod, buf, bfa_os_printf); | ||
907 | 1012 | ||
908 | bfad_drv_log_level_set(bfad); | 1013 | bfad_drv_log_level_set(bfad); |
909 | 1014 | ||
@@ -933,57 +1038,39 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
933 | bfad->ref_count = 0; | 1038 | bfad->ref_count = 0; |
934 | bfad->pport.bfad = bfad; | 1039 | bfad->pport.bfad = bfad; |
935 | 1040 | ||
1041 | bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s", | ||
1042 | "bfad_worker"); | ||
1043 | if (IS_ERR(bfad->bfad_tsk)) { | ||
1044 | printk(KERN_INFO "bfad[%d]: Kernel thread" | ||
1045 | " creation failed!\n", | ||
1046 | bfad->inst_no); | ||
1047 | goto out_kthread_create_failure; | ||
1048 | } | ||
1049 | |||
936 | retval = bfad_drv_init(bfad); | 1050 | retval = bfad_drv_init(bfad); |
937 | if (retval != BFA_STATUS_OK) | 1051 | if (retval != BFA_STATUS_OK) |
938 | goto out_drv_init_failure; | 1052 | goto out_drv_init_failure; |
939 | if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { | 1053 | if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { |
1054 | bfad->bfad_flags |= BFAD_HAL_INIT_FAIL; | ||
940 | printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no); | 1055 | printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no); |
941 | goto ok; | 1056 | goto ok; |
942 | } | 1057 | } |
943 | 1058 | ||
944 | /* | 1059 | retval = bfad_start_ops(bfad); |
945 | * PPORT FCS config | ||
946 | */ | ||
947 | bfad_fcs_port_cfg(bfad); | ||
948 | |||
949 | retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM); | ||
950 | if (retval != BFA_STATUS_OK) | 1060 | if (retval != BFA_STATUS_OK) |
951 | goto out_cfg_pport_failure; | 1061 | goto out_start_ops_failure; |
952 | |||
953 | /* | ||
954 | * BFAD level FC4 (IM/TM/IPFC) specific resource allocation | ||
955 | */ | ||
956 | retval = bfad_fc4_probe(bfad); | ||
957 | if (retval != BFA_STATUS_OK) { | ||
958 | printk(KERN_WARNING "bfad_fc4_probe failed\n"); | ||
959 | goto out_fc4_probe_failure; | ||
960 | } | ||
961 | 1062 | ||
962 | bfad_drv_start(bfad); | 1063 | kthread_stop(bfad->bfad_tsk); |
963 | 1064 | bfad->bfad_tsk = NULL; | |
964 | /* | ||
965 | * If bfa_linkup_delay is set to -1 default; try to retrive the | ||
966 | * value using the bfad_os_get_linkup_delay(); else use the | ||
967 | * passed in module param value as the bfa_linkup_delay. | ||
968 | */ | ||
969 | if (bfa_linkup_delay < 0) { | ||
970 | bfa_linkup_delay = bfad_os_get_linkup_delay(bfad); | ||
971 | bfad_os_rport_online_wait(bfad); | ||
972 | bfa_linkup_delay = -1; | ||
973 | } else { | ||
974 | bfad_os_rport_online_wait(bfad); | ||
975 | } | ||
976 | 1065 | ||
977 | bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name); | ||
978 | ok: | 1066 | ok: |
979 | return 0; | 1067 | return 0; |
980 | 1068 | ||
981 | out_fc4_probe_failure: | 1069 | out_start_ops_failure: |
982 | bfad_fc4_probe_undo(bfad); | ||
983 | bfad_uncfg_pport(bfad); | ||
984 | out_cfg_pport_failure: | ||
985 | bfad_drv_uninit(bfad); | 1070 | bfad_drv_uninit(bfad); |
986 | out_drv_init_failure: | 1071 | out_drv_init_failure: |
1072 | kthread_stop(bfad->bfad_tsk); | ||
1073 | out_kthread_create_failure: | ||
987 | mutex_lock(&bfad_mutex); | 1074 | mutex_lock(&bfad_mutex); |
988 | bfad_inst--; | 1075 | bfad_inst--; |
989 | list_del(&bfad->list_entry); | 1076 | list_del(&bfad->list_entry); |
@@ -1008,6 +1095,11 @@ bfad_pci_remove(struct pci_dev *pdev) | |||
1008 | 1095 | ||
1009 | bfa_trc(bfad, bfad->inst_no); | 1096 | bfa_trc(bfad, bfad->inst_no); |
1010 | 1097 | ||
1098 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1099 | if (bfad->bfad_tsk != NULL) | ||
1100 | kthread_stop(bfad->bfad_tsk); | ||
1101 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1102 | |||
1011 | if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE) | 1103 | if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE) |
1012 | && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { | 1104 | && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { |
1013 | 1105 | ||
@@ -1024,13 +1116,25 @@ bfad_pci_remove(struct pci_dev *pdev) | |||
1024 | goto remove_sysfs; | 1116 | goto remove_sysfs; |
1025 | } | 1117 | } |
1026 | 1118 | ||
1027 | if (bfad->bfad_flags & BFAD_HAL_START_DONE) | 1119 | if (bfad->bfad_flags & BFAD_HAL_START_DONE) { |
1028 | bfad_drv_stop(bfad); | 1120 | bfad_drv_stop(bfad); |
1121 | } else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) { | ||
1122 | /* Invoking bfa_stop() before bfa_detach | ||
1123 | * when HAL and DRV init are success | ||
1124 | * but HAL start did not occur. | ||
1125 | */ | ||
1126 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1127 | init_completion(&bfad->comp); | ||
1128 | bfa_stop(&bfad->bfa); | ||
1129 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1130 | wait_for_completion(&bfad->comp); | ||
1131 | } | ||
1029 | 1132 | ||
1030 | bfad_remove_intr(bfad); | 1133 | bfad_remove_intr(bfad); |
1031 | |||
1032 | del_timer_sync(&bfad->hal_tmo); | 1134 | del_timer_sync(&bfad->hal_tmo); |
1033 | bfad_fc4_probe_undo(bfad); | 1135 | |
1136 | if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE) | ||
1137 | bfad_fc4_probe_undo(bfad); | ||
1034 | 1138 | ||
1035 | if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE) | 1139 | if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE) |
1036 | bfad_uncfg_pport(bfad); | 1140 | bfad_uncfg_pport(bfad); |
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index 9129ae3040ff..d97f69191838 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c | |||
@@ -141,7 +141,7 @@ bfad_im_get_host_port_type(struct Scsi_Host *shost) | |||
141 | struct bfad_s *bfad = im_port->bfad; | 141 | struct bfad_s *bfad = im_port->bfad; |
142 | struct bfa_pport_attr_s attr; | 142 | struct bfa_pport_attr_s attr; |
143 | 143 | ||
144 | bfa_pport_get_attr(&bfad->bfa, &attr); | 144 | bfa_fcport_get_attr(&bfad->bfa, &attr); |
145 | 145 | ||
146 | switch (attr.port_type) { | 146 | switch (attr.port_type) { |
147 | case BFA_PPORT_TYPE_NPORT: | 147 | case BFA_PPORT_TYPE_NPORT: |
@@ -173,7 +173,7 @@ bfad_im_get_host_port_state(struct Scsi_Host *shost) | |||
173 | struct bfad_s *bfad = im_port->bfad; | 173 | struct bfad_s *bfad = im_port->bfad; |
174 | struct bfa_pport_attr_s attr; | 174 | struct bfa_pport_attr_s attr; |
175 | 175 | ||
176 | bfa_pport_get_attr(&bfad->bfa, &attr); | 176 | bfa_fcport_get_attr(&bfad->bfa, &attr); |
177 | 177 | ||
178 | switch (attr.port_state) { | 178 | switch (attr.port_state) { |
179 | case BFA_PPORT_ST_LINKDOWN: | 179 | case BFA_PPORT_ST_LINKDOWN: |
@@ -229,8 +229,10 @@ bfad_im_get_host_speed(struct Scsi_Host *shost) | |||
229 | (struct bfad_im_port_s *) shost->hostdata[0]; | 229 | (struct bfad_im_port_s *) shost->hostdata[0]; |
230 | struct bfad_s *bfad = im_port->bfad; | 230 | struct bfad_s *bfad = im_port->bfad; |
231 | struct bfa_pport_attr_s attr; | 231 | struct bfa_pport_attr_s attr; |
232 | unsigned long flags; | ||
232 | 233 | ||
233 | bfa_pport_get_attr(&bfad->bfa, &attr); | 234 | spin_lock_irqsave(shost->host_lock, flags); |
235 | bfa_fcport_get_attr(&bfad->bfa, &attr); | ||
234 | switch (attr.speed) { | 236 | switch (attr.speed) { |
235 | case BFA_PPORT_SPEED_8GBPS: | 237 | case BFA_PPORT_SPEED_8GBPS: |
236 | fc_host_speed(shost) = FC_PORTSPEED_8GBIT; | 238 | fc_host_speed(shost) = FC_PORTSPEED_8GBIT; |
@@ -248,6 +250,7 @@ bfad_im_get_host_speed(struct Scsi_Host *shost) | |||
248 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; | 250 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; |
249 | break; | 251 | break; |
250 | } | 252 | } |
253 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
251 | } | 254 | } |
252 | 255 | ||
253 | /** | 256 | /** |
@@ -285,7 +288,7 @@ bfad_im_get_stats(struct Scsi_Host *shost) | |||
285 | init_completion(&fcomp.comp); | 288 | init_completion(&fcomp.comp); |
286 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 289 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
287 | memset(hstats, 0, sizeof(struct fc_host_statistics)); | 290 | memset(hstats, 0, sizeof(struct fc_host_statistics)); |
288 | rc = bfa_pport_get_stats(&bfad->bfa, | 291 | rc = bfa_port_get_stats(BFA_FCPORT(&bfad->bfa), |
289 | (union bfa_pport_stats_u *) hstats, | 292 | (union bfa_pport_stats_u *) hstats, |
290 | bfad_hcb_comp, &fcomp); | 293 | bfad_hcb_comp, &fcomp); |
291 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 294 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
@@ -312,7 +315,8 @@ bfad_im_reset_stats(struct Scsi_Host *shost) | |||
312 | 315 | ||
313 | init_completion(&fcomp.comp); | 316 | init_completion(&fcomp.comp); |
314 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 317 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
315 | rc = bfa_pport_clear_stats(&bfad->bfa, bfad_hcb_comp, &fcomp); | 318 | rc = bfa_port_clear_stats(BFA_FCPORT(&bfad->bfa), bfad_hcb_comp, |
319 | &fcomp); | ||
316 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 320 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
317 | 321 | ||
318 | if (rc != BFA_STATUS_OK) | 322 | if (rc != BFA_STATUS_OK) |
@@ -421,12 +425,10 @@ bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr, | |||
421 | struct bfad_im_port_s *im_port = | 425 | struct bfad_im_port_s *im_port = |
422 | (struct bfad_im_port_s *) shost->hostdata[0]; | 426 | (struct bfad_im_port_s *) shost->hostdata[0]; |
423 | struct bfad_s *bfad = im_port->bfad; | 427 | struct bfad_s *bfad = im_port->bfad; |
424 | struct bfa_ioc_attr_s ioc_attr; | 428 | char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; |
425 | 429 | ||
426 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | 430 | bfa_get_adapter_serial_num(&bfad->bfa, serial_num); |
427 | bfa_get_attr(&bfad->bfa, &ioc_attr); | 431 | return snprintf(buf, PAGE_SIZE, "%s\n", serial_num); |
428 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
429 | ioc_attr.adapter_attr.serial_num); | ||
430 | } | 432 | } |
431 | 433 | ||
432 | static ssize_t | 434 | static ssize_t |
@@ -437,11 +439,10 @@ bfad_im_model_show(struct device *dev, struct device_attribute *attr, | |||
437 | struct bfad_im_port_s *im_port = | 439 | struct bfad_im_port_s *im_port = |
438 | (struct bfad_im_port_s *) shost->hostdata[0]; | 440 | (struct bfad_im_port_s *) shost->hostdata[0]; |
439 | struct bfad_s *bfad = im_port->bfad; | 441 | struct bfad_s *bfad = im_port->bfad; |
440 | struct bfa_ioc_attr_s ioc_attr; | 442 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; |
441 | 443 | ||
442 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | 444 | bfa_get_adapter_model(&bfad->bfa, model); |
443 | bfa_get_attr(&bfad->bfa, &ioc_attr); | 445 | return snprintf(buf, PAGE_SIZE, "%s\n", model); |
444 | return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.model); | ||
445 | } | 446 | } |
446 | 447 | ||
447 | static ssize_t | 448 | static ssize_t |
@@ -452,12 +453,10 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, | |||
452 | struct bfad_im_port_s *im_port = | 453 | struct bfad_im_port_s *im_port = |
453 | (struct bfad_im_port_s *) shost->hostdata[0]; | 454 | (struct bfad_im_port_s *) shost->hostdata[0]; |
454 | struct bfad_s *bfad = im_port->bfad; | 455 | struct bfad_s *bfad = im_port->bfad; |
455 | struct bfa_ioc_attr_s ioc_attr; | 456 | char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN]; |
456 | 457 | ||
457 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | 458 | bfa_get_adapter_model(&bfad->bfa, model_descr); |
458 | bfa_get_attr(&bfad->bfa, &ioc_attr); | 459 | return snprintf(buf, PAGE_SIZE, "%s\n", model_descr); |
459 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
460 | ioc_attr.adapter_attr.model_descr); | ||
461 | } | 460 | } |
462 | 461 | ||
463 | static ssize_t | 462 | static ssize_t |
@@ -482,14 +481,13 @@ bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr, | |||
482 | struct bfad_im_port_s *im_port = | 481 | struct bfad_im_port_s *im_port = |
483 | (struct bfad_im_port_s *) shost->hostdata[0]; | 482 | (struct bfad_im_port_s *) shost->hostdata[0]; |
484 | struct bfad_s *bfad = im_port->bfad; | 483 | struct bfad_s *bfad = im_port->bfad; |
485 | struct bfa_ioc_attr_s ioc_attr; | 484 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; |
486 | 485 | char fw_ver[BFA_VERSION_LEN]; | |
487 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | ||
488 | bfa_get_attr(&bfad->bfa, &ioc_attr); | ||
489 | 486 | ||
487 | bfa_get_adapter_model(&bfad->bfa, model); | ||
488 | bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); | ||
490 | return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n", | 489 | return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n", |
491 | ioc_attr.adapter_attr.model, | 490 | model, fw_ver, BFAD_DRIVER_VERSION); |
492 | ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION); | ||
493 | } | 491 | } |
494 | 492 | ||
495 | static ssize_t | 493 | static ssize_t |
@@ -500,11 +498,10 @@ bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr, | |||
500 | struct bfad_im_port_s *im_port = | 498 | struct bfad_im_port_s *im_port = |
501 | (struct bfad_im_port_s *) shost->hostdata[0]; | 499 | (struct bfad_im_port_s *) shost->hostdata[0]; |
502 | struct bfad_s *bfad = im_port->bfad; | 500 | struct bfad_s *bfad = im_port->bfad; |
503 | struct bfa_ioc_attr_s ioc_attr; | 501 | char hw_ver[BFA_VERSION_LEN]; |
504 | 502 | ||
505 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | 503 | bfa_get_pci_chip_rev(&bfad->bfa, hw_ver); |
506 | bfa_get_attr(&bfad->bfa, &ioc_attr); | 504 | return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver); |
507 | return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.hw_ver); | ||
508 | } | 505 | } |
509 | 506 | ||
510 | static ssize_t | 507 | static ssize_t |
@@ -522,12 +519,10 @@ bfad_im_optionrom_version_show(struct device *dev, | |||
522 | struct bfad_im_port_s *im_port = | 519 | struct bfad_im_port_s *im_port = |
523 | (struct bfad_im_port_s *) shost->hostdata[0]; | 520 | (struct bfad_im_port_s *) shost->hostdata[0]; |
524 | struct bfad_s *bfad = im_port->bfad; | 521 | struct bfad_s *bfad = im_port->bfad; |
525 | struct bfa_ioc_attr_s ioc_attr; | 522 | char optrom_ver[BFA_VERSION_LEN]; |
526 | 523 | ||
527 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | 524 | bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver); |
528 | bfa_get_attr(&bfad->bfa, &ioc_attr); | 525 | return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver); |
529 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
530 | ioc_attr.adapter_attr.optrom_ver); | ||
531 | } | 526 | } |
532 | 527 | ||
533 | static ssize_t | 528 | static ssize_t |
@@ -538,11 +533,10 @@ bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr, | |||
538 | struct bfad_im_port_s *im_port = | 533 | struct bfad_im_port_s *im_port = |
539 | (struct bfad_im_port_s *) shost->hostdata[0]; | 534 | (struct bfad_im_port_s *) shost->hostdata[0]; |
540 | struct bfad_s *bfad = im_port->bfad; | 535 | struct bfad_s *bfad = im_port->bfad; |
541 | struct bfa_ioc_attr_s ioc_attr; | 536 | char fw_ver[BFA_VERSION_LEN]; |
542 | 537 | ||
543 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | 538 | bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); |
544 | bfa_get_attr(&bfad->bfa, &ioc_attr); | 539 | return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver); |
545 | return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.fw_ver); | ||
546 | } | 540 | } |
547 | 541 | ||
548 | static ssize_t | 542 | static ssize_t |
@@ -553,11 +547,9 @@ bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr, | |||
553 | struct bfad_im_port_s *im_port = | 547 | struct bfad_im_port_s *im_port = |
554 | (struct bfad_im_port_s *) shost->hostdata[0]; | 548 | (struct bfad_im_port_s *) shost->hostdata[0]; |
555 | struct bfad_s *bfad = im_port->bfad; | 549 | struct bfad_s *bfad = im_port->bfad; |
556 | struct bfa_ioc_attr_s ioc_attr; | ||
557 | 550 | ||
558 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | 551 | return snprintf(buf, PAGE_SIZE, "%d\n", |
559 | bfa_get_attr(&bfad->bfa, &ioc_attr); | 552 | bfa_get_nports(&bfad->bfa)); |
560 | return snprintf(buf, PAGE_SIZE, "%d\n", ioc_attr.adapter_attr.nports); | ||
561 | } | 553 | } |
562 | 554 | ||
563 | static ssize_t | 555 | static ssize_t |
diff --git a/drivers/scsi/bfa/bfad_attr.h b/drivers/scsi/bfa/bfad_attr.h index 4d3312da6a81..bf0102076508 100644 --- a/drivers/scsi/bfa/bfad_attr.h +++ b/drivers/scsi/bfa/bfad_attr.h | |||
@@ -17,9 +17,6 @@ | |||
17 | 17 | ||
18 | #ifndef __BFAD_ATTR_H__ | 18 | #ifndef __BFAD_ATTR_H__ |
19 | #define __BFAD_ATTR_H__ | 19 | #define __BFAD_ATTR_H__ |
20 | /** | ||
21 | * bfad_attr.h VMware driver configuration interface module. | ||
22 | */ | ||
23 | 20 | ||
24 | /** | 21 | /** |
25 | * FC_transport_template FC transport template | 22 | * FC_transport_template FC transport template |
@@ -52,12 +49,6 @@ bfad_im_get_starget_port_name(struct scsi_target *starget); | |||
52 | void | 49 | void |
53 | bfad_im_get_host_port_id(struct Scsi_Host *shost); | 50 | bfad_im_get_host_port_id(struct Scsi_Host *shost); |
54 | 51 | ||
55 | /** | ||
56 | * FC transport template entry, issue a LIP. | ||
57 | */ | ||
58 | int | ||
59 | bfad_im_issue_fc_host_lip(struct Scsi_Host *shost); | ||
60 | |||
61 | struct Scsi_Host* | 52 | struct Scsi_Host* |
62 | bfad_os_starget_to_shost(struct scsi_target *starget); | 53 | bfad_os_starget_to_shost(struct scsi_target *starget); |
63 | 54 | ||
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 172c81e25c1c..107848cd3b6d 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h | |||
@@ -46,7 +46,7 @@ | |||
46 | #ifdef BFA_DRIVER_VERSION | 46 | #ifdef BFA_DRIVER_VERSION |
47 | #define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION | 47 | #define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION |
48 | #else | 48 | #else |
49 | #define BFAD_DRIVER_VERSION "2.0.0.0" | 49 | #define BFAD_DRIVER_VERSION "2.1.2.1" |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | 52 | ||
@@ -62,7 +62,9 @@ | |||
62 | #define BFAD_HAL_START_DONE 0x00000010 | 62 | #define BFAD_HAL_START_DONE 0x00000010 |
63 | #define BFAD_PORT_ONLINE 0x00000020 | 63 | #define BFAD_PORT_ONLINE 0x00000020 |
64 | #define BFAD_RPORT_ONLINE 0x00000040 | 64 | #define BFAD_RPORT_ONLINE 0x00000040 |
65 | 65 | #define BFAD_FCS_INIT_DONE 0x00000080 | |
66 | #define BFAD_HAL_INIT_FAIL 0x00000100 | ||
67 | #define BFAD_FC4_PROBE_DONE 0x00000200 | ||
66 | #define BFAD_PORT_DELETE 0x00000001 | 68 | #define BFAD_PORT_DELETE 0x00000001 |
67 | 69 | ||
68 | /* | 70 | /* |
@@ -137,12 +139,16 @@ struct bfad_cfg_param_s { | |||
137 | u32 binding_method; | 139 | u32 binding_method; |
138 | }; | 140 | }; |
139 | 141 | ||
140 | #define BFAD_AEN_MAX_APPS 8 | 142 | union bfad_tmp_buf { |
141 | struct bfad_aen_file_s { | 143 | /* From struct bfa_adapter_attr_s */ |
142 | struct list_head qe; | 144 | char manufacturer[BFA_ADAPTER_MFG_NAME_LEN]; |
143 | struct bfad_s *bfad; | 145 | char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; |
144 | s32 ri; | 146 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; |
145 | s32 app_id; | 147 | char fw_ver[BFA_VERSION_LEN]; |
148 | char optrom_ver[BFA_VERSION_LEN]; | ||
149 | |||
150 | /* From struct bfa_ioc_pci_attr_s */ | ||
151 | u8 chip_rev[BFA_IOC_CHIP_REV_LEN]; /* chip revision */ | ||
146 | }; | 152 | }; |
147 | 153 | ||
148 | /* | 154 | /* |
@@ -168,6 +174,7 @@ struct bfad_s { | |||
168 | u32 inst_no; /* BFAD instance number */ | 174 | u32 inst_no; /* BFAD instance number */ |
169 | u32 bfad_flags; | 175 | u32 bfad_flags; |
170 | spinlock_t bfad_lock; | 176 | spinlock_t bfad_lock; |
177 | struct task_struct *bfad_tsk; | ||
171 | struct bfad_cfg_param_s cfg_data; | 178 | struct bfad_cfg_param_s cfg_data; |
172 | struct bfad_msix_s msix_tab[MAX_MSIX_ENTRY]; | 179 | struct bfad_msix_s msix_tab[MAX_MSIX_ENTRY]; |
173 | int nvec; | 180 | int nvec; |
@@ -183,18 +190,12 @@ struct bfad_s { | |||
183 | struct bfa_log_mod_s *logmod; | 190 | struct bfa_log_mod_s *logmod; |
184 | struct bfa_aen_s *aen; | 191 | struct bfa_aen_s *aen; |
185 | struct bfa_aen_s aen_buf; | 192 | struct bfa_aen_s aen_buf; |
186 | struct bfad_aen_file_s file_buf[BFAD_AEN_MAX_APPS]; | 193 | void *file_map[BFA_AEN_MAX_APP]; |
187 | struct list_head file_q; | ||
188 | struct list_head file_free_q; | ||
189 | struct bfa_plog_s plog_buf; | 194 | struct bfa_plog_s plog_buf; |
190 | int ref_count; | 195 | int ref_count; |
191 | bfa_boolean_t ipfc_enabled; | 196 | bfa_boolean_t ipfc_enabled; |
197 | union bfad_tmp_buf tmp_buf; | ||
192 | struct fc_host_statistics link_stats; | 198 | struct fc_host_statistics link_stats; |
193 | |||
194 | struct kobject *bfa_kobj; | ||
195 | struct kobject *ioc_kobj; | ||
196 | struct kobject *pport_kobj; | ||
197 | struct kobject *lport_kobj; | ||
198 | }; | 199 | }; |
199 | 200 | ||
200 | /* | 201 | /* |
@@ -258,6 +259,7 @@ bfa_status_t bfad_vf_create(struct bfad_s *bfad, u16 vf_id, | |||
258 | struct bfa_port_cfg_s *port_cfg); | 259 | struct bfa_port_cfg_s *port_cfg); |
259 | bfa_status_t bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role); | 260 | bfa_status_t bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role); |
260 | bfa_status_t bfad_drv_init(struct bfad_s *bfad); | 261 | bfa_status_t bfad_drv_init(struct bfad_s *bfad); |
262 | bfa_status_t bfad_start_ops(struct bfad_s *bfad); | ||
261 | void bfad_drv_start(struct bfad_s *bfad); | 263 | void bfad_drv_start(struct bfad_s *bfad); |
262 | void bfad_uncfg_pport(struct bfad_s *bfad); | 264 | void bfad_uncfg_pport(struct bfad_s *bfad); |
263 | void bfad_drv_stop(struct bfad_s *bfad); | 265 | void bfad_drv_stop(struct bfad_s *bfad); |
@@ -279,6 +281,7 @@ void bfad_drv_uninit(struct bfad_s *bfad); | |||
279 | void bfad_drv_log_level_set(struct bfad_s *bfad); | 281 | void bfad_drv_log_level_set(struct bfad_s *bfad); |
280 | bfa_status_t bfad_fc4_module_init(void); | 282 | bfa_status_t bfad_fc4_module_init(void); |
281 | void bfad_fc4_module_exit(void); | 283 | void bfad_fc4_module_exit(void); |
284 | int bfad_worker (void *ptr); | ||
282 | 285 | ||
283 | void bfad_pci_remove(struct pci_dev *pdev); | 286 | void bfad_pci_remove(struct pci_dev *pdev); |
284 | int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid); | 287 | int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid); |
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index f788c2a0ab07..f9fc67a25bf2 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c | |||
@@ -43,11 +43,11 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio, | |||
43 | struct bfad_s *bfad = drv; | 43 | struct bfad_s *bfad = drv; |
44 | struct bfad_itnim_data_s *itnim_data; | 44 | struct bfad_itnim_data_s *itnim_data; |
45 | struct bfad_itnim_s *itnim; | 45 | struct bfad_itnim_s *itnim; |
46 | u8 host_status = DID_OK; | ||
46 | 47 | ||
47 | switch (io_status) { | 48 | switch (io_status) { |
48 | case BFI_IOIM_STS_OK: | 49 | case BFI_IOIM_STS_OK: |
49 | bfa_trc(bfad, scsi_status); | 50 | bfa_trc(bfad, scsi_status); |
50 | cmnd->result = ScsiResult(DID_OK, scsi_status); | ||
51 | scsi_set_resid(cmnd, 0); | 51 | scsi_set_resid(cmnd, 0); |
52 | 52 | ||
53 | if (sns_len > 0) { | 53 | if (sns_len > 0) { |
@@ -56,8 +56,18 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio, | |||
56 | sns_len = SCSI_SENSE_BUFFERSIZE; | 56 | sns_len = SCSI_SENSE_BUFFERSIZE; |
57 | memcpy(cmnd->sense_buffer, sns_info, sns_len); | 57 | memcpy(cmnd->sense_buffer, sns_info, sns_len); |
58 | } | 58 | } |
59 | if (residue > 0) | 59 | if (residue > 0) { |
60 | bfa_trc(bfad, residue); | ||
60 | scsi_set_resid(cmnd, residue); | 61 | scsi_set_resid(cmnd, residue); |
62 | if (!sns_len && (scsi_status == SAM_STAT_GOOD) && | ||
63 | (scsi_bufflen(cmnd) - residue) < | ||
64 | cmnd->underflow) { | ||
65 | bfa_trc(bfad, 0); | ||
66 | host_status = DID_ERROR; | ||
67 | } | ||
68 | } | ||
69 | cmnd->result = ScsiResult(host_status, scsi_status); | ||
70 | |||
61 | break; | 71 | break; |
62 | 72 | ||
63 | case BFI_IOIM_STS_ABORTED: | 73 | case BFI_IOIM_STS_ABORTED: |
@@ -167,17 +177,15 @@ bfad_im_info(struct Scsi_Host *shost) | |||
167 | static char bfa_buf[256]; | 177 | static char bfa_buf[256]; |
168 | struct bfad_im_port_s *im_port = | 178 | struct bfad_im_port_s *im_port = |
169 | (struct bfad_im_port_s *) shost->hostdata[0]; | 179 | (struct bfad_im_port_s *) shost->hostdata[0]; |
170 | struct bfa_ioc_attr_s ioc_attr; | ||
171 | struct bfad_s *bfad = im_port->bfad; | 180 | struct bfad_s *bfad = im_port->bfad; |
181 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; | ||
172 | 182 | ||
173 | memset(&ioc_attr, 0, sizeof(ioc_attr)); | 183 | bfa_get_adapter_model(&bfad->bfa, model); |
174 | bfa_get_attr(&bfad->bfa, &ioc_attr); | ||
175 | 184 | ||
176 | memset(bfa_buf, 0, sizeof(bfa_buf)); | 185 | memset(bfa_buf, 0, sizeof(bfa_buf)); |
177 | snprintf(bfa_buf, sizeof(bfa_buf), | 186 | snprintf(bfa_buf, sizeof(bfa_buf), |
178 | "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s", | 187 | "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s", |
179 | ioc_attr.adapter_attr.model, bfad->pci_name, | 188 | model, bfad->pci_name, BFAD_DRIVER_VERSION); |
180 | BFAD_DRIVER_VERSION); | ||
181 | return bfa_buf; | 189 | return bfa_buf; |
182 | } | 190 | } |
183 | 191 | ||
@@ -501,16 +509,6 @@ void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim) | |||
501 | } | 509 | } |
502 | 510 | ||
503 | /** | 511 | /** |
504 | * Path TOV processing begin notification -- dummy for linux | ||
505 | */ | ||
506 | void | ||
507 | bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim) | ||
508 | { | ||
509 | } | ||
510 | |||
511 | |||
512 | |||
513 | /** | ||
514 | * Allocate a Scsi_Host for a port. | 512 | * Allocate a Scsi_Host for a port. |
515 | */ | 513 | */ |
516 | int | 514 | int |
@@ -931,10 +929,9 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port) | |||
931 | struct Scsi_Host *host = im_port->shost; | 929 | struct Scsi_Host *host = im_port->shost; |
932 | struct bfad_s *bfad = im_port->bfad; | 930 | struct bfad_s *bfad = im_port->bfad; |
933 | struct bfad_port_s *port = im_port->port; | 931 | struct bfad_port_s *port = im_port->port; |
934 | union attr { | 932 | struct bfa_pport_attr_s pattr; |
935 | struct bfa_pport_attr_s pattr; | 933 | char model[BFA_ADAPTER_MODEL_NAME_LEN]; |
936 | struct bfa_ioc_attr_s ioc_attr; | 934 | char fw_ver[BFA_VERSION_LEN]; |
937 | } attr; | ||
938 | 935 | ||
939 | fc_host_node_name(host) = | 936 | fc_host_node_name(host) = |
940 | bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port))); | 937 | bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port))); |
@@ -954,20 +951,18 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port) | |||
954 | /* For fibre channel services type 0x20 */ | 951 | /* For fibre channel services type 0x20 */ |
955 | fc_host_supported_fc4s(host)[7] = 1; | 952 | fc_host_supported_fc4s(host)[7] = 1; |
956 | 953 | ||
957 | memset(&attr.ioc_attr, 0, sizeof(attr.ioc_attr)); | 954 | bfa_get_adapter_model(&bfad->bfa, model); |
958 | bfa_get_attr(&bfad->bfa, &attr.ioc_attr); | 955 | bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); |
959 | sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s", | 956 | sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s", |
960 | attr.ioc_attr.adapter_attr.model, | 957 | model, fw_ver, BFAD_DRIVER_VERSION); |
961 | attr.ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION); | ||
962 | 958 | ||
963 | fc_host_supported_speeds(host) = 0; | 959 | fc_host_supported_speeds(host) = 0; |
964 | fc_host_supported_speeds(host) |= | 960 | fc_host_supported_speeds(host) |= |
965 | FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | | 961 | FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | |
966 | FC_PORTSPEED_1GBIT; | 962 | FC_PORTSPEED_1GBIT; |
967 | 963 | ||
968 | memset(&attr.pattr, 0, sizeof(attr.pattr)); | 964 | bfa_fcport_get_attr(&bfad->bfa, &pattr); |
969 | bfa_pport_get_attr(&bfad->bfa, &attr.pattr); | 965 | fc_host_maxframe_size(host) = pattr.pport_cfg.maxfrsize; |
970 | fc_host_maxframe_size(host) = attr.pattr.pport_cfg.maxfrsize; | ||
971 | } | 966 | } |
972 | 967 | ||
973 | static void | 968 | static void |
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h index 189a5b29e21a..85ab2da21321 100644 --- a/drivers/scsi/bfa/bfad_im.h +++ b/drivers/scsi/bfa/bfad_im.h | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #define FCPI_NAME " fcpim" | 24 | #define FCPI_NAME " fcpim" |
25 | 25 | ||
26 | void bfad_flags_set(struct bfad_s *bfad, u32 flags); | ||
27 | bfa_status_t bfad_im_module_init(void); | 26 | bfa_status_t bfad_im_module_init(void); |
28 | void bfad_im_module_exit(void); | 27 | void bfad_im_module_exit(void); |
29 | bfa_status_t bfad_im_probe(struct bfad_s *bfad); | 28 | bfa_status_t bfad_im_probe(struct bfad_s *bfad); |
@@ -126,7 +125,6 @@ bfa_status_t bfad_os_thread_workq(struct bfad_s *bfad); | |||
126 | void bfad_os_destroy_workq(struct bfad_im_s *im); | 125 | void bfad_os_destroy_workq(struct bfad_im_s *im); |
127 | void bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv); | 126 | void bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv); |
128 | void bfad_os_fc_host_init(struct bfad_im_port_s *im_port); | 127 | void bfad_os_fc_host_init(struct bfad_im_port_s *im_port); |
129 | void bfad_os_init_work(struct bfad_im_port_s *im_port); | ||
130 | void bfad_os_scsi_host_free(struct bfad_s *bfad, | 128 | void bfad_os_scsi_host_free(struct bfad_s *bfad, |
131 | struct bfad_im_port_s *im_port); | 129 | struct bfad_im_port_s *im_port); |
132 | void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, | 130 | void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, |
@@ -136,9 +134,6 @@ struct bfad_itnim_s *bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id); | |||
136 | int bfad_os_scsi_add_host(struct Scsi_Host *shost, | 134 | int bfad_os_scsi_add_host(struct Scsi_Host *shost, |
137 | struct bfad_im_port_s *im_port, struct bfad_s *bfad); | 135 | struct bfad_im_port_s *im_port, struct bfad_s *bfad); |
138 | 136 | ||
139 | /* | ||
140 | * scsi_host_template entries | ||
141 | */ | ||
142 | void bfad_im_itnim_unmap(struct bfad_im_port_s *im_port, | 137 | void bfad_im_itnim_unmap(struct bfad_im_port_s *im_port, |
143 | struct bfad_itnim_s *itnim); | 138 | struct bfad_itnim_s *itnim); |
144 | 139 | ||
diff --git a/drivers/scsi/bfa/bfad_intr.c b/drivers/scsi/bfa/bfad_intr.c index 7de8832f6fee..2b7dbecbebca 100644 --- a/drivers/scsi/bfa/bfad_intr.c +++ b/drivers/scsi/bfa/bfad_intr.c | |||
@@ -23,8 +23,10 @@ BFA_TRC_FILE(LDRV, INTR); | |||
23 | /** | 23 | /** |
24 | * bfa_isr BFA driver interrupt functions | 24 | * bfa_isr BFA driver interrupt functions |
25 | */ | 25 | */ |
26 | static int msix_disable; | 26 | static int msix_disable_cb; |
27 | module_param(msix_disable, int, S_IRUGO | S_IWUSR); | 27 | static int msix_disable_ct; |
28 | module_param(msix_disable_cb, int, S_IRUGO | S_IWUSR); | ||
29 | module_param(msix_disable_ct, int, S_IRUGO | S_IWUSR); | ||
28 | /** | 30 | /** |
29 | * Line based interrupt handler. | 31 | * Line based interrupt handler. |
30 | */ | 32 | */ |
@@ -141,6 +143,7 @@ bfad_setup_intr(struct bfad_s *bfad) | |||
141 | int error = 0; | 143 | int error = 0; |
142 | u32 mask = 0, i, num_bit = 0, max_bit = 0; | 144 | u32 mask = 0, i, num_bit = 0, max_bit = 0; |
143 | struct msix_entry msix_entries[MAX_MSIX_ENTRY]; | 145 | struct msix_entry msix_entries[MAX_MSIX_ENTRY]; |
146 | struct pci_dev *pdev = bfad->pcidev; | ||
144 | 147 | ||
145 | /* Call BFA to get the msix map for this PCI function. */ | 148 | /* Call BFA to get the msix map for this PCI function. */ |
146 | bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit); | 149 | bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit); |
@@ -148,7 +151,9 @@ bfad_setup_intr(struct bfad_s *bfad) | |||
148 | /* Set up the msix entry table */ | 151 | /* Set up the msix entry table */ |
149 | bfad_init_msix_entry(bfad, msix_entries, mask, max_bit); | 152 | bfad_init_msix_entry(bfad, msix_entries, mask, max_bit); |
150 | 153 | ||
151 | if (!msix_disable) { | 154 | if ((pdev->device == BFA_PCI_DEVICE_ID_CT && !msix_disable_ct) || |
155 | (pdev->device != BFA_PCI_DEVICE_ID_CT && !msix_disable_cb)) { | ||
156 | |||
152 | error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec); | 157 | error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec); |
153 | if (error) { | 158 | if (error) { |
154 | /* | 159 | /* |
diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c index a4b5dd449573..8166e9745ec0 100644 --- a/drivers/scsi/bfa/fabric.c +++ b/drivers/scsi/bfa/fabric.c | |||
@@ -37,7 +37,7 @@ BFA_TRC_FILE(FCS, FABRIC); | |||
37 | #define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */ | 37 | #define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */ |
38 | 38 | ||
39 | #define bfa_fcs_fabric_set_opertype(__fabric) do { \ | 39 | #define bfa_fcs_fabric_set_opertype(__fabric) do { \ |
40 | if (bfa_pport_get_topology((__fabric)->fcs->bfa) \ | 40 | if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \ |
41 | == BFA_PPORT_TOPOLOGY_P2P) \ | 41 | == BFA_PPORT_TOPOLOGY_P2P) \ |
42 | (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT; \ | 42 | (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT; \ |
43 | else \ | 43 | else \ |
@@ -136,8 +136,7 @@ bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric, | |||
136 | case BFA_FCS_FABRIC_SM_CREATE: | 136 | case BFA_FCS_FABRIC_SM_CREATE: |
137 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created); | 137 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created); |
138 | bfa_fcs_fabric_init(fabric); | 138 | bfa_fcs_fabric_init(fabric); |
139 | bfa_fcs_lport_init(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, | 139 | bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg); |
140 | &fabric->bport.port_cfg, NULL); | ||
141 | break; | 140 | break; |
142 | 141 | ||
143 | case BFA_FCS_FABRIC_SM_LINK_UP: | 142 | case BFA_FCS_FABRIC_SM_LINK_UP: |
@@ -161,7 +160,7 @@ bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric, | |||
161 | 160 | ||
162 | switch (event) { | 161 | switch (event) { |
163 | case BFA_FCS_FABRIC_SM_START: | 162 | case BFA_FCS_FABRIC_SM_START: |
164 | if (bfa_pport_is_linkup(fabric->fcs->bfa)) { | 163 | if (bfa_fcport_is_linkup(fabric->fcs->bfa)) { |
165 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); | 164 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); |
166 | bfa_fcs_fabric_login(fabric); | 165 | bfa_fcs_fabric_login(fabric); |
167 | } else | 166 | } else |
@@ -225,7 +224,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric, | |||
225 | switch (event) { | 224 | switch (event) { |
226 | case BFA_FCS_FABRIC_SM_CONT_OP: | 225 | case BFA_FCS_FABRIC_SM_CONT_OP: |
227 | 226 | ||
228 | bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); | 227 | bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); |
229 | fabric->fab_type = BFA_FCS_FABRIC_SWITCHED; | 228 | fabric->fab_type = BFA_FCS_FABRIC_SWITCHED; |
230 | 229 | ||
231 | if (fabric->auth_reqd && fabric->is_auth) { | 230 | if (fabric->auth_reqd && fabric->is_auth) { |
@@ -252,7 +251,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric, | |||
252 | 251 | ||
253 | case BFA_FCS_FABRIC_SM_NO_FABRIC: | 252 | case BFA_FCS_FABRIC_SM_NO_FABRIC: |
254 | fabric->fab_type = BFA_FCS_FABRIC_N2N; | 253 | fabric->fab_type = BFA_FCS_FABRIC_N2N; |
255 | bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); | 254 | bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); |
256 | bfa_fcs_fabric_notify_online(fabric); | 255 | bfa_fcs_fabric_notify_online(fabric); |
257 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric); | 256 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric); |
258 | break; | 257 | break; |
@@ -419,7 +418,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric, | |||
419 | 418 | ||
420 | case BFA_FCS_FABRIC_SM_NO_FABRIC: | 419 | case BFA_FCS_FABRIC_SM_NO_FABRIC: |
421 | bfa_trc(fabric->fcs, fabric->bb_credit); | 420 | bfa_trc(fabric->fcs, fabric->bb_credit); |
422 | bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); | 421 | bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); |
423 | break; | 422 | break; |
424 | 423 | ||
425 | default: | 424 | default: |
@@ -563,17 +562,15 @@ void | |||
563 | bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric) | 562 | bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric) |
564 | { | 563 | { |
565 | struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg; | 564 | struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg; |
566 | struct bfa_adapter_attr_s adapter_attr; | 565 | char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0}; |
567 | struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info; | 566 | struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info; |
568 | 567 | ||
569 | bfa_os_memset((void *)&adapter_attr, 0, | 568 | bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model); |
570 | sizeof(struct bfa_adapter_attr_s)); | ||
571 | bfa_ioc_get_adapter_attr(&fabric->fcs->bfa->ioc, &adapter_attr); | ||
572 | 569 | ||
573 | /* | 570 | /* |
574 | * Model name/number | 571 | * Model name/number |
575 | */ | 572 | */ |
576 | strncpy((char *)&port_cfg->sym_name, adapter_attr.model, | 573 | strncpy((char *)&port_cfg->sym_name, model, |
577 | BFA_FCS_PORT_SYMBNAME_MODEL_SZ); | 574 | BFA_FCS_PORT_SYMBNAME_MODEL_SZ); |
578 | strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, | 575 | strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, |
579 | sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); | 576 | sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); |
@@ -719,10 +716,10 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric) | |||
719 | struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg; | 716 | struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg; |
720 | u8 alpa = 0; | 717 | u8 alpa = 0; |
721 | 718 | ||
722 | if (bfa_pport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP) | 719 | if (bfa_fcport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP) |
723 | alpa = bfa_pport_get_myalpa(bfa); | 720 | alpa = bfa_fcport_get_myalpa(bfa); |
724 | 721 | ||
725 | bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_pport_get_maxfrsize(bfa), | 722 | bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa), |
726 | pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd); | 723 | pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd); |
727 | 724 | ||
728 | fabric->stats.flogi_sent++; | 725 | fabric->stats.flogi_sent++; |
@@ -814,10 +811,10 @@ bfa_fcs_fabric_delete_comp(void *cbarg) | |||
814 | */ | 811 | */ |
815 | 812 | ||
816 | /** | 813 | /** |
817 | * Module initialization | 814 | * Attach time initialization |
818 | */ | 815 | */ |
819 | void | 816 | void |
820 | bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs) | 817 | bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs) |
821 | { | 818 | { |
822 | struct bfa_fcs_fabric_s *fabric; | 819 | struct bfa_fcs_fabric_s *fabric; |
823 | 820 | ||
@@ -841,7 +838,13 @@ bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs) | |||
841 | bfa_wc_up(&fabric->wc); /* For the base port */ | 838 | bfa_wc_up(&fabric->wc); /* For the base port */ |
842 | 839 | ||
843 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit); | 840 | bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit); |
844 | bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CREATE); | 841 | bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL); |
842 | } | ||
843 | |||
844 | void | ||
845 | bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs) | ||
846 | { | ||
847 | bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE); | ||
845 | bfa_trc(fcs, 0); | 848 | bfa_trc(fcs, 0); |
846 | } | 849 | } |
847 | 850 | ||
@@ -890,6 +893,12 @@ bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric) | |||
890 | return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback); | 893 | return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback); |
891 | } | 894 | } |
892 | 895 | ||
896 | bfa_boolean_t | ||
897 | bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric) | ||
898 | { | ||
899 | return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_auth_failed); | ||
900 | } | ||
901 | |||
893 | enum bfa_pport_type | 902 | enum bfa_pport_type |
894 | bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric) | 903 | bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric) |
895 | { | 904 | { |
@@ -1165,8 +1174,8 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric) | |||
1165 | reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), | 1174 | reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), |
1166 | bfa_os_hton3b(FC_FABRIC_PORT), | 1175 | bfa_os_hton3b(FC_FABRIC_PORT), |
1167 | n2n_port->reply_oxid, pcfg->pwwn, | 1176 | n2n_port->reply_oxid, pcfg->pwwn, |
1168 | pcfg->nwwn, bfa_pport_get_maxfrsize(bfa), | 1177 | pcfg->nwwn, bfa_fcport_get_maxfrsize(bfa), |
1169 | bfa_pport_get_rx_bbcredit(bfa)); | 1178 | bfa_fcport_get_rx_bbcredit(bfa)); |
1170 | 1179 | ||
1171 | bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps), | 1180 | bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps), |
1172 | BFA_FALSE, FC_CLASS_3, reqlen, &fchs, | 1181 | BFA_FALSE, FC_CLASS_3, reqlen, &fchs, |
@@ -1224,14 +1233,8 @@ bfa_fcs_fabric_aen_post(struct bfa_fcs_port_s *port, | |||
1224 | wwn2str(pwwn_ptr, pwwn); | 1233 | wwn2str(pwwn_ptr, pwwn); |
1225 | wwn2str(fwwn_ptr, fwwn); | 1234 | wwn2str(fwwn_ptr, fwwn); |
1226 | 1235 | ||
1227 | switch (event) { | 1236 | bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event), |
1228 | case BFA_PORT_AEN_FABRIC_NAME_CHANGE: | 1237 | pwwn_ptr, fwwn_ptr); |
1229 | bfa_log(logmod, BFA_AEN_PORT_FABRIC_NAME_CHANGE, pwwn_ptr, | ||
1230 | fwwn_ptr); | ||
1231 | break; | ||
1232 | default: | ||
1233 | break; | ||
1234 | } | ||
1235 | 1238 | ||
1236 | aen_data.port.pwwn = pwwn; | 1239 | aen_data.port.pwwn = pwwn; |
1237 | aen_data.port.fwwn = fwwn; | 1240 | aen_data.port.fwwn = fwwn; |
diff --git a/drivers/scsi/bfa/fcbuild.h b/drivers/scsi/bfa/fcbuild.h index 8fa7f270ef7b..981d98d542b9 100644 --- a/drivers/scsi/bfa/fcbuild.h +++ b/drivers/scsi/bfa/fcbuild.h | |||
@@ -72,6 +72,9 @@ fc_rpsc_operspeed_to_bfa_speed(enum fc_rpsc_op_speed_s speed) | |||
72 | case RPSC_OP_SPEED_8G: | 72 | case RPSC_OP_SPEED_8G: |
73 | return BFA_PPORT_SPEED_8GBPS; | 73 | return BFA_PPORT_SPEED_8GBPS; |
74 | 74 | ||
75 | case RPSC_OP_SPEED_10G: | ||
76 | return BFA_PPORT_SPEED_10GBPS; | ||
77 | |||
75 | default: | 78 | default: |
76 | return BFA_PPORT_SPEED_UNKNOWN; | 79 | return BFA_PPORT_SPEED_UNKNOWN; |
77 | } | 80 | } |
@@ -97,6 +100,9 @@ fc_bfa_speed_to_rpsc_operspeed(enum bfa_pport_speed op_speed) | |||
97 | case BFA_PPORT_SPEED_8GBPS: | 100 | case BFA_PPORT_SPEED_8GBPS: |
98 | return RPSC_OP_SPEED_8G; | 101 | return RPSC_OP_SPEED_8G; |
99 | 102 | ||
103 | case BFA_PPORT_SPEED_10GBPS: | ||
104 | return RPSC_OP_SPEED_10G; | ||
105 | |||
100 | default: | 106 | default: |
101 | return RPSC_OP_SPEED_NOT_EST; | 107 | return RPSC_OP_SPEED_NOT_EST; |
102 | } | 108 | } |
diff --git a/drivers/scsi/bfa/fcpim.c b/drivers/scsi/bfa/fcpim.c index 1f3c06efaa9e..8ae4a2cfa85b 100644 --- a/drivers/scsi/bfa/fcpim.c +++ b/drivers/scsi/bfa/fcpim.c | |||
@@ -126,7 +126,7 @@ bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim, | |||
126 | break; | 126 | break; |
127 | 127 | ||
128 | default: | 128 | default: |
129 | bfa_assert(0); | 129 | bfa_sm_fault(itnim->fcs, event); |
130 | } | 130 | } |
131 | 131 | ||
132 | } | 132 | } |
@@ -161,7 +161,7 @@ bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim, | |||
161 | break; | 161 | break; |
162 | 162 | ||
163 | default: | 163 | default: |
164 | bfa_assert(0); | 164 | bfa_sm_fault(itnim->fcs, event); |
165 | } | 165 | } |
166 | } | 166 | } |
167 | 167 | ||
@@ -205,7 +205,7 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim, | |||
205 | break; | 205 | break; |
206 | 206 | ||
207 | default: | 207 | default: |
208 | bfa_assert(0); | 208 | bfa_sm_fault(itnim->fcs, event); |
209 | } | 209 | } |
210 | } | 210 | } |
211 | 211 | ||
@@ -240,7 +240,7 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim, | |||
240 | break; | 240 | break; |
241 | 241 | ||
242 | default: | 242 | default: |
243 | bfa_assert(0); | 243 | bfa_sm_fault(itnim->fcs, event); |
244 | } | 244 | } |
245 | } | 245 | } |
246 | 246 | ||
@@ -270,7 +270,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim, | |||
270 | break; | 270 | break; |
271 | 271 | ||
272 | default: | 272 | default: |
273 | bfa_assert(0); | 273 | bfa_sm_fault(itnim->fcs, event); |
274 | } | 274 | } |
275 | } | 275 | } |
276 | 276 | ||
@@ -298,7 +298,7 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim, | |||
298 | break; | 298 | break; |
299 | 299 | ||
300 | default: | 300 | default: |
301 | bfa_assert(0); | 301 | bfa_sm_fault(itnim->fcs, event); |
302 | } | 302 | } |
303 | } | 303 | } |
304 | 304 | ||
@@ -321,7 +321,7 @@ bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim, | |||
321 | break; | 321 | break; |
322 | 322 | ||
323 | default: | 323 | default: |
324 | bfa_assert(0); | 324 | bfa_sm_fault(itnim->fcs, event); |
325 | } | 325 | } |
326 | } | 326 | } |
327 | 327 | ||
@@ -354,7 +354,7 @@ bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim, | |||
354 | break; | 354 | break; |
355 | 355 | ||
356 | default: | 356 | default: |
357 | bfa_assert(0); | 357 | bfa_sm_fault(itnim->fcs, event); |
358 | } | 358 | } |
359 | } | 359 | } |
360 | 360 | ||
@@ -385,19 +385,8 @@ bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim, | |||
385 | wwn2str(lpwwn_ptr, lpwwn); | 385 | wwn2str(lpwwn_ptr, lpwwn); |
386 | wwn2str(rpwwn_ptr, rpwwn); | 386 | wwn2str(rpwwn_ptr, rpwwn); |
387 | 387 | ||
388 | switch (event) { | 388 | bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, event), |
389 | case BFA_ITNIM_AEN_ONLINE: | 389 | rpwwn_ptr, lpwwn_ptr); |
390 | bfa_log(logmod, BFA_AEN_ITNIM_ONLINE, rpwwn_ptr, lpwwn_ptr); | ||
391 | break; | ||
392 | case BFA_ITNIM_AEN_OFFLINE: | ||
393 | bfa_log(logmod, BFA_AEN_ITNIM_OFFLINE, rpwwn_ptr, lpwwn_ptr); | ||
394 | break; | ||
395 | case BFA_ITNIM_AEN_DISCONNECT: | ||
396 | bfa_log(logmod, BFA_AEN_ITNIM_DISCONNECT, rpwwn_ptr, lpwwn_ptr); | ||
397 | break; | ||
398 | default: | ||
399 | break; | ||
400 | } | ||
401 | 390 | ||
402 | aen_data.itnim.vf_id = rport->port->fabric->vf_id; | 391 | aen_data.itnim.vf_id = rport->port->fabric->vf_id; |
403 | aen_data.itnim.ppwwn = | 392 | aen_data.itnim.ppwwn = |
@@ -689,7 +678,6 @@ bfa_cb_itnim_tov_begin(void *cb_arg) | |||
689 | struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg; | 678 | struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg; |
690 | 679 | ||
691 | bfa_trc(itnim->fcs, itnim->rport->pwwn); | 680 | bfa_trc(itnim->fcs, itnim->rport->pwwn); |
692 | bfa_fcb_itnim_tov_begin(itnim->itnim_drv); | ||
693 | } | 681 | } |
694 | 682 | ||
695 | /** | 683 | /** |
@@ -822,22 +810,3 @@ void | |||
822 | bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim) | 810 | bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim) |
823 | { | 811 | { |
824 | } | 812 | } |
825 | |||
826 | /** | ||
827 | * Module initialization | ||
828 | */ | ||
829 | void | ||
830 | bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs) | ||
831 | { | ||
832 | } | ||
833 | |||
834 | /** | ||
835 | * Module cleanup | ||
836 | */ | ||
837 | void | ||
838 | bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs) | ||
839 | { | ||
840 | bfa_fcs_modexit_comp(fcs); | ||
841 | } | ||
842 | |||
843 | |||
diff --git a/drivers/scsi/bfa/fcs_fabric.h b/drivers/scsi/bfa/fcs_fabric.h index eee960820f86..244c3f00c50c 100644 --- a/drivers/scsi/bfa/fcs_fabric.h +++ b/drivers/scsi/bfa/fcs_fabric.h | |||
@@ -29,6 +29,7 @@ | |||
29 | /* | 29 | /* |
30 | * fcs friend functions: only between fcs modules | 30 | * fcs friend functions: only between fcs modules |
31 | */ | 31 | */ |
32 | void bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs); | ||
32 | void bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs); | 33 | void bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs); |
33 | void bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs); | 34 | void bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs); |
34 | void bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs); | 35 | void bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs); |
@@ -46,6 +47,7 @@ void bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, | |||
46 | struct fchs_s *fchs, u16 len); | 47 | struct fchs_s *fchs, u16 len); |
47 | u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric); | 48 | u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric); |
48 | bfa_boolean_t bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric); | 49 | bfa_boolean_t bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric); |
50 | bfa_boolean_t bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric); | ||
49 | enum bfa_pport_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric); | 51 | enum bfa_pport_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric); |
50 | void bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric); | 52 | void bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric); |
51 | void bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric); | 53 | void bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric); |
diff --git a/drivers/scsi/bfa/fcs_fcpim.h b/drivers/scsi/bfa/fcs_fcpim.h index 61e9e2687de3..11e6e7bce9f6 100644 --- a/drivers/scsi/bfa/fcs_fcpim.h +++ b/drivers/scsi/bfa/fcs_fcpim.h | |||
@@ -34,11 +34,6 @@ void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim); | |||
34 | void bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim); | 34 | void bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim); |
35 | void bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim); | 35 | void bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim); |
36 | 36 | ||
37 | /* | ||
38 | * Modudle init/cleanup routines. | ||
39 | */ | ||
40 | void bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs); | ||
41 | void bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs); | ||
42 | void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs, | 37 | void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs, |
43 | u16 len); | 38 | u16 len); |
44 | #endif /* __FCS_FCPIM_H__ */ | 39 | #endif /* __FCS_FCPIM_H__ */ |
diff --git a/drivers/scsi/bfa/fcs_lport.h b/drivers/scsi/bfa/fcs_lport.h index ae744ba35671..a6508c8ab184 100644 --- a/drivers/scsi/bfa/fcs_lport.h +++ b/drivers/scsi/bfa/fcs_lport.h | |||
@@ -84,9 +84,10 @@ void bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs, | |||
84 | * Following routines will be called by Fabric to indicate port | 84 | * Following routines will be called by Fabric to indicate port |
85 | * online/offline to vport. | 85 | * online/offline to vport. |
86 | */ | 86 | */ |
87 | void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, | 87 | void bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, |
88 | u16 vf_id, struct bfa_port_cfg_s *port_cfg, | 88 | uint16_t vf_id, struct bfa_fcs_vport_s *vport); |
89 | struct bfa_fcs_vport_s *vport); | 89 | void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, |
90 | struct bfa_port_cfg_s *port_cfg); | ||
90 | void bfa_fcs_port_online(struct bfa_fcs_port_s *port); | 91 | void bfa_fcs_port_online(struct bfa_fcs_port_s *port); |
91 | void bfa_fcs_port_offline(struct bfa_fcs_port_s *port); | 92 | void bfa_fcs_port_offline(struct bfa_fcs_port_s *port); |
92 | void bfa_fcs_port_delete(struct bfa_fcs_port_s *port); | 93 | void bfa_fcs_port_delete(struct bfa_fcs_port_s *port); |
diff --git a/drivers/scsi/bfa/fcs_port.h b/drivers/scsi/bfa/fcs_port.h index abb65191dd27..408c06a7d164 100644 --- a/drivers/scsi/bfa/fcs_port.h +++ b/drivers/scsi/bfa/fcs_port.h | |||
@@ -26,7 +26,6 @@ | |||
26 | /* | 26 | /* |
27 | * fcs friend functions: only between fcs modules | 27 | * fcs friend functions: only between fcs modules |
28 | */ | 28 | */ |
29 | void bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs); | 29 | void bfa_fcs_pport_attach(struct bfa_fcs_s *fcs); |
30 | void bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs); | ||
31 | 30 | ||
32 | #endif /* __FCS_PPORT_H__ */ | 31 | #endif /* __FCS_PPORT_H__ */ |
diff --git a/drivers/scsi/bfa/fcs_rport.h b/drivers/scsi/bfa/fcs_rport.h index f601e9d74236..9c8d1d292380 100644 --- a/drivers/scsi/bfa/fcs_rport.h +++ b/drivers/scsi/bfa/fcs_rport.h | |||
@@ -24,9 +24,6 @@ | |||
24 | 24 | ||
25 | #include <fcs/bfa_fcs_rport.h> | 25 | #include <fcs/bfa_fcs_rport.h> |
26 | 26 | ||
27 | void bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs); | ||
28 | void bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs); | ||
29 | |||
30 | void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs, | 27 | void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs, |
31 | u16 len); | 28 | u16 len); |
32 | void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport); | 29 | void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport); |
diff --git a/drivers/scsi/bfa/fcs_uf.h b/drivers/scsi/bfa/fcs_uf.h index 96f1bdcb31ed..f591072214fe 100644 --- a/drivers/scsi/bfa/fcs_uf.h +++ b/drivers/scsi/bfa/fcs_uf.h | |||
@@ -26,7 +26,6 @@ | |||
26 | /* | 26 | /* |
27 | * fcs friend functions: only between fcs modules | 27 | * fcs friend functions: only between fcs modules |
28 | */ | 28 | */ |
29 | void bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs); | 29 | void bfa_fcs_uf_attach(struct bfa_fcs_s *fcs); |
30 | void bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs); | ||
31 | 30 | ||
32 | #endif /* __FCS_UF_H__ */ | 31 | #endif /* __FCS_UF_H__ */ |
diff --git a/drivers/scsi/bfa/fcs_vport.h b/drivers/scsi/bfa/fcs_vport.h index 9e80b6a97b7f..13c32ebf946c 100644 --- a/drivers/scsi/bfa/fcs_vport.h +++ b/drivers/scsi/bfa/fcs_vport.h | |||
@@ -22,18 +22,10 @@ | |||
22 | #include <fcs/bfa_fcs_vport.h> | 22 | #include <fcs/bfa_fcs_vport.h> |
23 | #include <defs/bfa_defs_pci.h> | 23 | #include <defs/bfa_defs_pci.h> |
24 | 24 | ||
25 | /* | ||
26 | * Modudle init/cleanup routines. | ||
27 | */ | ||
28 | |||
29 | void bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs); | ||
30 | void bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs); | ||
31 | |||
32 | void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport); | 25 | void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport); |
33 | void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport); | 26 | void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport); |
34 | void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport); | 27 | void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport); |
35 | void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport); | 28 | void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport); |
36 | u32 bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs); | ||
37 | 29 | ||
38 | #endif /* __FCS_VPORT_H__ */ | 30 | #endif /* __FCS_VPORT_H__ */ |
39 | 31 | ||
diff --git a/drivers/scsi/bfa/fdmi.c b/drivers/scsi/bfa/fdmi.c index df2a1e54e16b..8f17076d1a87 100644 --- a/drivers/scsi/bfa/fdmi.c +++ b/drivers/scsi/bfa/fdmi.c | |||
@@ -116,6 +116,9 @@ static void bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi, | |||
116 | enum port_fdmi_event event); | 116 | enum port_fdmi_event event); |
117 | static void bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi, | 117 | static void bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi, |
118 | enum port_fdmi_event event); | 118 | enum port_fdmi_event event); |
119 | static void bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi, | ||
120 | enum port_fdmi_event event); | ||
121 | |||
119 | /** | 122 | /** |
120 | * Start in offline state - awaiting MS to send start. | 123 | * Start in offline state - awaiting MS to send start. |
121 | */ | 124 | */ |
@@ -155,7 +158,7 @@ bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi, | |||
155 | break; | 158 | break; |
156 | 159 | ||
157 | default: | 160 | default: |
158 | bfa_assert(0); | 161 | bfa_sm_fault(port->fcs, event); |
159 | } | 162 | } |
160 | } | 163 | } |
161 | 164 | ||
@@ -180,7 +183,7 @@ bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi, | |||
180 | break; | 183 | break; |
181 | 184 | ||
182 | default: | 185 | default: |
183 | bfa_assert(0); | 186 | bfa_sm_fault(port->fcs, event); |
184 | } | 187 | } |
185 | } | 188 | } |
186 | 189 | ||
@@ -227,7 +230,7 @@ bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi, | |||
227 | break; | 230 | break; |
228 | 231 | ||
229 | default: | 232 | default: |
230 | bfa_assert(0); | 233 | bfa_sm_fault(port->fcs, event); |
231 | } | 234 | } |
232 | } | 235 | } |
233 | 236 | ||
@@ -255,7 +258,7 @@ bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi, | |||
255 | break; | 258 | break; |
256 | 259 | ||
257 | default: | 260 | default: |
258 | bfa_assert(0); | 261 | bfa_sm_fault(port->fcs, event); |
259 | } | 262 | } |
260 | } | 263 | } |
261 | 264 | ||
@@ -283,7 +286,7 @@ bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi, | |||
283 | break; | 286 | break; |
284 | 287 | ||
285 | default: | 288 | default: |
286 | bfa_assert(0); | 289 | bfa_sm_fault(port->fcs, event); |
287 | } | 290 | } |
288 | } | 291 | } |
289 | 292 | ||
@@ -328,7 +331,7 @@ bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi, | |||
328 | break; | 331 | break; |
329 | 332 | ||
330 | default: | 333 | default: |
331 | bfa_assert(0); | 334 | bfa_sm_fault(port->fcs, event); |
332 | } | 335 | } |
333 | } | 336 | } |
334 | 337 | ||
@@ -356,7 +359,7 @@ bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi, | |||
356 | break; | 359 | break; |
357 | 360 | ||
358 | default: | 361 | default: |
359 | bfa_assert(0); | 362 | bfa_sm_fault(port->fcs, event); |
360 | } | 363 | } |
361 | } | 364 | } |
362 | 365 | ||
@@ -384,7 +387,7 @@ bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi, | |||
384 | break; | 387 | break; |
385 | 388 | ||
386 | default: | 389 | default: |
387 | bfa_assert(0); | 390 | bfa_sm_fault(port->fcs, event); |
388 | } | 391 | } |
389 | } | 392 | } |
390 | 393 | ||
@@ -428,7 +431,7 @@ bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi, | |||
428 | break; | 431 | break; |
429 | 432 | ||
430 | default: | 433 | default: |
431 | bfa_assert(0); | 434 | bfa_sm_fault(port->fcs, event); |
432 | } | 435 | } |
433 | } | 436 | } |
434 | 437 | ||
@@ -456,7 +459,7 @@ bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi, | |||
456 | break; | 459 | break; |
457 | 460 | ||
458 | default: | 461 | default: |
459 | bfa_assert(0); | 462 | bfa_sm_fault(port->fcs, event); |
460 | } | 463 | } |
461 | } | 464 | } |
462 | 465 | ||
@@ -475,10 +478,24 @@ bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi, | |||
475 | break; | 478 | break; |
476 | 479 | ||
477 | default: | 480 | default: |
478 | bfa_assert(0); | 481 | bfa_sm_fault(port->fcs, event); |
479 | } | 482 | } |
480 | } | 483 | } |
481 | 484 | ||
485 | /** | ||
486 | * FDMI is disabled state. | ||
487 | */ | ||
488 | static void | ||
489 | bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi, | ||
490 | enum port_fdmi_event event) | ||
491 | { | ||
492 | struct bfa_fcs_port_s *port = fdmi->ms->port; | ||
493 | |||
494 | bfa_trc(port->fcs, port->port_cfg.pwwn); | ||
495 | bfa_trc(port->fcs, event); | ||
496 | |||
497 | /* No op State. It can only be enabled at Driver Init. */ | ||
498 | } | ||
482 | 499 | ||
483 | /** | 500 | /** |
484 | * RHBA : Register HBA Attributes. | 501 | * RHBA : Register HBA Attributes. |
@@ -1097,36 +1114,23 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi, | |||
1097 | { | 1114 | { |
1098 | struct bfa_fcs_port_s *port = fdmi->ms->port; | 1115 | struct bfa_fcs_port_s *port = fdmi->ms->port; |
1099 | struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; | 1116 | struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; |
1100 | struct bfa_adapter_attr_s adapter_attr; | ||
1101 | 1117 | ||
1102 | bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); | 1118 | bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); |
1103 | bfa_os_memset(&adapter_attr, 0, sizeof(struct bfa_adapter_attr_s)); | ||
1104 | |||
1105 | bfa_ioc_get_adapter_attr(&port->fcs->bfa->ioc, &adapter_attr); | ||
1106 | |||
1107 | strncpy(hba_attr->manufacturer, adapter_attr.manufacturer, | ||
1108 | sizeof(adapter_attr.manufacturer)); | ||
1109 | |||
1110 | strncpy(hba_attr->serial_num, adapter_attr.serial_num, | ||
1111 | sizeof(adapter_attr.serial_num)); | ||
1112 | 1119 | ||
1113 | strncpy(hba_attr->model, adapter_attr.model, sizeof(hba_attr->model)); | 1120 | bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc, |
1114 | 1121 | hba_attr->manufacturer); | |
1115 | strncpy(hba_attr->model_desc, adapter_attr.model_descr, | 1122 | bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc, |
1116 | sizeof(hba_attr->model_desc)); | 1123 | hba_attr->serial_num); |
1117 | 1124 | bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model); | |
1118 | strncpy(hba_attr->hw_version, adapter_attr.hw_ver, | 1125 | bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model_desc); |
1119 | sizeof(hba_attr->hw_version)); | 1126 | bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, hba_attr->hw_version); |
1127 | bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc, | ||
1128 | hba_attr->option_rom_ver); | ||
1129 | bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, hba_attr->fw_version); | ||
1120 | 1130 | ||
1121 | strncpy(hba_attr->driver_version, (char *)driver_info->version, | 1131 | strncpy(hba_attr->driver_version, (char *)driver_info->version, |
1122 | sizeof(hba_attr->driver_version)); | 1132 | sizeof(hba_attr->driver_version)); |
1123 | 1133 | ||
1124 | strncpy(hba_attr->option_rom_ver, adapter_attr.optrom_ver, | ||
1125 | sizeof(hba_attr->option_rom_ver)); | ||
1126 | |||
1127 | strncpy(hba_attr->fw_version, adapter_attr.fw_ver, | ||
1128 | sizeof(hba_attr->fw_version)); | ||
1129 | |||
1130 | strncpy(hba_attr->os_name, driver_info->host_os_name, | 1134 | strncpy(hba_attr->os_name, driver_info->host_os_name, |
1131 | sizeof(hba_attr->os_name)); | 1135 | sizeof(hba_attr->os_name)); |
1132 | 1136 | ||
@@ -1158,7 +1162,7 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi, | |||
1158 | /* | 1162 | /* |
1159 | * get pport attributes from hal | 1163 | * get pport attributes from hal |
1160 | */ | 1164 | */ |
1161 | bfa_pport_get_attr(port->fcs->bfa, &pport_attr); | 1165 | bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); |
1162 | 1166 | ||
1163 | /* | 1167 | /* |
1164 | * get FC4 type Bitmask | 1168 | * get FC4 type Bitmask |
@@ -1201,7 +1205,10 @@ bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms) | |||
1201 | struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi; | 1205 | struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi; |
1202 | 1206 | ||
1203 | fdmi->ms = ms; | 1207 | fdmi->ms = ms; |
1204 | bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); | 1208 | if (ms->port->fcs->fdmi_enabled) |
1209 | bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); | ||
1210 | else | ||
1211 | bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_disabled); | ||
1205 | } | 1212 | } |
1206 | 1213 | ||
1207 | void | 1214 | void |
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen.h b/drivers/scsi/bfa/include/aen/bfa_aen.h index d9cbc2a783d4..6abbab005db6 100644 --- a/drivers/scsi/bfa/include/aen/bfa_aen.h +++ b/drivers/scsi/bfa/include/aen/bfa_aen.h | |||
@@ -18,21 +18,24 @@ | |||
18 | #define __BFA_AEN_H__ | 18 | #define __BFA_AEN_H__ |
19 | 19 | ||
20 | #include "defs/bfa_defs_aen.h" | 20 | #include "defs/bfa_defs_aen.h" |
21 | #include "defs/bfa_defs_status.h" | ||
22 | #include "cs/bfa_debug.h" | ||
21 | 23 | ||
22 | #define BFA_AEN_MAX_ENTRY 512 | 24 | #define BFA_AEN_MAX_ENTRY 512 |
23 | 25 | ||
24 | extern s32 bfa_aen_max_cfg_entry; | 26 | extern int bfa_aen_max_cfg_entry; |
25 | struct bfa_aen_s { | 27 | struct bfa_aen_s { |
26 | void *bfad; | 28 | void *bfad; |
27 | s32 max_entry; | 29 | int max_entry; |
28 | s32 write_index; | 30 | int write_index; |
29 | s32 read_index; | 31 | int read_index; |
30 | u32 bfad_num; | 32 | int bfad_num; |
31 | u32 seq_num; | 33 | int seq_num; |
32 | void (*aen_cb_notify)(void *bfad); | 34 | void (*aen_cb_notify)(void *bfad); |
33 | void (*gettimeofday)(struct bfa_timeval_s *tv); | 35 | void (*gettimeofday)(struct bfa_timeval_s *tv); |
34 | struct bfa_trc_mod_s *trcmod; | 36 | struct bfa_trc_mod_s *trcmod; |
35 | struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */ | 37 | int app_ri[BFA_AEN_MAX_APP]; /* For multiclient support */ |
38 | struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */ | ||
36 | }; | 39 | }; |
37 | 40 | ||
38 | 41 | ||
@@ -45,48 +48,49 @@ bfa_aen_set_max_cfg_entry(int max_entry) | |||
45 | bfa_aen_max_cfg_entry = max_entry; | 48 | bfa_aen_max_cfg_entry = max_entry; |
46 | } | 49 | } |
47 | 50 | ||
48 | static inline s32 | 51 | static inline int |
49 | bfa_aen_get_max_cfg_entry(void) | 52 | bfa_aen_get_max_cfg_entry(void) |
50 | { | 53 | { |
51 | return bfa_aen_max_cfg_entry; | 54 | return bfa_aen_max_cfg_entry; |
52 | } | 55 | } |
53 | 56 | ||
54 | static inline s32 | 57 | static inline int |
55 | bfa_aen_get_meminfo(void) | 58 | bfa_aen_get_meminfo(void) |
56 | { | 59 | { |
57 | return sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry(); | 60 | return sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry(); |
58 | } | 61 | } |
59 | 62 | ||
60 | static inline s32 | 63 | static inline int |
61 | bfa_aen_get_wi(struct bfa_aen_s *aen) | 64 | bfa_aen_get_wi(struct bfa_aen_s *aen) |
62 | { | 65 | { |
63 | return aen->write_index; | 66 | return aen->write_index; |
64 | } | 67 | } |
65 | 68 | ||
66 | static inline s32 | 69 | static inline int |
67 | bfa_aen_get_ri(struct bfa_aen_s *aen) | 70 | bfa_aen_get_ri(struct bfa_aen_s *aen) |
68 | { | 71 | { |
69 | return aen->read_index; | 72 | return aen->read_index; |
70 | } | 73 | } |
71 | 74 | ||
72 | static inline s32 | 75 | static inline int |
73 | bfa_aen_fetch_count(struct bfa_aen_s *aen, s32 read_index) | 76 | bfa_aen_fetch_count(struct bfa_aen_s *aen, enum bfa_aen_app app_id) |
74 | { | 77 | { |
75 | return ((aen->write_index + aen->max_entry) - read_index) | 78 | bfa_assert((app_id < BFA_AEN_MAX_APP) && (app_id >= bfa_aen_app_bcu)); |
79 | return ((aen->write_index + aen->max_entry) - aen->app_ri[app_id]) | ||
76 | % aen->max_entry; | 80 | % aen->max_entry; |
77 | } | 81 | } |
78 | 82 | ||
79 | s32 bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod, | 83 | int bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod, |
80 | void *bfad, u32 inst_id, void (*aen_cb_notify)(void *), | 84 | void *bfad, int bfad_num, void (*aen_cb_notify)(void *), |
81 | void (*gettimeofday)(struct bfa_timeval_s *)); | 85 | void (*gettimeofday)(struct bfa_timeval_s *)); |
82 | 86 | ||
83 | s32 bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category, | 87 | void bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category, |
84 | int aen_type, union bfa_aen_data_u *aen_data); | 88 | int aen_type, union bfa_aen_data_u *aen_data); |
85 | 89 | ||
86 | s32 bfa_aen_fetch(struct bfa_aen_s *aen, struct bfa_aen_entry_s *aen_entry, | 90 | bfa_status_t bfa_aen_fetch(struct bfa_aen_s *aen, |
87 | s32 entry_space, s32 rii, s32 *ri_arr, | 91 | struct bfa_aen_entry_s *aen_entry, |
88 | s32 ri_arr_cnt); | 92 | int entry_req, enum bfa_aen_app app_id, int *entry_ret); |
89 | 93 | ||
90 | s32 bfa_aen_get_inst(struct bfa_aen_s *aen); | 94 | int bfa_aen_get_inst(struct bfa_aen_s *aen); |
91 | 95 | ||
92 | #endif /* __BFA_AEN_H__ */ | 96 | #endif /* __BFA_AEN_H__ */ |
diff --git a/drivers/scsi/bfa/include/bfa.h b/drivers/scsi/bfa/include/bfa.h index d4bc0d9fa42c..1f5966cfbd16 100644 --- a/drivers/scsi/bfa/include/bfa.h +++ b/drivers/scsi/bfa/include/bfa.h | |||
@@ -106,6 +106,26 @@ struct bfa_sge_s { | |||
106 | bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats) | 106 | bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats) |
107 | #define bfa_ioc_clear_stats(__bfa) \ | 107 | #define bfa_ioc_clear_stats(__bfa) \ |
108 | bfa_ioc_clr_stats(&(__bfa)->ioc) | 108 | bfa_ioc_clr_stats(&(__bfa)->ioc) |
109 | #define bfa_get_nports(__bfa) \ | ||
110 | bfa_ioc_get_nports(&(__bfa)->ioc) | ||
111 | #define bfa_get_adapter_manufacturer(__bfa, __manufacturer) \ | ||
112 | bfa_ioc_get_adapter_manufacturer(&(__bfa)->ioc, __manufacturer) | ||
113 | #define bfa_get_adapter_model(__bfa, __model) \ | ||
114 | bfa_ioc_get_adapter_model(&(__bfa)->ioc, __model) | ||
115 | #define bfa_get_adapter_serial_num(__bfa, __serial_num) \ | ||
116 | bfa_ioc_get_adapter_serial_num(&(__bfa)->ioc, __serial_num) | ||
117 | #define bfa_get_adapter_fw_ver(__bfa, __fw_ver) \ | ||
118 | bfa_ioc_get_adapter_fw_ver(&(__bfa)->ioc, __fw_ver) | ||
119 | #define bfa_get_adapter_optrom_ver(__bfa, __optrom_ver) \ | ||
120 | bfa_ioc_get_adapter_optrom_ver(&(__bfa)->ioc, __optrom_ver) | ||
121 | #define bfa_get_pci_chip_rev(__bfa, __chip_rev) \ | ||
122 | bfa_ioc_get_pci_chip_rev(&(__bfa)->ioc, __chip_rev) | ||
123 | #define bfa_get_ioc_state(__bfa) \ | ||
124 | bfa_ioc_get_state(&(__bfa)->ioc) | ||
125 | #define bfa_get_type(__bfa) \ | ||
126 | bfa_ioc_get_type(&(__bfa)->ioc) | ||
127 | #define bfa_get_mac(__bfa) \ | ||
128 | bfa_ioc_get_mac(&(__bfa)->ioc) | ||
109 | 129 | ||
110 | /* | 130 | /* |
111 | * bfa API functions | 131 | * bfa API functions |
@@ -161,6 +181,7 @@ bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa, | |||
161 | void bfa_iocfc_enable(struct bfa_s *bfa); | 181 | void bfa_iocfc_enable(struct bfa_s *bfa); |
162 | void bfa_iocfc_disable(struct bfa_s *bfa); | 182 | void bfa_iocfc_disable(struct bfa_s *bfa); |
163 | void bfa_ioc_auto_recover(bfa_boolean_t auto_recover); | 183 | void bfa_ioc_auto_recover(bfa_boolean_t auto_recover); |
184 | void bfa_chip_reset(struct bfa_s *bfa); | ||
164 | void bfa_cb_ioc_disable(void *bfad); | 185 | void bfa_cb_ioc_disable(void *bfad); |
165 | void bfa_timer_tick(struct bfa_s *bfa); | 186 | void bfa_timer_tick(struct bfa_s *bfa); |
166 | #define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \ | 187 | #define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \ |
@@ -171,6 +192,7 @@ void bfa_timer_tick(struct bfa_s *bfa); | |||
171 | */ | 192 | */ |
172 | bfa_status_t bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen); | 193 | bfa_status_t bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen); |
173 | bfa_status_t bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen); | 194 | bfa_status_t bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen); |
195 | void bfa_debug_fwsave_clear(struct bfa_s *bfa); | ||
174 | 196 | ||
175 | #include "bfa_priv.h" | 197 | #include "bfa_priv.h" |
176 | 198 | ||
diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h index 268d956bad89..1349b99a3c6d 100644 --- a/drivers/scsi/bfa/include/bfa_svc.h +++ b/drivers/scsi/bfa/include/bfa_svc.h | |||
@@ -26,6 +26,7 @@ struct bfa_fcxp_s; | |||
26 | #include <defs/bfa_defs_pport.h> | 26 | #include <defs/bfa_defs_pport.h> |
27 | #include <defs/bfa_defs_rport.h> | 27 | #include <defs/bfa_defs_rport.h> |
28 | #include <defs/bfa_defs_qos.h> | 28 | #include <defs/bfa_defs_qos.h> |
29 | #include <defs/bfa_defs_fcport.h> | ||
29 | #include <cs/bfa_sm.h> | 30 | #include <cs/bfa_sm.h> |
30 | #include <bfa.h> | 31 | #include <bfa.h> |
31 | 32 | ||
@@ -35,7 +36,7 @@ struct bfa_fcxp_s; | |||
35 | struct bfa_rport_info_s { | 36 | struct bfa_rport_info_s { |
36 | u16 max_frmsz; /* max rcv pdu size */ | 37 | u16 max_frmsz; /* max rcv pdu size */ |
37 | u32 pid:24, /* remote port ID */ | 38 | u32 pid:24, /* remote port ID */ |
38 | lp_tag:8; | 39 | lp_tag:8; /* tag */ |
39 | u32 local_pid:24, /* local port ID */ | 40 | u32 local_pid:24, /* local port ID */ |
40 | cisc:8; /* CIRO supported */ | 41 | cisc:8; /* CIRO supported */ |
41 | u8 fc_class; /* supported FC classes. enum fc_cos */ | 42 | u8 fc_class; /* supported FC classes. enum fc_cos */ |
@@ -54,7 +55,7 @@ struct bfa_rport_s { | |||
54 | void *rport_drv; /* fcs/driver rport object */ | 55 | void *rport_drv; /* fcs/driver rport object */ |
55 | u16 fw_handle; /* firmware rport handle */ | 56 | u16 fw_handle; /* firmware rport handle */ |
56 | u16 rport_tag; /* BFA rport tag */ | 57 | u16 rport_tag; /* BFA rport tag */ |
57 | struct bfa_rport_info_s rport_info; /* rport info from *fcs/driver */ | 58 | struct bfa_rport_info_s rport_info; /* rport info from fcs/driver */ |
58 | struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ | 59 | struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ |
59 | struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */ | 60 | struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */ |
60 | struct bfa_rport_hal_stats_s stats; /* BFA rport statistics */ | 61 | struct bfa_rport_hal_stats_s stats; /* BFA rport statistics */ |
@@ -101,7 +102,7 @@ struct bfa_uf_buf_s { | |||
101 | struct bfa_uf_s { | 102 | struct bfa_uf_s { |
102 | struct list_head qe; /* queue element */ | 103 | struct list_head qe; /* queue element */ |
103 | struct bfa_s *bfa; /* bfa instance */ | 104 | struct bfa_s *bfa; /* bfa instance */ |
104 | u16 uf_tag; /* identifying tag f/w messages */ | 105 | u16 uf_tag; /* identifying tag fw msgs */ |
105 | u16 vf_id; | 106 | u16 vf_id; |
106 | u16 src_rport_handle; | 107 | u16 src_rport_handle; |
107 | u16 rsvd; | 108 | u16 rsvd; |
@@ -127,7 +128,7 @@ struct bfa_lps_s { | |||
127 | u8 reqq; /* lport request queue */ | 128 | u8 reqq; /* lport request queue */ |
128 | u8 alpa; /* ALPA for loop topologies */ | 129 | u8 alpa; /* ALPA for loop topologies */ |
129 | u32 lp_pid; /* lport port ID */ | 130 | u32 lp_pid; /* lport port ID */ |
130 | bfa_boolean_t fdisc; /* send FDISC instead of FLOGI*/ | 131 | bfa_boolean_t fdisc; /* send FDISC instead of FLOGI */ |
131 | bfa_boolean_t auth_en; /* enable authentication */ | 132 | bfa_boolean_t auth_en; /* enable authentication */ |
132 | bfa_boolean_t auth_req; /* authentication required */ | 133 | bfa_boolean_t auth_req; /* authentication required */ |
133 | bfa_boolean_t npiv_en; /* NPIV is allowed by peer */ | 134 | bfa_boolean_t npiv_en; /* NPIV is allowed by peer */ |
@@ -151,60 +152,69 @@ struct bfa_lps_s { | |||
151 | bfa_eproto_status_t ext_status; | 152 | bfa_eproto_status_t ext_status; |
152 | }; | 153 | }; |
153 | 154 | ||
155 | #define BFA_FCPORT(_bfa) (&((_bfa)->modules.port)) | ||
156 | |||
154 | /* | 157 | /* |
155 | * bfa pport API functions | 158 | * bfa pport API functions |
156 | */ | 159 | */ |
157 | bfa_status_t bfa_pport_enable(struct bfa_s *bfa); | 160 | bfa_status_t bfa_fcport_enable(struct bfa_s *bfa); |
158 | bfa_status_t bfa_pport_disable(struct bfa_s *bfa); | 161 | bfa_status_t bfa_fcport_disable(struct bfa_s *bfa); |
159 | bfa_status_t bfa_pport_cfg_speed(struct bfa_s *bfa, | 162 | bfa_status_t bfa_fcport_cfg_speed(struct bfa_s *bfa, |
160 | enum bfa_pport_speed speed); | 163 | enum bfa_pport_speed speed); |
161 | enum bfa_pport_speed bfa_pport_get_speed(struct bfa_s *bfa); | 164 | enum bfa_pport_speed bfa_fcport_get_speed(struct bfa_s *bfa); |
162 | bfa_status_t bfa_pport_cfg_topology(struct bfa_s *bfa, | 165 | bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa, |
163 | enum bfa_pport_topology topo); | 166 | enum bfa_pport_topology topo); |
164 | enum bfa_pport_topology bfa_pport_get_topology(struct bfa_s *bfa); | 167 | enum bfa_pport_topology bfa_fcport_get_topology(struct bfa_s *bfa); |
165 | bfa_status_t bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa); | 168 | bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa); |
166 | bfa_boolean_t bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa); | 169 | bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa); |
167 | u8 bfa_pport_get_myalpa(struct bfa_s *bfa); | 170 | u8 bfa_fcport_get_myalpa(struct bfa_s *bfa); |
168 | bfa_status_t bfa_pport_clr_hardalpa(struct bfa_s *bfa); | 171 | bfa_status_t bfa_fcport_clr_hardalpa(struct bfa_s *bfa); |
169 | bfa_status_t bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize); | 172 | bfa_status_t bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize); |
170 | u16 bfa_pport_get_maxfrsize(struct bfa_s *bfa); | 173 | u16 bfa_fcport_get_maxfrsize(struct bfa_s *bfa); |
171 | u32 bfa_pport_mypid(struct bfa_s *bfa); | 174 | u32 bfa_fcport_mypid(struct bfa_s *bfa); |
172 | u8 bfa_pport_get_rx_bbcredit(struct bfa_s *bfa); | 175 | u8 bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa); |
173 | bfa_status_t bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap); | 176 | bfa_status_t bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap); |
174 | bfa_status_t bfa_pport_trunk_disable(struct bfa_s *bfa); | 177 | bfa_status_t bfa_fcport_trunk_disable(struct bfa_s *bfa); |
175 | bfa_boolean_t bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap); | 178 | bfa_boolean_t bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap); |
176 | void bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr); | 179 | void bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr); |
177 | wwn_t bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node); | 180 | wwn_t bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node); |
178 | bfa_status_t bfa_pport_get_stats(struct bfa_s *bfa, | 181 | void bfa_fcport_event_register(struct bfa_s *bfa, |
179 | union bfa_pport_stats_u *stats, | ||
180 | bfa_cb_pport_t cbfn, void *cbarg); | ||
181 | bfa_status_t bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, | ||
182 | void *cbarg); | ||
183 | void bfa_pport_event_register(struct bfa_s *bfa, | ||
184 | void (*event_cbfn) (void *cbarg, | 182 | void (*event_cbfn) (void *cbarg, |
185 | bfa_pport_event_t event), void *event_cbarg); | 183 | bfa_pport_event_t event), void *event_cbarg); |
186 | bfa_boolean_t bfa_pport_is_disabled(struct bfa_s *bfa); | 184 | bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa); |
187 | void bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off); | 185 | void bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off); |
188 | void bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off); | 186 | void bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off); |
189 | bfa_status_t bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, | 187 | bfa_status_t bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, |
190 | enum bfa_pport_speed speed); | 188 | enum bfa_pport_speed speed); |
191 | enum bfa_pport_speed bfa_pport_get_ratelim_speed(struct bfa_s *bfa); | 189 | enum bfa_pport_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); |
192 | 190 | ||
193 | void bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit); | 191 | void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit); |
194 | void bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status); | 192 | void bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status); |
195 | void bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, | 193 | void bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, |
196 | bfa_boolean_t link_e2e_beacon); | 194 | bfa_boolean_t link_e2e_beacon); |
197 | void bfa_cb_pport_event(void *cbarg, bfa_pport_event_t event); | 195 | void bfa_cb_pport_event(void *cbarg, bfa_pport_event_t event); |
198 | void bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr); | 196 | void bfa_fcport_qos_get_attr(struct bfa_s *bfa, |
199 | void bfa_pport_qos_get_vc_attr(struct bfa_s *bfa, | 197 | struct bfa_qos_attr_s *qos_attr); |
198 | void bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa, | ||
200 | struct bfa_qos_vc_attr_s *qos_vc_attr); | 199 | struct bfa_qos_vc_attr_s *qos_vc_attr); |
201 | bfa_status_t bfa_pport_get_qos_stats(struct bfa_s *bfa, | 200 | bfa_status_t bfa_fcport_get_qos_stats(struct bfa_s *bfa, |
202 | union bfa_pport_stats_u *stats, | 201 | union bfa_fcport_stats_u *stats, |
203 | bfa_cb_pport_t cbfn, void *cbarg); | 202 | bfa_cb_pport_t cbfn, void *cbarg); |
204 | bfa_status_t bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, | 203 | bfa_status_t bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, |
205 | void *cbarg); | 204 | void *cbarg); |
206 | bfa_boolean_t bfa_pport_is_ratelim(struct bfa_s *bfa); | 205 | bfa_status_t bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, |
207 | bfa_boolean_t bfa_pport_is_linkup(struct bfa_s *bfa); | 206 | union bfa_fcport_stats_u *stats, |
207 | bfa_cb_pport_t cbfn, void *cbarg); | ||
208 | bfa_status_t bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, | ||
209 | void *cbarg); | ||
210 | |||
211 | bfa_boolean_t bfa_fcport_is_ratelim(struct bfa_s *bfa); | ||
212 | bfa_boolean_t bfa_fcport_is_linkup(struct bfa_s *bfa); | ||
213 | bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa, | ||
214 | union bfa_fcport_stats_u *stats, | ||
215 | bfa_cb_pport_t cbfn, void *cbarg); | ||
216 | bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, | ||
217 | void *cbarg); | ||
208 | 218 | ||
209 | /* | 219 | /* |
210 | * bfa rport API functions | 220 | * bfa rport API functions |
@@ -293,6 +303,7 @@ void bfa_uf_free(struct bfa_uf_s *uf); | |||
293 | * bfa lport service api | 303 | * bfa lport service api |
294 | */ | 304 | */ |
295 | 305 | ||
306 | u32 bfa_lps_get_max_vport(struct bfa_s *bfa); | ||
296 | struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa); | 307 | struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa); |
297 | void bfa_lps_delete(struct bfa_lps_s *lps); | 308 | void bfa_lps_delete(struct bfa_lps_s *lps); |
298 | void bfa_lps_discard(struct bfa_lps_s *lps); | 309 | void bfa_lps_discard(struct bfa_lps_s *lps); |
@@ -315,10 +326,12 @@ wwn_t bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps); | |||
315 | wwn_t bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps); | 326 | wwn_t bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps); |
316 | u8 bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps); | 327 | u8 bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps); |
317 | u8 bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps); | 328 | u8 bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps); |
329 | mac_t bfa_lps_get_lp_mac(struct bfa_lps_s *lps); | ||
318 | void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status); | 330 | void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status); |
319 | void bfa_cb_lps_flogo_comp(void *bfad, void *uarg); | 331 | void bfa_cb_lps_flogo_comp(void *bfad, void *uarg); |
320 | void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status); | 332 | void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status); |
321 | void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg); | 333 | void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg); |
334 | void bfa_cb_lps_cvl_event(void *bfad, void *uarg); | ||
322 | 335 | ||
323 | #endif /* __BFA_SVC_H__ */ | 336 | #endif /* __BFA_SVC_H__ */ |
324 | 337 | ||
diff --git a/drivers/scsi/bfa/include/bfa_timer.h b/drivers/scsi/bfa/include/bfa_timer.h index e407103fa565..f71087448222 100644 --- a/drivers/scsi/bfa/include/bfa_timer.h +++ b/drivers/scsi/bfa/include/bfa_timer.h | |||
@@ -41,7 +41,7 @@ struct bfa_timer_mod_s { | |||
41 | struct list_head timer_q; | 41 | struct list_head timer_q; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #define BFA_TIMER_FREQ 500 /**< specified in millisecs */ | 44 | #define BFA_TIMER_FREQ 200 /**< specified in millisecs */ |
45 | 45 | ||
46 | void bfa_timer_beat(struct bfa_timer_mod_s *mod); | 46 | void bfa_timer_beat(struct bfa_timer_mod_s *mod); |
47 | void bfa_timer_init(struct bfa_timer_mod_s *mod); | 47 | void bfa_timer_init(struct bfa_timer_mod_s *mod); |
diff --git a/drivers/scsi/bfa/include/bfi/bfi.h b/drivers/scsi/bfa/include/bfi/bfi.h index 7042c18e542d..a550e80cabd2 100644 --- a/drivers/scsi/bfa/include/bfi/bfi.h +++ b/drivers/scsi/bfa/include/bfi/bfi.h | |||
@@ -143,8 +143,8 @@ enum bfi_mclass { | |||
143 | BFI_MC_IOC = 1, /* IO Controller (IOC) */ | 143 | BFI_MC_IOC = 1, /* IO Controller (IOC) */ |
144 | BFI_MC_DIAG = 2, /* Diagnostic Msgs */ | 144 | BFI_MC_DIAG = 2, /* Diagnostic Msgs */ |
145 | BFI_MC_FLASH = 3, /* Flash message class */ | 145 | BFI_MC_FLASH = 3, /* Flash message class */ |
146 | BFI_MC_CEE = 4, | 146 | BFI_MC_CEE = 4, /* CEE */ |
147 | BFI_MC_FC_PORT = 5, /* FC port */ | 147 | BFI_MC_FCPORT = 5, /* FC port */ |
148 | BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */ | 148 | BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */ |
149 | BFI_MC_LL = 7, /* Link Layer */ | 149 | BFI_MC_LL = 7, /* Link Layer */ |
150 | BFI_MC_UF = 8, /* Unsolicited frame receive */ | 150 | BFI_MC_UF = 8, /* Unsolicited frame receive */ |
diff --git a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h index b3bb52b565b1..a51ee61ddb19 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h +++ b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h | |||
@@ -177,7 +177,21 @@ | |||
177 | #define __PSS_LMEM_INIT_EN 0x00000100 | 177 | #define __PSS_LMEM_INIT_EN 0x00000100 |
178 | #define __PSS_LPU1_RESET 0x00000002 | 178 | #define __PSS_LPU1_RESET 0x00000002 |
179 | #define __PSS_LPU0_RESET 0x00000001 | 179 | #define __PSS_LPU0_RESET 0x00000001 |
180 | 180 | #define PSS_ERR_STATUS_REG 0x00018810 | |
181 | #define __PSS_LMEM1_CORR_ERR 0x00000800 | ||
182 | #define __PSS_LMEM0_CORR_ERR 0x00000400 | ||
183 | #define __PSS_LMEM1_UNCORR_ERR 0x00000200 | ||
184 | #define __PSS_LMEM0_UNCORR_ERR 0x00000100 | ||
185 | #define __PSS_BAL_PERR 0x00000080 | ||
186 | #define __PSS_DIP_IF_ERR 0x00000040 | ||
187 | #define __PSS_IOH_IF_ERR 0x00000020 | ||
188 | #define __PSS_TDS_IF_ERR 0x00000010 | ||
189 | #define __PSS_RDS_IF_ERR 0x00000008 | ||
190 | #define __PSS_SGM_IF_ERR 0x00000004 | ||
191 | #define __PSS_LPU1_RAM_ERR 0x00000002 | ||
192 | #define __PSS_LPU0_RAM_ERR 0x00000001 | ||
193 | #define ERR_SET_REG 0x00018818 | ||
194 | #define __PSS_ERR_STATUS_SET 0x00000fff | ||
181 | 195 | ||
182 | /* | 196 | /* |
183 | * These definitions are either in error/missing in spec. Its auto-generated | 197 | * These definitions are either in error/missing in spec. Its auto-generated |
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h index d3caa58c0a0a..57a8497105af 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h +++ b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h | |||
@@ -430,6 +430,31 @@ enum { | |||
430 | #define __PSS_LMEM_INIT_EN 0x00000100 | 430 | #define __PSS_LMEM_INIT_EN 0x00000100 |
431 | #define __PSS_LPU1_RESET 0x00000002 | 431 | #define __PSS_LPU1_RESET 0x00000002 |
432 | #define __PSS_LPU0_RESET 0x00000001 | 432 | #define __PSS_LPU0_RESET 0x00000001 |
433 | #define PSS_ERR_STATUS_REG 0x00018810 | ||
434 | #define __PSS_LPU1_TCM_READ_ERR 0x00200000 | ||
435 | #define __PSS_LPU0_TCM_READ_ERR 0x00100000 | ||
436 | #define __PSS_LMEM5_CORR_ERR 0x00080000 | ||
437 | #define __PSS_LMEM4_CORR_ERR 0x00040000 | ||
438 | #define __PSS_LMEM3_CORR_ERR 0x00020000 | ||
439 | #define __PSS_LMEM2_CORR_ERR 0x00010000 | ||
440 | #define __PSS_LMEM1_CORR_ERR 0x00008000 | ||
441 | #define __PSS_LMEM0_CORR_ERR 0x00004000 | ||
442 | #define __PSS_LMEM5_UNCORR_ERR 0x00002000 | ||
443 | #define __PSS_LMEM4_UNCORR_ERR 0x00001000 | ||
444 | #define __PSS_LMEM3_UNCORR_ERR 0x00000800 | ||
445 | #define __PSS_LMEM2_UNCORR_ERR 0x00000400 | ||
446 | #define __PSS_LMEM1_UNCORR_ERR 0x00000200 | ||
447 | #define __PSS_LMEM0_UNCORR_ERR 0x00000100 | ||
448 | #define __PSS_BAL_PERR 0x00000080 | ||
449 | #define __PSS_DIP_IF_ERR 0x00000040 | ||
450 | #define __PSS_IOH_IF_ERR 0x00000020 | ||
451 | #define __PSS_TDS_IF_ERR 0x00000010 | ||
452 | #define __PSS_RDS_IF_ERR 0x00000008 | ||
453 | #define __PSS_SGM_IF_ERR 0x00000004 | ||
454 | #define __PSS_LPU1_RAM_ERR 0x00000002 | ||
455 | #define __PSS_LPU0_RAM_ERR 0x00000001 | ||
456 | #define ERR_SET_REG 0x00018818 | ||
457 | #define __PSS_ERR_STATUS_SET 0x003fffff | ||
433 | #define HQM_QSET0_RXQ_DRBL_P0 0x00038000 | 458 | #define HQM_QSET0_RXQ_DRBL_P0 0x00038000 |
434 | #define __RXQ0_ADD_VECTORS_P 0x80000000 | 459 | #define __RXQ0_ADD_VECTORS_P 0x80000000 |
435 | #define __RXQ0_STOP_P 0x40000000 | 460 | #define __RXQ0_STOP_P 0x40000000 |
@@ -589,6 +614,7 @@ enum { | |||
589 | #define __HFN_INT_MBOX_LPU1 0x00200000U | 614 | #define __HFN_INT_MBOX_LPU1 0x00200000U |
590 | #define __HFN_INT_MBOX1_LPU0 0x00400000U | 615 | #define __HFN_INT_MBOX1_LPU0 0x00400000U |
591 | #define __HFN_INT_MBOX1_LPU1 0x00800000U | 616 | #define __HFN_INT_MBOX1_LPU1 0x00800000U |
617 | #define __HFN_INT_LL_HALT 0x01000000U | ||
592 | #define __HFN_INT_CPE_MASK 0x000000ffU | 618 | #define __HFN_INT_CPE_MASK 0x000000ffU |
593 | #define __HFN_INT_RME_MASK 0x0000ff00U | 619 | #define __HFN_INT_RME_MASK 0x0000ff00U |
594 | 620 | ||
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ioc.h b/drivers/scsi/bfa/include/bfi/bfi_ioc.h index 96ef05670659..a0158aac0024 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_ioc.h +++ b/drivers/scsi/bfa/include/bfi/bfi_ioc.h | |||
@@ -123,7 +123,7 @@ enum bfi_ioc_state { | |||
123 | BFI_IOC_DISABLING = 5, /* IOC is being disabled */ | 123 | BFI_IOC_DISABLING = 5, /* IOC is being disabled */ |
124 | BFI_IOC_DISABLED = 6, /* IOC is disabled */ | 124 | BFI_IOC_DISABLED = 6, /* IOC is disabled */ |
125 | BFI_IOC_CFG_DISABLED = 7, /* IOC is being disabled;transient */ | 125 | BFI_IOC_CFG_DISABLED = 7, /* IOC is being disabled;transient */ |
126 | BFI_IOC_HBFAIL = 8, /* IOC heart-beat failure */ | 126 | BFI_IOC_FAIL = 8, /* IOC heart-beat failure */ |
127 | BFI_IOC_MEMTEST = 9, /* IOC is doing memtest */ | 127 | BFI_IOC_MEMTEST = 9, /* IOC is doing memtest */ |
128 | }; | 128 | }; |
129 | 129 | ||
diff --git a/drivers/scsi/bfa/include/bfi/bfi_lps.h b/drivers/scsi/bfa/include/bfi/bfi_lps.h index c59d47badb4b..7ed31bbb8696 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_lps.h +++ b/drivers/scsi/bfa/include/bfi/bfi_lps.h | |||
@@ -30,6 +30,7 @@ enum bfi_lps_h2i_msgs { | |||
30 | enum bfi_lps_i2h_msgs { | 30 | enum bfi_lps_i2h_msgs { |
31 | BFI_LPS_H2I_LOGIN_RSP = BFA_I2HM(1), | 31 | BFI_LPS_H2I_LOGIN_RSP = BFA_I2HM(1), |
32 | BFI_LPS_H2I_LOGOUT_RSP = BFA_I2HM(2), | 32 | BFI_LPS_H2I_LOGOUT_RSP = BFA_I2HM(2), |
33 | BFI_LPS_H2I_CVL_EVENT = BFA_I2HM(3), | ||
33 | }; | 34 | }; |
34 | 35 | ||
35 | struct bfi_lps_login_req_s { | 36 | struct bfi_lps_login_req_s { |
@@ -77,6 +78,12 @@ struct bfi_lps_logout_rsp_s { | |||
77 | u8 rsvd[2]; | 78 | u8 rsvd[2]; |
78 | }; | 79 | }; |
79 | 80 | ||
81 | struct bfi_lps_cvl_event_s { | ||
82 | struct bfi_mhdr_s mh; /* common msg header */ | ||
83 | u8 lp_tag; | ||
84 | u8 rsvd[3]; | ||
85 | }; | ||
86 | |||
80 | union bfi_lps_h2i_msg_u { | 87 | union bfi_lps_h2i_msg_u { |
81 | struct bfi_mhdr_s *msg; | 88 | struct bfi_mhdr_s *msg; |
82 | struct bfi_lps_login_req_s *login_req; | 89 | struct bfi_lps_login_req_s *login_req; |
@@ -87,6 +94,7 @@ union bfi_lps_i2h_msg_u { | |||
87 | struct bfi_msg_s *msg; | 94 | struct bfi_msg_s *msg; |
88 | struct bfi_lps_login_rsp_s *login_rsp; | 95 | struct bfi_lps_login_rsp_s *login_rsp; |
89 | struct bfi_lps_logout_rsp_s *logout_rsp; | 96 | struct bfi_lps_logout_rsp_s *logout_rsp; |
97 | struct bfi_lps_cvl_event_s *cvl_event; | ||
90 | }; | 98 | }; |
91 | 99 | ||
92 | #pragma pack() | 100 | #pragma pack() |
diff --git a/drivers/scsi/bfa/include/bfi/bfi_pport.h b/drivers/scsi/bfa/include/bfi/bfi_pport.h index c96d246851af..50dcf45c7470 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_pport.h +++ b/drivers/scsi/bfa/include/bfi/bfi_pport.h | |||
@@ -22,163 +22,97 @@ | |||
22 | 22 | ||
23 | #pragma pack(1) | 23 | #pragma pack(1) |
24 | 24 | ||
25 | enum bfi_pport_h2i { | 25 | enum bfi_fcport_h2i { |
26 | BFI_PPORT_H2I_ENABLE_REQ = (1), | 26 | BFI_FCPORT_H2I_ENABLE_REQ = (1), |
27 | BFI_PPORT_H2I_DISABLE_REQ = (2), | 27 | BFI_FCPORT_H2I_DISABLE_REQ = (2), |
28 | BFI_PPORT_H2I_GET_STATS_REQ = (3), | 28 | BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ = (3), |
29 | BFI_PPORT_H2I_CLEAR_STATS_REQ = (4), | 29 | BFI_FCPORT_H2I_STATS_GET_REQ = (4), |
30 | BFI_PPORT_H2I_SET_SVC_PARAMS_REQ = (5), | 30 | BFI_FCPORT_H2I_STATS_CLEAR_REQ = (5), |
31 | BFI_PPORT_H2I_ENABLE_RX_VF_TAG_REQ = (6), | ||
32 | BFI_PPORT_H2I_ENABLE_TX_VF_TAG_REQ = (7), | ||
33 | BFI_PPORT_H2I_GET_QOS_STATS_REQ = (8), | ||
34 | BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ = (9), | ||
35 | }; | 31 | }; |
36 | 32 | ||
37 | enum bfi_pport_i2h { | 33 | enum bfi_fcport_i2h { |
38 | BFI_PPORT_I2H_ENABLE_RSP = BFA_I2HM(1), | 34 | BFI_FCPORT_I2H_ENABLE_RSP = BFA_I2HM(1), |
39 | BFI_PPORT_I2H_DISABLE_RSP = BFA_I2HM(2), | 35 | BFI_FCPORT_I2H_DISABLE_RSP = BFA_I2HM(2), |
40 | BFI_PPORT_I2H_GET_STATS_RSP = BFA_I2HM(3), | 36 | BFI_FCPORT_I2H_SET_SVC_PARAMS_RSP = BFA_I2HM(3), |
41 | BFI_PPORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4), | 37 | BFI_FCPORT_I2H_STATS_GET_RSP = BFA_I2HM(4), |
42 | BFI_PPORT_I2H_SET_SVC_PARAMS_RSP = BFA_I2HM(5), | 38 | BFI_FCPORT_I2H_STATS_CLEAR_RSP = BFA_I2HM(5), |
43 | BFI_PPORT_I2H_ENABLE_RX_VF_TAG_RSP = BFA_I2HM(6), | 39 | BFI_FCPORT_I2H_EVENT = BFA_I2HM(6), |
44 | BFI_PPORT_I2H_ENABLE_TX_VF_TAG_RSP = BFA_I2HM(7), | ||
45 | BFI_PPORT_I2H_EVENT = BFA_I2HM(8), | ||
46 | BFI_PPORT_I2H_GET_QOS_STATS_RSP = BFA_I2HM(9), | ||
47 | BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP = BFA_I2HM(10), | ||
48 | }; | 40 | }; |
49 | 41 | ||
50 | /** | 42 | /** |
51 | * Generic REQ type | 43 | * Generic REQ type |
52 | */ | 44 | */ |
53 | struct bfi_pport_generic_req_s { | 45 | struct bfi_fcport_req_s { |
54 | struct bfi_mhdr_s mh; /* msg header */ | 46 | struct bfi_mhdr_s mh; /* msg header */ |
55 | u32 msgtag; /* msgtag for reply */ | 47 | u32 msgtag; /* msgtag for reply */ |
56 | }; | 48 | }; |
57 | 49 | ||
58 | /** | 50 | /** |
59 | * Generic RSP type | 51 | * Generic RSP type |
60 | */ | 52 | */ |
61 | struct bfi_pport_generic_rsp_s { | 53 | struct bfi_fcport_rsp_s { |
62 | struct bfi_mhdr_s mh; /* common msg header */ | 54 | struct bfi_mhdr_s mh; /* common msg header */ |
63 | u8 status; /* port enable status */ | 55 | u8 status; /* port enable status */ |
64 | u8 rsvd[3]; | 56 | u8 rsvd[3]; |
65 | u32 msgtag; /* msgtag for reply */ | 57 | u32 msgtag; /* msgtag for reply */ |
66 | }; | 58 | }; |
67 | 59 | ||
68 | /** | 60 | /** |
69 | * BFI_PPORT_H2I_ENABLE_REQ | 61 | * BFI_FCPORT_H2I_ENABLE_REQ |
70 | */ | 62 | */ |
71 | struct bfi_pport_enable_req_s { | 63 | struct bfi_fcport_enable_req_s { |
72 | struct bfi_mhdr_s mh; /* msg header */ | 64 | struct bfi_mhdr_s mh; /* msg header */ |
73 | u32 rsvd1; | 65 | u32 rsvd1; |
74 | wwn_t nwwn; /* node wwn of physical port */ | 66 | wwn_t nwwn; /* node wwn of physical port */ |
75 | wwn_t pwwn; /* port wwn of physical port */ | 67 | wwn_t pwwn; /* port wwn of physical port */ |
76 | struct bfa_pport_cfg_s port_cfg; /* port configuration */ | 68 | struct bfa_pport_cfg_s port_cfg; /* port configuration */ |
77 | union bfi_addr_u stats_dma_addr; /* DMA address for stats */ | 69 | union bfi_addr_u stats_dma_addr; /* DMA address for stats */ |
78 | u32 msgtag; /* msgtag for reply */ | 70 | u32 msgtag; /* msgtag for reply */ |
79 | u32 rsvd2; | 71 | u32 rsvd2; |
80 | }; | 72 | }; |
81 | 73 | ||
82 | /** | 74 | /** |
83 | * BFI_PPORT_I2H_ENABLE_RSP | 75 | * BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ |
84 | */ | 76 | */ |
85 | #define bfi_pport_enable_rsp_t struct bfi_pport_generic_rsp_s | 77 | struct bfi_fcport_set_svc_params_req_s { |
86 | |||
87 | /** | ||
88 | * BFI_PPORT_H2I_DISABLE_REQ | ||
89 | */ | ||
90 | #define bfi_pport_disable_req_t struct bfi_pport_generic_req_s | ||
91 | |||
92 | /** | ||
93 | * BFI_PPORT_I2H_DISABLE_RSP | ||
94 | */ | ||
95 | #define bfi_pport_disable_rsp_t struct bfi_pport_generic_rsp_s | ||
96 | |||
97 | /** | ||
98 | * BFI_PPORT_H2I_GET_STATS_REQ | ||
99 | */ | ||
100 | #define bfi_pport_get_stats_req_t struct bfi_pport_generic_req_s | ||
101 | |||
102 | /** | ||
103 | * BFI_PPORT_I2H_GET_STATS_RSP | ||
104 | */ | ||
105 | #define bfi_pport_get_stats_rsp_t struct bfi_pport_generic_rsp_s | ||
106 | |||
107 | /** | ||
108 | * BFI_PPORT_H2I_CLEAR_STATS_REQ | ||
109 | */ | ||
110 | #define bfi_pport_clear_stats_req_t struct bfi_pport_generic_req_s | ||
111 | |||
112 | /** | ||
113 | * BFI_PPORT_I2H_CLEAR_STATS_RSP | ||
114 | */ | ||
115 | #define bfi_pport_clear_stats_rsp_t struct bfi_pport_generic_rsp_s | ||
116 | |||
117 | /** | ||
118 | * BFI_PPORT_H2I_GET_QOS_STATS_REQ | ||
119 | */ | ||
120 | #define bfi_pport_get_qos_stats_req_t struct bfi_pport_generic_req_s | ||
121 | |||
122 | /** | ||
123 | * BFI_PPORT_H2I_GET_QOS_STATS_RSP | ||
124 | */ | ||
125 | #define bfi_pport_get_qos_stats_rsp_t struct bfi_pport_generic_rsp_s | ||
126 | |||
127 | /** | ||
128 | * BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ | ||
129 | */ | ||
130 | #define bfi_pport_clear_qos_stats_req_t struct bfi_pport_generic_req_s | ||
131 | |||
132 | /** | ||
133 | * BFI_PPORT_H2I_CLEAR_QOS_STATS_RSP | ||
134 | */ | ||
135 | #define bfi_pport_clear_qos_stats_rsp_t struct bfi_pport_generic_rsp_s | ||
136 | |||
137 | /** | ||
138 | * BFI_PPORT_H2I_SET_SVC_PARAMS_REQ | ||
139 | */ | ||
140 | struct bfi_pport_set_svc_params_req_s { | ||
141 | struct bfi_mhdr_s mh; /* msg header */ | 78 | struct bfi_mhdr_s mh; /* msg header */ |
142 | u16 tx_bbcredit; /* Tx credits */ | 79 | u16 tx_bbcredit; /* Tx credits */ |
143 | u16 rsvd; | 80 | u16 rsvd; |
144 | }; | 81 | }; |
145 | 82 | ||
146 | /** | 83 | /** |
147 | * BFI_PPORT_I2H_SET_SVC_PARAMS_RSP | 84 | * BFI_FCPORT_I2H_EVENT |
148 | */ | ||
149 | |||
150 | /** | ||
151 | * BFI_PPORT_I2H_EVENT | ||
152 | */ | 85 | */ |
153 | struct bfi_pport_event_s { | 86 | struct bfi_fcport_event_s { |
154 | struct bfi_mhdr_s mh; /* common msg header */ | 87 | struct bfi_mhdr_s mh; /* common msg header */ |
155 | struct bfa_pport_link_s link_state; | 88 | struct bfa_pport_link_s link_state; |
156 | }; | 89 | }; |
157 | 90 | ||
158 | union bfi_pport_h2i_msg_u { | 91 | /** |
92 | * fcport H2I message | ||
93 | */ | ||
94 | union bfi_fcport_h2i_msg_u { | ||
159 | struct bfi_mhdr_s *mhdr; | 95 | struct bfi_mhdr_s *mhdr; |
160 | struct bfi_pport_enable_req_s *penable; | 96 | struct bfi_fcport_enable_req_s *penable; |
161 | struct bfi_pport_generic_req_s *pdisable; | 97 | struct bfi_fcport_req_s *pdisable; |
162 | struct bfi_pport_generic_req_s *pgetstats; | 98 | struct bfi_fcport_set_svc_params_req_s *psetsvcparams; |
163 | struct bfi_pport_generic_req_s *pclearstats; | 99 | struct bfi_fcport_req_s *pstatsget; |
164 | struct bfi_pport_set_svc_params_req_s *psetsvcparams; | 100 | struct bfi_fcport_req_s *pstatsclear; |
165 | struct bfi_pport_get_qos_stats_req_s *pgetqosstats; | ||
166 | struct bfi_pport_generic_req_s *pclearqosstats; | ||
167 | }; | 101 | }; |
168 | 102 | ||
169 | union bfi_pport_i2h_msg_u { | 103 | /** |
104 | * fcport I2H message | ||
105 | */ | ||
106 | union bfi_fcport_i2h_msg_u { | ||
170 | struct bfi_msg_s *msg; | 107 | struct bfi_msg_s *msg; |
171 | struct bfi_pport_generic_rsp_s *enable_rsp; | 108 | struct bfi_fcport_rsp_s *penable_rsp; |
172 | struct bfi_pport_disable_rsp_s *disable_rsp; | 109 | struct bfi_fcport_rsp_s *pdisable_rsp; |
173 | struct bfi_pport_generic_rsp_s *getstats_rsp; | 110 | struct bfi_fcport_rsp_s *psetsvcparams_rsp; |
174 | struct bfi_pport_clear_stats_rsp_s *clearstats_rsp; | 111 | struct bfi_fcport_rsp_s *pstatsget_rsp; |
175 | struct bfi_pport_set_svc_params_rsp_s *setsvcparasm_rsp; | 112 | struct bfi_fcport_rsp_s *pstatsclear_rsp; |
176 | struct bfi_pport_get_qos_stats_rsp_s *getqosstats_rsp; | 113 | struct bfi_fcport_event_s *event; |
177 | struct bfi_pport_clear_qos_stats_rsp_s *clearqosstats_rsp; | ||
178 | struct bfi_pport_event_s *event; | ||
179 | }; | 114 | }; |
180 | 115 | ||
181 | #pragma pack() | 116 | #pragma pack() |
182 | 117 | ||
183 | #endif /* __BFI_PPORT_H__ */ | 118 | #endif /* __BFI_PPORT_H__ */ |
184 | |||
diff --git a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h index 43ba7064e81a..a75a1f3be315 100644 --- a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h +++ b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h | |||
@@ -31,6 +31,10 @@ | |||
31 | enum { | 31 | enum { |
32 | BFA_TRC_CNA_CEE = 1, | 32 | BFA_TRC_CNA_CEE = 1, |
33 | BFA_TRC_CNA_PORT = 2, | 33 | BFA_TRC_CNA_PORT = 2, |
34 | BFA_TRC_CNA_IOC = 3, | ||
35 | BFA_TRC_CNA_DIAG = 4, | ||
36 | BFA_TRC_CNA_IOC_CB = 5, | ||
37 | BFA_TRC_CNA_IOC_CT = 6, | ||
34 | }; | 38 | }; |
35 | 39 | ||
36 | #endif /* __BFA_CNA_TRCMOD_H__ */ | 40 | #endif /* __BFA_CNA_TRCMOD_H__ */ |
diff --git a/drivers/scsi/bfa/include/cs/bfa_log.h b/drivers/scsi/bfa/include/cs/bfa_log.h index 761cbe22130a..bc334e0a93fa 100644 --- a/drivers/scsi/bfa/include/cs/bfa_log.h +++ b/drivers/scsi/bfa/include/cs/bfa_log.h | |||
@@ -157,7 +157,7 @@ typedef void (*bfa_log_cb_t)(struct bfa_log_mod_s *log_mod, u32 msg_id, | |||
157 | 157 | ||
158 | 158 | ||
159 | struct bfa_log_mod_s { | 159 | struct bfa_log_mod_s { |
160 | char instance_info[16]; /* instance info */ | 160 | char instance_info[BFA_STRING_32]; /* instance info */ |
161 | int log_level[BFA_LOG_MODULE_ID_MAX + 1]; | 161 | int log_level[BFA_LOG_MODULE_ID_MAX + 1]; |
162 | /* log level for modules */ | 162 | /* log level for modules */ |
163 | bfa_log_cb_t cbfn; /* callback function */ | 163 | bfa_log_cb_t cbfn; /* callback function */ |
diff --git a/drivers/scsi/bfa/include/cs/bfa_plog.h b/drivers/scsi/bfa/include/cs/bfa_plog.h index 670f86e5fc6e..f5bef63b5877 100644 --- a/drivers/scsi/bfa/include/cs/bfa_plog.h +++ b/drivers/scsi/bfa/include/cs/bfa_plog.h | |||
@@ -80,7 +80,8 @@ enum bfa_plog_mid { | |||
80 | BFA_PL_MID_HAL_FCXP = 4, | 80 | BFA_PL_MID_HAL_FCXP = 4, |
81 | BFA_PL_MID_HAL_UF = 5, | 81 | BFA_PL_MID_HAL_UF = 5, |
82 | BFA_PL_MID_FCS = 6, | 82 | BFA_PL_MID_FCS = 6, |
83 | BFA_PL_MID_MAX = 7 | 83 | BFA_PL_MID_LPS = 7, |
84 | BFA_PL_MID_MAX = 8 | ||
84 | }; | 85 | }; |
85 | 86 | ||
86 | #define BFA_PL_MID_STRLEN 8 | 87 | #define BFA_PL_MID_STRLEN 8 |
@@ -118,7 +119,11 @@ enum bfa_plog_eid { | |||
118 | BFA_PL_EID_RSCN = 17, | 119 | BFA_PL_EID_RSCN = 17, |
119 | BFA_PL_EID_DEBUG = 18, | 120 | BFA_PL_EID_DEBUG = 18, |
120 | BFA_PL_EID_MISC = 19, | 121 | BFA_PL_EID_MISC = 19, |
121 | BFA_PL_EID_MAX = 20 | 122 | BFA_PL_EID_FIP_FCF_DISC = 20, |
123 | BFA_PL_EID_FIP_FCF_CVL = 21, | ||
124 | BFA_PL_EID_LOGIN = 22, | ||
125 | BFA_PL_EID_LOGO = 23, | ||
126 | BFA_PL_EID_MAX = 24 | ||
122 | }; | 127 | }; |
123 | 128 | ||
124 | #define BFA_PL_ENAME_STRLEN 8 | 129 | #define BFA_PL_ENAME_STRLEN 8 |
diff --git a/drivers/scsi/bfa/include/cs/bfa_sm.h b/drivers/scsi/bfa/include/cs/bfa_sm.h index b0a92baf6657..11fba9082f05 100644 --- a/drivers/scsi/bfa/include/cs/bfa_sm.h +++ b/drivers/scsi/bfa/include/cs/bfa_sm.h | |||
@@ -23,6 +23,14 @@ | |||
23 | #define __BFA_SM_H__ | 23 | #define __BFA_SM_H__ |
24 | 24 | ||
25 | typedef void (*bfa_sm_t)(void *sm, int event); | 25 | typedef void (*bfa_sm_t)(void *sm, int event); |
26 | /** | ||
27 | * oc - object class eg. bfa_ioc | ||
28 | * st - state, eg. reset | ||
29 | * otype - object type, eg. struct bfa_ioc_s | ||
30 | * etype - object type, eg. enum ioc_event | ||
31 | */ | ||
32 | #define bfa_sm_state_decl(oc, st, otype, etype) \ | ||
33 | static void oc ## _sm_ ## st(otype * fsm, etype event) | ||
26 | 34 | ||
27 | #define bfa_sm_set_state(_sm, _state) ((_sm)->sm = (bfa_sm_t)(_state)) | 35 | #define bfa_sm_set_state(_sm, _state) ((_sm)->sm = (bfa_sm_t)(_state)) |
28 | #define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event))) | 36 | #define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event))) |
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_aen.h b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h index 4c81a613db3d..35244698fcdc 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_aen.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h | |||
@@ -30,6 +30,16 @@ | |||
30 | #include <defs/bfa_defs_audit.h> | 30 | #include <defs/bfa_defs_audit.h> |
31 | #include <defs/bfa_defs_ethport.h> | 31 | #include <defs/bfa_defs_ethport.h> |
32 | 32 | ||
33 | #define BFA_AEN_MAX_APP 5 | ||
34 | |||
35 | enum bfa_aen_app { | ||
36 | bfa_aen_app_bcu = 0, /* No thread for bcu */ | ||
37 | bfa_aen_app_hcm = 1, | ||
38 | bfa_aen_app_cim = 2, | ||
39 | bfa_aen_app_snia = 3, | ||
40 | bfa_aen_app_test = 4, /* To be removed after unit test */ | ||
41 | }; | ||
42 | |||
33 | enum bfa_aen_category { | 43 | enum bfa_aen_category { |
34 | BFA_AEN_CAT_ADAPTER = 1, | 44 | BFA_AEN_CAT_ADAPTER = 1, |
35 | BFA_AEN_CAT_PORT = 2, | 45 | BFA_AEN_CAT_PORT = 2, |
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h index dd19c83aba58..45df32820911 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #define PRIVATE_KEY 19009 | 23 | #define PRIVATE_KEY 19009 |
24 | #define KEY_LEN 32399 | 24 | #define KEY_LEN 32399 |
25 | #define BFA_AUTH_SECRET_STRING_LEN 256 | 25 | #define BFA_AUTH_SECRET_STRING_LEN 256 |
26 | #define BFA_AUTH_FAIL_NO_PASSWORD 0xFE | ||
26 | #define BFA_AUTH_FAIL_TIMEOUT 0xFF | 27 | #define BFA_AUTH_FAIL_TIMEOUT 0xFF |
27 | 28 | ||
28 | /** | 29 | /** |
@@ -41,6 +42,27 @@ enum bfa_auth_status { | |||
41 | BFA_AUTH_STATUS_UNKNOWN = 9, /* authentication status unknown */ | 42 | BFA_AUTH_STATUS_UNKNOWN = 9, /* authentication status unknown */ |
42 | }; | 43 | }; |
43 | 44 | ||
45 | enum bfa_auth_rej_code { | ||
46 | BFA_AUTH_RJT_CODE_AUTH_FAILURE = 1, /* auth failure */ | ||
47 | BFA_AUTH_RJT_CODE_LOGICAL_ERR = 2, /* logical error */ | ||
48 | }; | ||
49 | |||
50 | /** | ||
51 | * Authentication reject codes | ||
52 | */ | ||
53 | enum bfa_auth_rej_code_exp { | ||
54 | BFA_AUTH_MECH_NOT_USABLE = 1, /* auth. mechanism not usable */ | ||
55 | BFA_AUTH_DH_GROUP_NOT_USABLE = 2, /* DH Group not usable */ | ||
56 | BFA_AUTH_HASH_FUNC_NOT_USABLE = 3, /* hash Function not usable */ | ||
57 | BFA_AUTH_AUTH_XACT_STARTED = 4, /* auth xact started */ | ||
58 | BFA_AUTH_AUTH_FAILED = 5, /* auth failed */ | ||
59 | BFA_AUTH_INCORRECT_PLD = 6, /* incorrect payload */ | ||
60 | BFA_AUTH_INCORRECT_PROTO_MSG = 7, /* incorrect proto msg */ | ||
61 | BFA_AUTH_RESTART_AUTH_PROTO = 8, /* restart auth protocol */ | ||
62 | BFA_AUTH_AUTH_CONCAT_NOT_SUPP = 9, /* auth concat not supported */ | ||
63 | BFA_AUTH_PROTO_VER_NOT_SUPP = 10,/* proto version not supported */ | ||
64 | }; | ||
65 | |||
44 | struct auth_proto_stats_s { | 66 | struct auth_proto_stats_s { |
45 | u32 auth_rjts; | 67 | u32 auth_rjts; |
46 | u32 auth_negs; | 68 | u32 auth_negs; |
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_cee.h b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h index 520a22f52dd1..b0ac9ac15c5d 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_cee.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h | |||
@@ -28,10 +28,6 @@ | |||
28 | 28 | ||
29 | #define BFA_CEE_LLDP_MAX_STRING_LEN (128) | 29 | #define BFA_CEE_LLDP_MAX_STRING_LEN (128) |
30 | 30 | ||
31 | |||
32 | /* FIXME: this is coming from the protocol spec. Can the host & apps share the | ||
33 | protocol .h files ? | ||
34 | */ | ||
35 | #define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001 | 31 | #define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001 |
36 | #define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002 | 32 | #define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002 |
37 | #define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004 | 33 | #define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004 |
@@ -94,9 +90,10 @@ struct bfa_cee_dcbx_cfg_s { | |||
94 | /* CEE status */ | 90 | /* CEE status */ |
95 | /* Making this to tri-state for the benefit of port list command */ | 91 | /* Making this to tri-state for the benefit of port list command */ |
96 | enum bfa_cee_status_e { | 92 | enum bfa_cee_status_e { |
97 | CEE_PHY_DOWN = 0, | 93 | CEE_UP = 0, |
98 | CEE_PHY_UP = 1, | 94 | CEE_PHY_UP = 1, |
99 | CEE_UP = 2, | 95 | CEE_LOOPBACK = 2, |
96 | CEE_PHY_DOWN = 3, | ||
100 | }; | 97 | }; |
101 | 98 | ||
102 | /* CEE Query */ | 99 | /* CEE Query */ |
@@ -107,7 +104,8 @@ struct bfa_cee_attr_s { | |||
107 | struct bfa_cee_dcbx_cfg_s dcbx_remote; | 104 | struct bfa_cee_dcbx_cfg_s dcbx_remote; |
108 | mac_t src_mac; | 105 | mac_t src_mac; |
109 | u8 link_speed; | 106 | u8 link_speed; |
110 | u8 filler[3]; | 107 | u8 nw_priority; |
108 | u8 filler[2]; | ||
111 | }; | 109 | }; |
112 | 110 | ||
113 | 111 | ||
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h index 57049805762b..50382dd2ab41 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h | |||
@@ -21,6 +21,7 @@ | |||
21 | /** | 21 | /** |
22 | * Driver statistics | 22 | * Driver statistics |
23 | */ | 23 | */ |
24 | struct bfa_driver_stats_s { | ||
24 | u16 tm_io_abort; | 25 | u16 tm_io_abort; |
25 | u16 tm_io_abort_comp; | 26 | u16 tm_io_abort_comp; |
26 | u16 tm_lun_reset; | 27 | u16 tm_lun_reset; |
@@ -34,7 +35,7 @@ | |||
34 | u64 output_req; | 35 | u64 output_req; |
35 | u64 input_words; | 36 | u64 input_words; |
36 | u64 output_words; | 37 | u64 output_words; |
37 | } bfa_driver_stats_t; | 38 | }; |
38 | 39 | ||
39 | 40 | ||
40 | #endif /* __BFA_DEFS_DRIVER_H__ */ | 41 | #endif /* __BFA_DEFS_DRIVER_H__ */ |
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h index 79f9b3e146f7..b4fa0923aa89 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #define __BFA_DEFS_ETHPORT_H__ | 19 | #define __BFA_DEFS_ETHPORT_H__ |
20 | 20 | ||
21 | #include <defs/bfa_defs_status.h> | 21 | #include <defs/bfa_defs_status.h> |
22 | #include <defs/bfa_defs_port.h> | ||
22 | #include <protocol/types.h> | 23 | #include <protocol/types.h> |
23 | #include <cna/pstats/phyport_defs.h> | 24 | #include <cna/pstats/phyport_defs.h> |
24 | #include <cna/pstats/ethport_defs.h> | 25 | #include <cna/pstats/ethport_defs.h> |
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h b/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h new file mode 100644 index 000000000000..a07ef4a3cd78 --- /dev/null +++ b/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. | ||
3 | * All rights reserved | ||
4 | * www.brocade.com | ||
5 | * | ||
6 | * bfa_defs_fcport.h | ||
7 | * | ||
8 | * Linux driver for Brocade Fibre Channel Host Bus Adapter. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License (GPL) Version 2 as | ||
12 | * published by the Free Software Foundation | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | */ | ||
19 | #ifndef __BFA_DEFS_FCPORT_H__ | ||
20 | #define __BFA_DEFS_FCPORT_H__ | ||
21 | |||
22 | #include <defs/bfa_defs_types.h> | ||
23 | #include <protocol/types.h> | ||
24 | |||
25 | #pragma pack(1) | ||
26 | |||
27 | /** | ||
28 | * FCoE statistics | ||
29 | */ | ||
30 | struct bfa_fcoe_stats_s { | ||
31 | u64 secs_reset; /* Seconds since stats reset */ | ||
32 | u64 cee_linkups; /* CEE link up */ | ||
33 | u64 cee_linkdns; /* CEE link down */ | ||
34 | u64 fip_linkups; /* FIP link up */ | ||
35 | u64 fip_linkdns; /* FIP link down */ | ||
36 | u64 fip_fails; /* FIP failures */ | ||
37 | u64 mac_invalids; /* Invalid mac assignments */ | ||
38 | u64 vlan_req; /* Vlan requests */ | ||
39 | u64 vlan_notify; /* Vlan notifications */ | ||
40 | u64 vlan_err; /* Vlan notification errors */ | ||
41 | u64 vlan_timeouts; /* Vlan request timeouts */ | ||
42 | u64 vlan_invalids; /* Vlan invalids */ | ||
43 | u64 disc_req; /* Discovery requests */ | ||
44 | u64 disc_rsp; /* Discovery responses */ | ||
45 | u64 disc_err; /* Discovery error frames */ | ||
46 | u64 disc_unsol; /* Discovery unsolicited */ | ||
47 | u64 disc_timeouts; /* Discovery timeouts */ | ||
48 | u64 disc_fcf_unavail; /* Discovery FCF not avail */ | ||
49 | u64 linksvc_unsupp; /* FIP link service req unsupp. */ | ||
50 | u64 linksvc_err; /* FIP link service req errors */ | ||
51 | u64 logo_req; /* FIP logo */ | ||
52 | u64 clrvlink_req; /* Clear virtual link requests */ | ||
53 | u64 op_unsupp; /* FIP operation unsupp. */ | ||
54 | u64 untagged; /* FIP untagged frames */ | ||
55 | u64 txf_ucast; /* Tx FCoE unicast frames */ | ||
56 | u64 txf_ucast_vlan; /* Tx FCoE unicast vlan frames */ | ||
57 | u64 txf_ucast_octets; /* Tx FCoE unicast octets */ | ||
58 | u64 txf_mcast; /* Tx FCoE mutlicast frames */ | ||
59 | u64 txf_mcast_vlan; /* Tx FCoE mutlicast vlan frames */ | ||
60 | u64 txf_mcast_octets; /* Tx FCoE multicast octets */ | ||
61 | u64 txf_bcast; /* Tx FCoE broadcast frames */ | ||
62 | u64 txf_bcast_vlan; /* Tx FCoE broadcast vlan frames */ | ||
63 | u64 txf_bcast_octets; /* Tx FCoE broadcast octets */ | ||
64 | u64 txf_timeout; /* Tx timeouts */ | ||
65 | u64 txf_parity_errors; /* Transmit parity err */ | ||
66 | u64 txf_fid_parity_errors; /* Transmit FID parity err */ | ||
67 | u64 tx_pause; /* Tx pause frames */ | ||
68 | u64 tx_zero_pause; /* Tx zero pause frames */ | ||
69 | u64 tx_first_pause; /* Tx first pause frames */ | ||
70 | u64 rx_pause; /* Rx pause frames */ | ||
71 | u64 rx_zero_pause; /* Rx zero pause frames */ | ||
72 | u64 rx_first_pause; /* Rx first pause frames */ | ||
73 | u64 rxf_ucast_octets; /* Rx unicast octets */ | ||
74 | u64 rxf_ucast; /* Rx unicast frames */ | ||
75 | u64 rxf_ucast_vlan; /* Rx unicast vlan frames */ | ||
76 | u64 rxf_mcast_octets; /* Rx multicast octets */ | ||
77 | u64 rxf_mcast; /* Rx multicast frames */ | ||
78 | u64 rxf_mcast_vlan; /* Rx multicast vlan frames */ | ||
79 | u64 rxf_bcast_octets; /* Rx broadcast octests */ | ||
80 | u64 rxf_bcast; /* Rx broadcast frames */ | ||
81 | u64 rxf_bcast_vlan; /* Rx broadcast vlan frames */ | ||
82 | }; | ||
83 | |||
84 | /** | ||
85 | * QoS or FCoE stats (fcport stats excluding physical FC port stats) | ||
86 | */ | ||
87 | union bfa_fcport_stats_u { | ||
88 | struct bfa_qos_stats_s fcqos; | ||
89 | struct bfa_fcoe_stats_s fcoe; | ||
90 | }; | ||
91 | |||
92 | #pragma pack() | ||
93 | |||
94 | #endif /* __BFA_DEFS_FCPORT_H__ */ | ||
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h deleted file mode 100644 index 9ccf53bef65a..000000000000 --- a/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. | ||
3 | * All rights reserved | ||
4 | * www.brocade.com | ||
5 | * | ||
6 | * Linux driver for Brocade Fibre Channel Host Bus Adapter. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License (GPL) Version 2 as | ||
10 | * published by the Free Software Foundation | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #ifndef __BFA_DEFS_IM_COMMON_H__ | ||
19 | #define __BFA_DEFS_IM_COMMON_H__ | ||
20 | |||
21 | #define BFA_ADAPTER_NAME_LEN 256 | ||
22 | #define BFA_ADAPTER_GUID_LEN 256 | ||
23 | #define RESERVED_VLAN_NAME L"PORT VLAN" | ||
24 | #define PASSTHRU_VLAN_NAME L"PASSTHRU VLAN" | ||
25 | |||
26 | u64 tx_pkt_cnt; | ||
27 | u64 rx_pkt_cnt; | ||
28 | u32 duration; | ||
29 | u8 status; | ||
30 | } bfa_im_stats_t, *pbfa_im_stats_t; | ||
31 | |||
32 | #endif /* __BFA_DEFS_IM_COMMON_H__ */ | ||
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h deleted file mode 100644 index a486a7eb81d6..000000000000 --- a/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h +++ /dev/null | |||
@@ -1,72 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. | ||
3 | * All rights reserved | ||
4 | * www.brocade.com | ||
5 | * | ||
6 | * Linux driver for Brocade Fibre Channel Host Bus Adapter. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License (GPL) Version 2 as | ||
10 | * published by the Free Software Foundation | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #ifndef __BFA_DEFS_IM_TEAM_H__ | ||
19 | #define __BFA_DEFS_IM_TEAM_H__ | ||
20 | |||
21 | #include <protocol/types.h> | ||
22 | |||
23 | #define BFA_TEAM_MAX_PORTS 8 | ||
24 | #define BFA_TEAM_NAME_LEN 256 | ||
25 | #define BFA_MAX_NUM_TEAMS 16 | ||
26 | #define BFA_TEAM_INVALID_DELAY -1 | ||
27 | |||
28 | BFA_LACP_RATE_SLOW = 1, | ||
29 | BFA_LACP_RATE_FAST | ||
30 | } bfa_im_lacp_rate_t; | ||
31 | |||
32 | BFA_TEAM_MODE_FAIL_OVER = 1, | ||
33 | BFA_TEAM_MODE_FAIL_BACK, | ||
34 | BFA_TEAM_MODE_LACP, | ||
35 | BFA_TEAM_MODE_NONE | ||
36 | } bfa_im_team_mode_t; | ||
37 | |||
38 | BFA_XMIT_POLICY_L2 = 1, | ||
39 | BFA_XMIT_POLICY_L3_L4 | ||
40 | } bfa_im_xmit_policy_t; | ||
41 | |||
42 | bfa_im_team_mode_t team_mode; | ||
43 | bfa_im_lacp_rate_t lacp_rate; | ||
44 | bfa_im_xmit_policy_t xmit_policy; | ||
45 | int delay; | ||
46 | wchar_t primary[BFA_ADAPTER_NAME_LEN]; | ||
47 | wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN]; | ||
48 | mac_t mac; | ||
49 | u16 num_ports; | ||
50 | u16 num_vlans; | ||
51 | u16 vlan_list[BFA_MAX_VLANS_PER_PORT]; | ||
52 | wchar_t team_guid_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_GUID_LEN]; | ||
53 | wchar_t ioc_name_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_NAME_LEN]; | ||
54 | } bfa_im_team_attr_t; | ||
55 | |||
56 | wchar_t team_name[BFA_TEAM_NAME_LEN]; | ||
57 | bfa_im_xmit_policy_t xmit_policy; | ||
58 | int delay; | ||
59 | wchar_t primary[BFA_ADAPTER_NAME_LEN]; | ||
60 | wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN]; | ||
61 | } bfa_im_team_edit_t, *pbfa_im_team_edit_t; | ||
62 | |||
63 | wchar_t team_name[BFA_TEAM_NAME_LEN]; | ||
64 | bfa_im_team_mode_t team_mode; | ||
65 | mac_t mac; | ||
66 | } bfa_im_team_info_t; | ||
67 | |||
68 | bfa_im_team_info_t team_info[BFA_MAX_NUM_TEAMS]; | ||
69 | u16 num_teams; | ||
70 | } bfa_im_team_list_t, *pbfa_im_team_list_t; | ||
71 | |||
72 | #endif /* __BFA_DEFS_IM_TEAM_H__ */ | ||
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h index b1d532da3a9d..8d8e6a966537 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h | |||
@@ -126,6 +126,7 @@ struct bfa_ioc_attr_s { | |||
126 | struct bfa_ioc_driver_attr_s driver_attr; /* driver attr */ | 126 | struct bfa_ioc_driver_attr_s driver_attr; /* driver attr */ |
127 | struct bfa_ioc_pci_attr_s pci_attr; | 127 | struct bfa_ioc_pci_attr_s pci_attr; |
128 | u8 port_id; /* port number */ | 128 | u8 port_id; /* port number */ |
129 | u8 rsvd[7]; /*!< 64bit align */ | ||
129 | }; | 130 | }; |
130 | 131 | ||
131 | /** | 132 | /** |
@@ -143,8 +144,8 @@ enum bfa_ioc_aen_event { | |||
143 | * BFA IOC level event data, now just a place holder | 144 | * BFA IOC level event data, now just a place holder |
144 | */ | 145 | */ |
145 | struct bfa_ioc_aen_data_s { | 146 | struct bfa_ioc_aen_data_s { |
146 | enum bfa_ioc_type_e ioc_type; | ||
147 | wwn_t pwwn; | 147 | wwn_t pwwn; |
148 | s16 ioc_type; | ||
148 | mac_t mac; | 149 | mac_t mac; |
149 | }; | 150 | }; |
150 | 151 | ||
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h index d76bcbd9820f..c290fb13d2d1 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h | |||
@@ -26,6 +26,8 @@ | |||
26 | 26 | ||
27 | #define BFA_IOCFC_INTR_DELAY 1125 | 27 | #define BFA_IOCFC_INTR_DELAY 1125 |
28 | #define BFA_IOCFC_INTR_LATENCY 225 | 28 | #define BFA_IOCFC_INTR_LATENCY 225 |
29 | #define BFA_IOCFCOE_INTR_DELAY 25 | ||
30 | #define BFA_IOCFCOE_INTR_LATENCY 5 | ||
29 | 31 | ||
30 | /** | 32 | /** |
31 | * Interrupt coalescing configuration. | 33 | * Interrupt coalescing configuration. |
@@ -50,7 +52,7 @@ struct bfa_iocfc_fwcfg_s { | |||
50 | u16 num_fcxp_reqs; /* unassisted FC exchanges */ | 52 | u16 num_fcxp_reqs; /* unassisted FC exchanges */ |
51 | u16 num_uf_bufs; /* unsolicited recv buffers */ | 53 | u16 num_uf_bufs; /* unsolicited recv buffers */ |
52 | u8 num_cqs; | 54 | u8 num_cqs; |
53 | u8 rsvd; | 55 | u8 rsvd[5]; |
54 | }; | 56 | }; |
55 | 57 | ||
56 | struct bfa_iocfc_drvcfg_s { | 58 | struct bfa_iocfc_drvcfg_s { |
@@ -224,18 +226,24 @@ struct bfa_fw_port_physm_stats_s { | |||
224 | 226 | ||
225 | 227 | ||
226 | struct bfa_fw_fip_stats_s { | 228 | struct bfa_fw_fip_stats_s { |
229 | u32 vlan_req; /* vlan discovery requests */ | ||
230 | u32 vlan_notify; /* vlan notifications */ | ||
231 | u32 vlan_err; /* vlan response error */ | ||
232 | u32 vlan_timeouts; /* vlan disvoery timeouts */ | ||
233 | u32 vlan_invalids; /* invalid vlan in discovery advert. */ | ||
227 | u32 disc_req; /* Discovery solicit requests */ | 234 | u32 disc_req; /* Discovery solicit requests */ |
228 | u32 disc_rsp; /* Discovery solicit response */ | 235 | u32 disc_rsp; /* Discovery solicit response */ |
229 | u32 disc_err; /* Discovery advt. parse errors */ | 236 | u32 disc_err; /* Discovery advt. parse errors */ |
230 | u32 disc_unsol; /* Discovery unsolicited */ | 237 | u32 disc_unsol; /* Discovery unsolicited */ |
231 | u32 disc_timeouts; /* Discovery timeouts */ | 238 | u32 disc_timeouts; /* Discovery timeouts */ |
239 | u32 disc_fcf_unavail; /* Discovery FCF Not Avail. */ | ||
232 | u32 linksvc_unsupp; /* Unsupported link service req */ | 240 | u32 linksvc_unsupp; /* Unsupported link service req */ |
233 | u32 linksvc_err; /* Parse error in link service req */ | 241 | u32 linksvc_err; /* Parse error in link service req */ |
234 | u32 logo_req; /* Number of FIP logos received */ | 242 | u32 logo_req; /* Number of FIP logos received */ |
235 | u32 clrvlink_req; /* Clear virtual link req */ | 243 | u32 clrvlink_req; /* Clear virtual link req */ |
236 | u32 op_unsupp; /* Unsupported FIP operation */ | 244 | u32 op_unsupp; /* Unsupported FIP operation */ |
237 | u32 untagged; /* Untagged frames (ignored) */ | 245 | u32 untagged; /* Untagged frames (ignored) */ |
238 | u32 rsvd; | 246 | u32 invalid_version; /*!< Invalid FIP version */ |
239 | }; | 247 | }; |
240 | 248 | ||
241 | 249 | ||
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_lport.h b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h index 7359f82aacfc..0952a139c47c 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_lport.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h | |||
@@ -59,8 +59,8 @@ enum bfa_lport_aen_event { | |||
59 | */ | 59 | */ |
60 | struct bfa_lport_aen_data_s { | 60 | struct bfa_lport_aen_data_s { |
61 | u16 vf_id; /* vf_id of this logical port */ | 61 | u16 vf_id; /* vf_id of this logical port */ |
62 | u16 rsvd; | 62 | s16 roles; /* Logical port mode,IM/TM/IP etc */ |
63 | enum bfa_port_role roles; /* Logical port mode,IM/TM/IP etc */ | 63 | u32 rsvd; |
64 | wwn_t ppwwn; /* WWN of its physical port */ | 64 | wwn_t ppwwn; /* WWN of its physical port */ |
65 | wwn_t lpwwn; /* WWN of this logical port */ | 65 | wwn_t lpwwn; /* WWN of this logical port */ |
66 | }; | 66 | }; |
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h index 13fd4ab6aae2..c5bd9c36ad4d 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h | |||
@@ -22,7 +22,47 @@ | |||
22 | /** | 22 | /** |
23 | * Manufacturing block version | 23 | * Manufacturing block version |
24 | */ | 24 | */ |
25 | #define BFA_MFG_VERSION 1 | 25 | #define BFA_MFG_VERSION 2 |
26 | |||
27 | /** | ||
28 | * Manufacturing block encrypted version | ||
29 | */ | ||
30 | #define BFA_MFG_ENC_VER 2 | ||
31 | |||
32 | /** | ||
33 | * Manufacturing block version 1 length | ||
34 | */ | ||
35 | #define BFA_MFG_VER1_LEN 128 | ||
36 | |||
37 | /** | ||
38 | * Manufacturing block header length | ||
39 | */ | ||
40 | #define BFA_MFG_HDR_LEN 4 | ||
41 | |||
42 | /** | ||
43 | * Checksum size | ||
44 | */ | ||
45 | #define BFA_MFG_CHKSUM_SIZE 16 | ||
46 | |||
47 | /** | ||
48 | * Manufacturing block encrypted version | ||
49 | */ | ||
50 | #define BFA_MFG_ENC_VER 2 | ||
51 | |||
52 | /** | ||
53 | * Manufacturing block version 1 length | ||
54 | */ | ||
55 | #define BFA_MFG_VER1_LEN 128 | ||
56 | |||
57 | /** | ||
58 | * Manufacturing block header length | ||
59 | */ | ||
60 | #define BFA_MFG_HDR_LEN 4 | ||
61 | |||
62 | /** | ||
63 | * Checksum size | ||
64 | */ | ||
65 | #define BFA_MFG_CHKSUM_SIZE 16 | ||
26 | 66 | ||
27 | /** | 67 | /** |
28 | * Manufacturing block format | 68 | * Manufacturing block format |
@@ -30,29 +70,74 @@ | |||
30 | #define BFA_MFG_SERIALNUM_SIZE 11 | 70 | #define BFA_MFG_SERIALNUM_SIZE 11 |
31 | #define BFA_MFG_PARTNUM_SIZE 14 | 71 | #define BFA_MFG_PARTNUM_SIZE 14 |
32 | #define BFA_MFG_SUPPLIER_ID_SIZE 10 | 72 | #define BFA_MFG_SUPPLIER_ID_SIZE 10 |
33 | #define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20 | 73 | #define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20 |
34 | #define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20 | 74 | #define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20 |
35 | #define BFA_MFG_SUPPLIER_REVISION_SIZE 4 | 75 | #define BFA_MFG_SUPPLIER_REVISION_SIZE 4 |
36 | #define STRSZ(_n) (((_n) + 4) & ~3) | 76 | #define STRSZ(_n) (((_n) + 4) & ~3) |
37 | 77 | ||
38 | /** | 78 | /** |
79 | * Manufacturing card type | ||
80 | */ | ||
81 | enum { | ||
82 | BFA_MFG_TYPE_CB_MAX = 825, /* Crossbow card type max */ | ||
83 | BFA_MFG_TYPE_FC8P2 = 825, /* 8G 2port FC card */ | ||
84 | BFA_MFG_TYPE_FC8P1 = 815, /* 8G 1port FC card */ | ||
85 | BFA_MFG_TYPE_FC4P2 = 425, /* 4G 2port FC card */ | ||
86 | BFA_MFG_TYPE_FC4P1 = 415, /* 4G 1port FC card */ | ||
87 | BFA_MFG_TYPE_CNA10P2 = 1020, /* 10G 2port CNA card */ | ||
88 | BFA_MFG_TYPE_CNA10P1 = 1010, /* 10G 1port CNA card */ | ||
89 | }; | ||
90 | |||
91 | #pragma pack(1) | ||
92 | |||
93 | /** | ||
94 | * Card type to port number conversion | ||
95 | */ | ||
96 | #define bfa_mfg_type2port_num(card_type) (((card_type) / 10) % 10) | ||
97 | |||
98 | |||
99 | /** | ||
100 | * All numerical fields are in big-endian format. | ||
101 | */ | ||
102 | struct bfa_mfg_block_s { | ||
103 | }; | ||
104 | |||
105 | /** | ||
39 | * VPD data length | 106 | * VPD data length |
40 | */ | 107 | */ |
41 | #define BFA_MFG_VPD_LEN 256 | 108 | #define BFA_MFG_VPD_LEN 512 |
109 | |||
110 | #define BFA_MFG_VPD_PCI_HDR_OFF 137 | ||
111 | #define BFA_MFG_VPD_PCI_VER_MASK 0x07 /* version mask 3 bits */ | ||
112 | #define BFA_MFG_VPD_PCI_VDR_MASK 0xf8 /* vendor mask 5 bits */ | ||
113 | |||
114 | /** | ||
115 | * VPD vendor tag | ||
116 | */ | ||
117 | enum { | ||
118 | BFA_MFG_VPD_UNKNOWN = 0, /* vendor unknown */ | ||
119 | BFA_MFG_VPD_IBM = 1, /* vendor IBM */ | ||
120 | BFA_MFG_VPD_HP = 2, /* vendor HP */ | ||
121 | BFA_MFG_VPD_DELL = 3, /* vendor DELL */ | ||
122 | BFA_MFG_VPD_PCI_IBM = 0x08, /* PCI VPD IBM */ | ||
123 | BFA_MFG_VPD_PCI_HP = 0x10, /* PCI VPD HP */ | ||
124 | BFA_MFG_VPD_PCI_DELL = 0x20, /* PCI VPD DELL */ | ||
125 | BFA_MFG_VPD_PCI_BRCD = 0xf8, /* PCI VPD Brocade */ | ||
126 | }; | ||
42 | 127 | ||
43 | /** | 128 | /** |
44 | * All numerical fields are in big-endian format. | 129 | * All numerical fields are in big-endian format. |
45 | */ | 130 | */ |
46 | struct bfa_mfg_vpd_s { | 131 | struct bfa_mfg_vpd_s { |
47 | u8 version; /* vpd data version */ | 132 | u8 version; /* vpd data version */ |
48 | u8 vpd_sig[3]; /* characters 'V', 'P', 'D' */ | 133 | u8 vpd_sig[3]; /* characters 'V', 'P', 'D' */ |
49 | u8 chksum; /* u8 checksum */ | 134 | u8 chksum; /* u8 checksum */ |
50 | u8 vendor; /* vendor */ | 135 | u8 vendor; /* vendor */ |
51 | u8 len; /* vpd data length excluding header */ | 136 | u8 len; /* vpd data length excluding header */ |
52 | u8 rsv; | 137 | u8 rsv; |
53 | u8 data[BFA_MFG_VPD_LEN]; /* vpd data */ | 138 | u8 data[BFA_MFG_VPD_LEN]; /* vpd data */ |
54 | }; | 139 | }; |
55 | 140 | ||
56 | #pragma pack(1) | 141 | #pragma pack() |
57 | 142 | ||
58 | #endif /* __BFA_DEFS_MFG_H__ */ | 143 | #endif /* __BFA_DEFS_MFG_H__ */ |
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_port.h b/drivers/scsi/bfa/include/defs/bfa_defs_port.h index de0696c81bc4..501bc9739d9d 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_port.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_port.h | |||
@@ -185,6 +185,8 @@ struct bfa_port_attr_s { | |||
185 | wwn_t fabric_name; /* attached switch's nwwn */ | 185 | wwn_t fabric_name; /* attached switch's nwwn */ |
186 | u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /* attached | 186 | u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /* attached |
187 | * fabric's ip addr */ | 187 | * fabric's ip addr */ |
188 | struct mac_s fpma_mac; /* Lport's FPMA Mac address */ | ||
189 | u16 authfail; /* auth failed state */ | ||
188 | }; | 190 | }; |
189 | 191 | ||
190 | /** | 192 | /** |
@@ -232,14 +234,15 @@ enum bfa_port_aen_sfp_pom { | |||
232 | }; | 234 | }; |
233 | 235 | ||
234 | struct bfa_port_aen_data_s { | 236 | struct bfa_port_aen_data_s { |
235 | enum bfa_ioc_type_e ioc_type; | 237 | wwn_t pwwn; /* WWN of the physical port */ |
236 | wwn_t pwwn; /* WWN of the physical port */ | 238 | wwn_t fwwn; /* WWN of the fabric port */ |
237 | wwn_t fwwn; /* WWN of the fabric port */ | 239 | s32 phy_port_num; /*! For SFP related events */ |
238 | mac_t mac; /* MAC addres of the ethernet port, | 240 | s16 ioc_type; |
239 | * applicable to CNA port only */ | 241 | s16 level; /* Only transitions will |
240 | int phy_port_num; /*! For SFP related events */ | 242 | * be informed */ |
241 | enum bfa_port_aen_sfp_pom level; /* Only transitions will | 243 | struct mac_s mac; /* MAC address of the ethernet port, |
242 | * be informed */ | 244 | * applicable to CNA port only */ |
245 | s16 rsvd; | ||
243 | }; | 246 | }; |
244 | 247 | ||
245 | #endif /* __BFA_DEFS_PORT_H__ */ | 248 | #endif /* __BFA_DEFS_PORT_H__ */ |
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h index bf320412ee24..26e5cc78095d 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h | |||
@@ -232,7 +232,7 @@ struct bfa_pport_attr_s { | |||
232 | u32 pid; /* port ID */ | 232 | u32 pid; /* port ID */ |
233 | enum bfa_pport_type port_type; /* current topology */ | 233 | enum bfa_pport_type port_type; /* current topology */ |
234 | u32 loopback; /* external loopback */ | 234 | u32 loopback; /* external loopback */ |
235 | u32 rsvd1; | 235 | u32 authfail; /* auth fail state */ |
236 | u32 rsvd2; /* padding for 64 bit */ | 236 | u32 rsvd2; /* padding for 64 bit */ |
237 | }; | 237 | }; |
238 | 238 | ||
@@ -240,73 +240,79 @@ struct bfa_pport_attr_s { | |||
240 | * FC Port statistics. | 240 | * FC Port statistics. |
241 | */ | 241 | */ |
242 | struct bfa_pport_fc_stats_s { | 242 | struct bfa_pport_fc_stats_s { |
243 | u64 secs_reset; /* seconds since stats is reset */ | 243 | u64 secs_reset; /* Seconds since stats is reset */ |
244 | u64 tx_frames; /* transmitted frames */ | 244 | u64 tx_frames; /* Tx frames */ |
245 | u64 tx_words; /* transmitted words */ | 245 | u64 tx_words; /* Tx words */ |
246 | u64 rx_frames; /* received frames */ | 246 | u64 tx_lip; /* TX LIP */ |
247 | u64 rx_words; /* received words */ | 247 | u64 tx_nos; /* Tx NOS */ |
248 | u64 lip_count; /* LIPs seen */ | 248 | u64 tx_ols; /* Tx OLS */ |
249 | u64 nos_count; /* NOS count */ | 249 | u64 tx_lr; /* Tx LR */ |
250 | u64 error_frames; /* errored frames (sent?) */ | 250 | u64 tx_lrr; /* Tx LRR */ |
251 | u64 dropped_frames; /* dropped frames */ | 251 | u64 rx_frames; /* Rx frames */ |
252 | u64 link_failures; /* link failure count */ | 252 | u64 rx_words; /* Rx words */ |
253 | u64 loss_of_syncs; /* loss of sync count */ | 253 | u64 lip_count; /* Rx LIP */ |
254 | u64 loss_of_signals;/* loss of signal count */ | 254 | u64 nos_count; /* Rx NOS */ |
255 | u64 primseq_errs; /* primitive sequence protocol */ | 255 | u64 ols_count; /* Rx OLS */ |
256 | u64 bad_os_count; /* invalid ordered set */ | 256 | u64 lr_count; /* Rx LR */ |
257 | u64 err_enc_out; /* Encoding error outside frame */ | 257 | u64 lrr_count; /* Rx LRR */ |
258 | u64 invalid_crcs; /* frames received with invalid CRC*/ | 258 | u64 invalid_crcs; /* Rx CRC err frames */ |
259 | u64 undersized_frm; /* undersized frames */ | 259 | u64 invalid_crc_gd_eof; /* Rx CRC err good EOF frames */ |
260 | u64 oversized_frm; /* oversized frames */ | 260 | u64 undersized_frm; /* Rx undersized frames */ |
261 | u64 bad_eof_frm; /* frames with bad EOF */ | 261 | u64 oversized_frm; /* Rx oversized frames */ |
262 | struct bfa_qos_stats_s qos_stats; /* QoS statistics */ | 262 | u64 bad_eof_frm; /* Rx frames with bad EOF */ |
263 | u64 error_frames; /* Errored frames */ | ||
264 | u64 dropped_frames; /* Dropped frames */ | ||
265 | u64 link_failures; /* Link Failure (LF) count */ | ||
266 | u64 loss_of_syncs; /* Loss of sync count */ | ||
267 | u64 loss_of_signals;/* Loss of signal count */ | ||
268 | u64 primseq_errs; /* Primitive sequence protocol err. */ | ||
269 | u64 bad_os_count; /* Invalid ordered sets */ | ||
270 | u64 err_enc_out; /* Encoding err nonframe_8b10b */ | ||
271 | u64 err_enc; /* Encoding err frame_8b10b */ | ||
263 | }; | 272 | }; |
264 | 273 | ||
265 | /** | 274 | /** |
266 | * Eth Port statistics. | 275 | * Eth Port statistics. |
267 | */ | 276 | */ |
268 | struct bfa_pport_eth_stats_s { | 277 | struct bfa_pport_eth_stats_s { |
269 | u64 secs_reset; /* seconds since stats is reset */ | 278 | u64 secs_reset; /* Seconds since stats is reset */ |
270 | u64 frame_64; /* both rx and tx counter */ | 279 | u64 frame_64; /* Frames 64 bytes */ |
271 | u64 frame_65_127; /* both rx and tx counter */ | 280 | u64 frame_65_127; /* Frames 65-127 bytes */ |
272 | u64 frame_128_255; /* both rx and tx counter */ | 281 | u64 frame_128_255; /* Frames 128-255 bytes */ |
273 | u64 frame_256_511; /* both rx and tx counter */ | 282 | u64 frame_256_511; /* Frames 256-511 bytes */ |
274 | u64 frame_512_1023; /* both rx and tx counter */ | 283 | u64 frame_512_1023; /* Frames 512-1023 bytes */ |
275 | u64 frame_1024_1518; /* both rx and tx counter */ | 284 | u64 frame_1024_1518; /* Frames 1024-1518 bytes */ |
276 | u64 frame_1519_1522; /* both rx and tx counter */ | 285 | u64 frame_1519_1522; /* Frames 1519-1522 bytes */ |
277 | 286 | u64 tx_bytes; /* Tx bytes */ | |
278 | u64 tx_bytes; | 287 | u64 tx_packets; /* Tx packets */ |
279 | u64 tx_packets; | 288 | u64 tx_mcast_packets; /* Tx multicast packets */ |
280 | u64 tx_mcast_packets; | 289 | u64 tx_bcast_packets; /* Tx broadcast packets */ |
281 | u64 tx_bcast_packets; | 290 | u64 tx_control_frame; /* Tx control frame */ |
282 | u64 tx_control_frame; | 291 | u64 tx_drop; /* Tx drops */ |
283 | u64 tx_drop; | 292 | u64 tx_jabber; /* Tx jabber */ |
284 | u64 tx_jabber; | 293 | u64 tx_fcs_error; /* Tx FCS error */ |
285 | u64 tx_fcs_error; | 294 | u64 tx_fragments; /* Tx fragments */ |
286 | u64 tx_fragments; | 295 | u64 rx_bytes; /* Rx bytes */ |
287 | 296 | u64 rx_packets; /* Rx packets */ | |
288 | u64 rx_bytes; | 297 | u64 rx_mcast_packets; /* Rx multicast packets */ |
289 | u64 rx_packets; | 298 | u64 rx_bcast_packets; /* Rx broadcast packets */ |
290 | u64 rx_mcast_packets; | 299 | u64 rx_control_frames; /* Rx control frames */ |
291 | u64 rx_bcast_packets; | 300 | u64 rx_unknown_opcode; /* Rx unknown opcode */ |
292 | u64 rx_control_frames; | 301 | u64 rx_drop; /* Rx drops */ |
293 | u64 rx_unknown_opcode; | 302 | u64 rx_jabber; /* Rx jabber */ |
294 | u64 rx_drop; | 303 | u64 rx_fcs_error; /* Rx FCS errors */ |
295 | u64 rx_jabber; | 304 | u64 rx_alignment_error; /* Rx alignment errors */ |
296 | u64 rx_fcs_error; | 305 | u64 rx_frame_length_error; /* Rx frame len errors */ |
297 | u64 rx_alignment_error; | 306 | u64 rx_code_error; /* Rx code errors */ |
298 | u64 rx_frame_length_error; | 307 | u64 rx_fragments; /* Rx fragments */ |
299 | u64 rx_code_error; | 308 | u64 rx_pause; /* Rx pause */ |
300 | u64 rx_fragments; | 309 | u64 rx_zero_pause; /* Rx zero pause */ |
301 | 310 | u64 tx_pause; /* Tx pause */ | |
302 | u64 rx_pause; /* BPC */ | 311 | u64 tx_zero_pause; /* Tx zero pause */ |
303 | u64 rx_zero_pause; /* BPC Pause cancellation */ | 312 | u64 rx_fcoe_pause; /* Rx fcoe pause */ |
304 | u64 tx_pause; /* BPC */ | 313 | u64 rx_fcoe_zero_pause; /* Rx FCoE zero pause */ |
305 | u64 tx_zero_pause; /* BPC Pause cancellation */ | 314 | u64 tx_fcoe_pause; /* Tx FCoE pause */ |
306 | u64 rx_fcoe_pause; /* BPC */ | 315 | u64 tx_fcoe_zero_pause; /* Tx FCoE zero pause */ |
307 | u64 rx_fcoe_zero_pause; /* BPC Pause cancellation */ | ||
308 | u64 tx_fcoe_pause; /* BPC */ | ||
309 | u64 tx_fcoe_zero_pause; /* BPC Pause cancellation */ | ||
310 | }; | 316 | }; |
311 | 317 | ||
312 | /** | 318 | /** |
@@ -333,8 +339,7 @@ struct bfa_pport_fcpmap_s { | |||
333 | }; | 339 | }; |
334 | 340 | ||
335 | /** | 341 | /** |
336 | * Port RNID info. | 342 | * Port RNI */ |
337 | */ | ||
338 | struct bfa_pport_rnid_s { | 343 | struct bfa_pport_rnid_s { |
339 | wwn_t wwn; | 344 | wwn_t wwn; |
340 | u32 unittype; | 345 | u32 unittype; |
@@ -347,6 +352,23 @@ struct bfa_pport_rnid_s { | |||
347 | u16 topologydiscoveryflags; | 352 | u16 topologydiscoveryflags; |
348 | }; | 353 | }; |
349 | 354 | ||
355 | struct bfa_fcport_fcf_s { | ||
356 | wwn_t name; /* FCF name */ | ||
357 | wwn_t fabric_name; /* Fabric Name */ | ||
358 | u8 fipenabled; /* FIP enabled or not */ | ||
359 | u8 fipfailed; /* FIP failed or not */ | ||
360 | u8 resv[2]; | ||
361 | u8 pri; /* FCF priority */ | ||
362 | u8 version; /* FIP version used */ | ||
363 | u8 available; /* Available for login */ | ||
364 | u8 fka_disabled; /* FKA is disabled */ | ||
365 | u8 maxsz_verified; /* FCoE max size verified */ | ||
366 | u8 fc_map[3]; /* FC map */ | ||
367 | u16 vlan; /* FCoE vlan tag/priority */ | ||
368 | u32 fka_adv_per; /* FIP ka advert. period */ | ||
369 | struct mac_s mac; /* FCF mac */ | ||
370 | }; | ||
371 | |||
350 | /** | 372 | /** |
351 | * Link state information | 373 | * Link state information |
352 | */ | 374 | */ |
@@ -378,6 +400,7 @@ struct bfa_pport_link_s { | |||
378 | struct fc_alpabm_s alpabm; /* alpa bitmap */ | 400 | struct fc_alpabm_s alpabm; /* alpa bitmap */ |
379 | } loop_info; | 401 | } loop_info; |
380 | } tl; | 402 | } tl; |
403 | struct bfa_fcport_fcf_s fcf; /*!< FCF information (for FCoE) */ | ||
381 | }; | 404 | }; |
382 | 405 | ||
383 | #endif /* __BFA_DEFS_PPORT_H__ */ | 406 | #endif /* __BFA_DEFS_PPORT_H__ */ |
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_status.h b/drivers/scsi/bfa/include/defs/bfa_defs_status.h index cdceaeb9f4b8..4374494bd566 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_status.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_status.h | |||
@@ -180,8 +180,8 @@ enum bfa_status { | |||
180 | BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, /* Given adapter is part | 180 | BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, /* Given adapter is part |
181 | * of another team */ | 181 | * of another team */ |
182 | BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, /* Adapter has VLANs configured. | 182 | BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, /* Adapter has VLANs configured. |
183 | * Delete all VLANs before | 183 | * Delete all VLANs to become |
184 | * creating team */ | 184 | * part of the team */ |
185 | BFA_STATUS_IM_PVID_MISMATCH = 116, /* Mismatching PVIDs configured | 185 | BFA_STATUS_IM_PVID_MISMATCH = 116, /* Mismatching PVIDs configured |
186 | * for adapters */ | 186 | * for adapters */ |
187 | BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, /* Mismatching link speeds | 187 | BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, /* Mismatching link speeds |
@@ -213,7 +213,7 @@ enum bfa_status { | |||
213 | * loaded */ | 213 | * loaded */ |
214 | BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */ | 214 | BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */ |
215 | BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */ | 215 | BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */ |
216 | BFA_STATUS_NO_DRIVER = 133, /* Storage/Ethernet driver not loaded */ | 216 | BFA_STATUS_NO_DRIVER = 133, /* Brocade adapter/driver not installed or loaded */ |
217 | BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */ | 217 | BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */ |
218 | BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */ | 218 | BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */ |
219 | BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */ | 219 | BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */ |
@@ -228,8 +228,7 @@ enum bfa_status { | |||
228 | BFA_STATUS_IM_GET_INETCFG_FAILED = 142, /* Acquiring Network Subsytem | 228 | BFA_STATUS_IM_GET_INETCFG_FAILED = 142, /* Acquiring Network Subsytem |
229 | * handle Failed. Please try | 229 | * handle Failed. Please try |
230 | * after some time */ | 230 | * after some time */ |
231 | BFA_STATUS_IM_NOT_BOUND = 143, /* Brocade 10G Ethernet Service is not | 231 | BFA_STATUS_IM_NOT_BOUND = 143, /* IM driver is not active */ |
232 | * Enabled on this port */ | ||
233 | BFA_STATUS_INSUFFICIENT_PERMS = 144, /* User doesn't have sufficient | 232 | BFA_STATUS_INSUFFICIENT_PERMS = 144, /* User doesn't have sufficient |
234 | * permissions to execute the BCU | 233 | * permissions to execute the BCU |
235 | * application */ | 234 | * application */ |
@@ -242,6 +241,14 @@ enum bfa_status { | |||
242 | * failed */ | 241 | * failed */ |
243 | BFA_STATUS_IM_UNBIND_FAILED = 149, /* ! < IM Driver unbind operation | 242 | BFA_STATUS_IM_UNBIND_FAILED = 149, /* ! < IM Driver unbind operation |
244 | * failed */ | 243 | * failed */ |
244 | BFA_STATUS_IM_PORT_IN_TEAM = 150, /* Port is already part of the | ||
245 | * team */ | ||
246 | BFA_STATUS_IM_VLAN_NOT_FOUND = 151, /* VLAN ID doesn't exists */ | ||
247 | BFA_STATUS_IM_TEAM_NOT_FOUND = 152, /* Teaming configuration doesn't | ||
248 | * exists */ | ||
249 | BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153, /* Given settings are not | ||
250 | * allowed for the current | ||
251 | * Teaming mode */ | ||
245 | BFA_STATUS_MAX_VAL /* Unknown error code */ | 252 | BFA_STATUS_MAX_VAL /* Unknown error code */ |
246 | }; | 253 | }; |
247 | #define bfa_status_t enum bfa_status | 254 | #define bfa_status_t enum bfa_status |
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h index a6c70aee0aa3..52585d3dd891 100644 --- a/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h +++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h | |||
@@ -70,7 +70,6 @@ void bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv); | |||
70 | */ | 70 | */ |
71 | void bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv); | 71 | void bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv); |
72 | 72 | ||
73 | void bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim_drv); | ||
74 | void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim_drv); | 73 | void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim_drv); |
75 | 74 | ||
76 | #endif /* __BFAD_FCB_FCPIM_H__ */ | 75 | #endif /* __BFAD_FCB_FCPIM_H__ */ |
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs.h b/drivers/scsi/bfa/include/fcs/bfa_fcs.h index 627669c65546..f2fd35fdee28 100644 --- a/drivers/scsi/bfa/include/fcs/bfa_fcs.h +++ b/drivers/scsi/bfa/include/fcs/bfa_fcs.h | |||
@@ -49,6 +49,7 @@ struct bfa_fcs_s { | |||
49 | struct bfa_trc_mod_s *trcmod; /* tracing module */ | 49 | struct bfa_trc_mod_s *trcmod; /* tracing module */ |
50 | struct bfa_aen_s *aen; /* aen component */ | 50 | struct bfa_aen_s *aen; /* aen component */ |
51 | bfa_boolean_t vf_enabled; /* VF mode is enabled */ | 51 | bfa_boolean_t vf_enabled; /* VF mode is enabled */ |
52 | bfa_boolean_t fdmi_enabled; /*!< FDMI is enabled */ | ||
52 | bfa_boolean_t min_cfg; /* min cfg enabled/disabled */ | 53 | bfa_boolean_t min_cfg; /* min cfg enabled/disabled */ |
53 | u16 port_vfid; /* port default VF ID */ | 54 | u16 port_vfid; /* port default VF ID */ |
54 | struct bfa_fcs_driver_info_s driver_info; | 55 | struct bfa_fcs_driver_info_s driver_info; |
@@ -60,10 +61,12 @@ struct bfa_fcs_s { | |||
60 | /* | 61 | /* |
61 | * bfa fcs API functions | 62 | * bfa fcs API functions |
62 | */ | 63 | */ |
63 | void bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, | 64 | void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, |
64 | bfa_boolean_t min_cfg); | 65 | bfa_boolean_t min_cfg); |
66 | void bfa_fcs_init(struct bfa_fcs_s *fcs); | ||
65 | void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, | 67 | void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, |
66 | struct bfa_fcs_driver_info_s *driver_info); | 68 | struct bfa_fcs_driver_info_s *driver_info); |
69 | void bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable); | ||
67 | void bfa_fcs_exit(struct bfa_fcs_s *fcs); | 70 | void bfa_fcs_exit(struct bfa_fcs_s *fcs); |
68 | void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod); | 71 | void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod); |
69 | void bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod); | 72 | void bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod); |
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h index 967ceb0eb074..ceaefd3060f4 100644 --- a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h +++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h | |||
@@ -34,14 +34,6 @@ struct bfa_fcs_s; | |||
34 | struct bfa_fcs_fabric_s; | 34 | struct bfa_fcs_fabric_s; |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * @todo : need to move to a global config file. | ||
38 | * Maximum Vports supported per physical port or vf. | ||
39 | */ | ||
40 | #define BFA_FCS_MAX_VPORTS_SUPP_CB 255 | ||
41 | #define BFA_FCS_MAX_VPORTS_SUPP_CT 191 | ||
42 | |||
43 | /* | ||
44 | * @todo : need to move to a global config file. | ||
45 | * Maximum Rports supported per port (physical/logical). | 37 | * Maximum Rports supported per port (physical/logical). |
46 | */ | 38 | */ |
47 | #define BFA_FCS_MAX_RPORTS_SUPP 256 /* @todo : tentative value */ | 39 | #define BFA_FCS_MAX_RPORTS_SUPP 256 /* @todo : tentative value */ |
diff --git a/drivers/scsi/bfa/include/log/bfa_log_hal.h b/drivers/scsi/bfa/include/log/bfa_log_hal.h index 0412aea2ec30..5f8f5e30b9e8 100644 --- a/drivers/scsi/bfa/include/log/bfa_log_hal.h +++ b/drivers/scsi/bfa/include/log/bfa_log_hal.h | |||
@@ -27,4 +27,10 @@ | |||
27 | (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 3) | 27 | (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 3) |
28 | #define BFA_LOG_HAL_SM_ASSERT \ | 28 | #define BFA_LOG_HAL_SM_ASSERT \ |
29 | (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 4) | 29 | (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 4) |
30 | #define BFA_LOG_HAL_DRIVER_ERROR \ | ||
31 | (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 5) | ||
32 | #define BFA_LOG_HAL_DRIVER_CONFIG_ERROR \ | ||
33 | (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 6) | ||
34 | #define BFA_LOG_HAL_MBOX_ERROR \ | ||
35 | (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 7) | ||
30 | #endif | 36 | #endif |
diff --git a/drivers/scsi/bfa/include/log/bfa_log_linux.h b/drivers/scsi/bfa/include/log/bfa_log_linux.h index 317c0547ee16..bd451db4c30a 100644 --- a/drivers/scsi/bfa/include/log/bfa_log_linux.h +++ b/drivers/scsi/bfa/include/log/bfa_log_linux.h | |||
@@ -41,4 +41,20 @@ | |||
41 | (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 10) | 41 | (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 10) |
42 | #define BFA_LOG_LINUX_SCSI_ABORT_COMP \ | 42 | #define BFA_LOG_LINUX_SCSI_ABORT_COMP \ |
43 | (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 11) | 43 | (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 11) |
44 | #define BFA_LOG_LINUX_DRIVER_CONFIG_ERROR \ | ||
45 | (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 12) | ||
46 | #define BFA_LOG_LINUX_BNA_STATE_MACHINE \ | ||
47 | (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 13) | ||
48 | #define BFA_LOG_LINUX_IOC_ERROR \ | ||
49 | (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 14) | ||
50 | #define BFA_LOG_LINUX_RESOURCE_ALLOC_ERROR \ | ||
51 | (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 15) | ||
52 | #define BFA_LOG_LINUX_RING_BUFFER_ERROR \ | ||
53 | (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 16) | ||
54 | #define BFA_LOG_LINUX_DRIVER_ERROR \ | ||
55 | (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 17) | ||
56 | #define BFA_LOG_LINUX_DRIVER_DIAG \ | ||
57 | (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 18) | ||
58 | #define BFA_LOG_LINUX_DRIVER_AEN \ | ||
59 | (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 19) | ||
44 | #endif | 60 | #endif |
diff --git a/drivers/scsi/bfa/include/protocol/fc.h b/drivers/scsi/bfa/include/protocol/fc.h index 14969eecf6a9..8d1038035a76 100644 --- a/drivers/scsi/bfa/include/protocol/fc.h +++ b/drivers/scsi/bfa/include/protocol/fc.h | |||
@@ -50,6 +50,11 @@ struct fchs_s { | |||
50 | 50 | ||
51 | u32 ro; /* relative offset */ | 51 | u32 ro; /* relative offset */ |
52 | }; | 52 | }; |
53 | |||
54 | #define FC_SOF_LEN 4 | ||
55 | #define FC_EOF_LEN 4 | ||
56 | #define FC_CRC_LEN 4 | ||
57 | |||
53 | /* | 58 | /* |
54 | * Fibre Channel BB_E Header Structure | 59 | * Fibre Channel BB_E Header Structure |
55 | */ | 60 | */ |
diff --git a/drivers/scsi/bfa/include/protocol/pcifw.h b/drivers/scsi/bfa/include/protocol/pcifw.h deleted file mode 100644 index 6830dc3ee58a..000000000000 --- a/drivers/scsi/bfa/include/protocol/pcifw.h +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. | ||
3 | * All rights reserved | ||
4 | * www.brocade.com | ||
5 | * | ||
6 | * Linux driver for Brocade Fibre Channel Host Bus Adapter. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License (GPL) Version 2 as | ||
10 | * published by the Free Software Foundation | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | /** | ||
19 | * pcifw.h PCI FW related headers | ||
20 | */ | ||
21 | |||
22 | #ifndef __PCIFW_H__ | ||
23 | #define __PCIFW_H__ | ||
24 | |||
25 | #pragma pack(1) | ||
26 | |||
27 | struct pnp_hdr_s{ | ||
28 | u32 signature; /* "$PnP" */ | ||
29 | u8 rev; /* Struct revision */ | ||
30 | u8 len; /* Header structure len in multiples | ||
31 | * of 16 bytes */ | ||
32 | u16 off; /* Offset to next header 00 if none */ | ||
33 | u8 rsvd; /* Reserved byte */ | ||
34 | u8 cksum; /* 8-bit checksum for this header */ | ||
35 | u32 pnp_dev_id; /* PnP Device Id */ | ||
36 | u16 mfstr; /* Pointer to manufacturer string */ | ||
37 | u16 prstr; /* Pointer to product string */ | ||
38 | u8 devtype[3]; /* Device Type Code */ | ||
39 | u8 devind; /* Device Indicator */ | ||
40 | u16 bcventr; /* Bootstrap entry vector */ | ||
41 | u16 rsvd2; /* Reserved */ | ||
42 | u16 sriv; /* Static resource information vector */ | ||
43 | }; | ||
44 | |||
45 | struct pci_3_0_ds_s{ | ||
46 | u32 sig; /* Signature "PCIR" */ | ||
47 | u16 vendid; /* Vendor ID */ | ||
48 | u16 devid; /* Device ID */ | ||
49 | u16 devlistoff; /* Device List Offset */ | ||
50 | u16 len; /* PCI Data Structure Length */ | ||
51 | u8 rev; /* PCI Data Structure Revision */ | ||
52 | u8 clcode[3]; /* Class Code */ | ||
53 | u16 imglen; /* Code image length in multiples of | ||
54 | * 512 bytes */ | ||
55 | u16 coderev; /* Revision level of code/data */ | ||
56 | u8 codetype; /* Code type 0x00 - BIOS */ | ||
57 | u8 indr; /* Last image indicator */ | ||
58 | u16 mrtimglen; /* Max Run Time Image Length */ | ||
59 | u16 cuoff; /* Config Utility Code Header Offset */ | ||
60 | u16 dmtfclp; /* DMTF CLP entry point offset */ | ||
61 | }; | ||
62 | |||
63 | struct pci_optrom_hdr_s{ | ||
64 | u16 sig; /* Signature 0x55AA */ | ||
65 | u8 len; /* Option ROM length in units of 512 bytes */ | ||
66 | u8 inivec[3]; /* Initialization vector */ | ||
67 | u8 rsvd[16]; /* Reserved field */ | ||
68 | u16 verptr; /* Pointer to version string - private */ | ||
69 | u16 pcids; /* Pointer to PCI data structure */ | ||
70 | u16 pnphdr; /* Pointer to PnP expansion header */ | ||
71 | }; | ||
72 | |||
73 | #pragma pack() | ||
74 | |||
75 | #endif | ||
diff --git a/drivers/scsi/bfa/loop.c b/drivers/scsi/bfa/loop.c index f7c7f4f3c640..f6342efb6a90 100644 --- a/drivers/scsi/bfa/loop.c +++ b/drivers/scsi/bfa/loop.c | |||
@@ -162,7 +162,7 @@ bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port, u8 alpa) | |||
162 | len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa, | 162 | len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa, |
163 | bfa_fcs_port_get_fcid(port), 0, | 163 | bfa_fcs_port_get_fcid(port), 0, |
164 | port->port_cfg.pwwn, port->port_cfg.nwwn, | 164 | port->port_cfg.pwwn, port->port_cfg.nwwn, |
165 | bfa_pport_get_maxfrsize(port->fcs->bfa)); | 165 | bfa_fcport_get_maxfrsize(port->fcs->bfa)); |
166 | 166 | ||
167 | bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, | 167 | bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, |
168 | FC_CLASS_3, len, &fchs, | 168 | FC_CLASS_3, len, &fchs, |
diff --git a/drivers/scsi/bfa/lport_api.c b/drivers/scsi/bfa/lport_api.c index 1e06792cd4c2..d3907d184e2b 100644 --- a/drivers/scsi/bfa/lport_api.c +++ b/drivers/scsi/bfa/lport_api.c | |||
@@ -156,7 +156,7 @@ bfa_fcs_port_get_rport_max_speed(struct bfa_fcs_port_s *port) | |||
156 | /* | 156 | /* |
157 | * Get Physical port's current speed | 157 | * Get Physical port's current speed |
158 | */ | 158 | */ |
159 | bfa_pport_get_attr(port->fcs->bfa, &pport_attr); | 159 | bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); |
160 | pport_speed = pport_attr.speed; | 160 | pport_speed = pport_attr.speed; |
161 | bfa_trc(fcs, pport_speed); | 161 | bfa_trc(fcs, pport_speed); |
162 | 162 | ||
@@ -235,7 +235,8 @@ bfa_fcs_port_get_info(struct bfa_fcs_port_s *port, | |||
235 | port_info->port_wwn = bfa_fcs_port_get_pwwn(port); | 235 | port_info->port_wwn = bfa_fcs_port_get_pwwn(port); |
236 | port_info->node_wwn = bfa_fcs_port_get_nwwn(port); | 236 | port_info->node_wwn = bfa_fcs_port_get_nwwn(port); |
237 | 237 | ||
238 | port_info->max_vports_supp = bfa_fcs_vport_get_max(port->fcs); | 238 | port_info->max_vports_supp = |
239 | bfa_lps_get_max_vport(port->fcs->bfa); | ||
239 | port_info->num_vports_inuse = | 240 | port_info->num_vports_inuse = |
240 | bfa_fcs_fabric_vport_count(port->fabric); | 241 | bfa_fcs_fabric_vport_count(port->fabric); |
241 | port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP; | 242 | port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP; |
diff --git a/drivers/scsi/bfa/ms.c b/drivers/scsi/bfa/ms.c index c96b3ca007ae..5e8c8dee6c97 100644 --- a/drivers/scsi/bfa/ms.c +++ b/drivers/scsi/bfa/ms.c | |||
@@ -118,7 +118,7 @@ bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms, | |||
118 | break; | 118 | break; |
119 | 119 | ||
120 | default: | 120 | default: |
121 | bfa_assert(0); | 121 | bfa_sm_fault(ms->port->fcs, event); |
122 | } | 122 | } |
123 | } | 123 | } |
124 | 124 | ||
@@ -141,7 +141,7 @@ bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms, | |||
141 | break; | 141 | break; |
142 | 142 | ||
143 | default: | 143 | default: |
144 | bfa_assert(0); | 144 | bfa_sm_fault(ms->port->fcs, event); |
145 | } | 145 | } |
146 | } | 146 | } |
147 | 147 | ||
@@ -190,7 +190,7 @@ bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event) | |||
190 | break; | 190 | break; |
191 | 191 | ||
192 | default: | 192 | default: |
193 | bfa_assert(0); | 193 | bfa_sm_fault(ms->port->fcs, event); |
194 | } | 194 | } |
195 | } | 195 | } |
196 | 196 | ||
@@ -216,7 +216,7 @@ bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms, | |||
216 | break; | 216 | break; |
217 | 217 | ||
218 | default: | 218 | default: |
219 | bfa_assert(0); | 219 | bfa_sm_fault(ms->port->fcs, event); |
220 | } | 220 | } |
221 | } | 221 | } |
222 | 222 | ||
@@ -230,10 +230,6 @@ bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms, | |||
230 | switch (event) { | 230 | switch (event) { |
231 | case MSSM_EVENT_PORT_OFFLINE: | 231 | case MSSM_EVENT_PORT_OFFLINE: |
232 | bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); | 232 | bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); |
233 | /* | ||
234 | * now invoke MS related sub-modules | ||
235 | */ | ||
236 | bfa_fcs_port_fdmi_offline(ms); | ||
237 | break; | 233 | break; |
238 | 234 | ||
239 | case MSSM_EVENT_PORT_FABRIC_RSCN: | 235 | case MSSM_EVENT_PORT_FABRIC_RSCN: |
@@ -243,7 +239,7 @@ bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms, | |||
243 | break; | 239 | break; |
244 | 240 | ||
245 | default: | 241 | default: |
246 | bfa_assert(0); | 242 | bfa_sm_fault(ms->port->fcs, event); |
247 | } | 243 | } |
248 | } | 244 | } |
249 | 245 | ||
@@ -266,7 +262,7 @@ bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms, | |||
266 | break; | 262 | break; |
267 | 263 | ||
268 | default: | 264 | default: |
269 | bfa_assert(0); | 265 | bfa_sm_fault(ms->port->fcs, event); |
270 | } | 266 | } |
271 | } | 267 | } |
272 | 268 | ||
@@ -304,7 +300,7 @@ bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event) | |||
304 | break; | 300 | break; |
305 | 301 | ||
306 | default: | 302 | default: |
307 | bfa_assert(0); | 303 | bfa_sm_fault(ms->port->fcs, event); |
308 | } | 304 | } |
309 | } | 305 | } |
310 | 306 | ||
@@ -330,7 +326,7 @@ bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms, | |||
330 | break; | 326 | break; |
331 | 327 | ||
332 | default: | 328 | default: |
333 | bfa_assert(0); | 329 | bfa_sm_fault(ms->port->fcs, event); |
334 | } | 330 | } |
335 | } | 331 | } |
336 | 332 | ||
@@ -466,7 +462,7 @@ bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms, | |||
466 | break; | 462 | break; |
467 | 463 | ||
468 | default: | 464 | default: |
469 | bfa_assert(0); | 465 | bfa_sm_fault(ms->port->fcs, event); |
470 | } | 466 | } |
471 | } | 467 | } |
472 | 468 | ||
@@ -502,7 +498,7 @@ bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event) | |||
502 | break; | 498 | break; |
503 | 499 | ||
504 | default: | 500 | default: |
505 | bfa_assert(0); | 501 | bfa_sm_fault(ms->port->fcs, event); |
506 | } | 502 | } |
507 | } | 503 | } |
508 | 504 | ||
@@ -528,7 +524,7 @@ bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms, | |||
528 | break; | 524 | break; |
529 | 525 | ||
530 | default: | 526 | default: |
531 | bfa_assert(0); | 527 | bfa_sm_fault(ms->port->fcs, event); |
532 | } | 528 | } |
533 | } | 529 | } |
534 | 530 | ||
@@ -637,7 +633,7 @@ bfa_fcs_port_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) | |||
637 | bfa_os_hton3b(FC_MGMT_SERVER), | 633 | bfa_os_hton3b(FC_MGMT_SERVER), |
638 | bfa_fcs_port_get_fcid(port), 0, | 634 | bfa_fcs_port_get_fcid(port), 0, |
639 | port->port_cfg.pwwn, port->port_cfg.nwwn, | 635 | port->port_cfg.pwwn, port->port_cfg.nwwn, |
640 | bfa_pport_get_maxfrsize(port->fcs->bfa)); | 636 | bfa_fcport_get_maxfrsize(port->fcs->bfa)); |
641 | 637 | ||
642 | bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, | 638 | bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, |
643 | FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response, | 639 | FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response, |
@@ -735,6 +731,7 @@ bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port) | |||
735 | 731 | ||
736 | ms->port = port; | 732 | ms->port = port; |
737 | bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE); | 733 | bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE); |
734 | bfa_fcs_port_fdmi_offline(ms); | ||
738 | } | 735 | } |
739 | 736 | ||
740 | void | 737 | void |
diff --git a/drivers/scsi/bfa/ns.c b/drivers/scsi/bfa/ns.c index 2f8b880060bb..d20dd7e15742 100644 --- a/drivers/scsi/bfa/ns.c +++ b/drivers/scsi/bfa/ns.c | |||
@@ -164,7 +164,7 @@ bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns, | |||
164 | break; | 164 | break; |
165 | 165 | ||
166 | default: | 166 | default: |
167 | bfa_assert(0); | 167 | bfa_sm_fault(ns->port->fcs, event); |
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
@@ -187,7 +187,7 @@ bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns, | |||
187 | break; | 187 | break; |
188 | 188 | ||
189 | default: | 189 | default: |
190 | bfa_assert(0); | 190 | bfa_sm_fault(ns->port->fcs, event); |
191 | } | 191 | } |
192 | } | 192 | } |
193 | 193 | ||
@@ -221,7 +221,7 @@ bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns, | |||
221 | break; | 221 | break; |
222 | 222 | ||
223 | default: | 223 | default: |
224 | bfa_assert(0); | 224 | bfa_sm_fault(ns->port->fcs, event); |
225 | } | 225 | } |
226 | } | 226 | } |
227 | 227 | ||
@@ -247,7 +247,7 @@ bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns, | |||
247 | break; | 247 | break; |
248 | 248 | ||
249 | default: | 249 | default: |
250 | bfa_assert(0); | 250 | bfa_sm_fault(ns->port->fcs, event); |
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
@@ -270,7 +270,7 @@ bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns, | |||
270 | break; | 270 | break; |
271 | 271 | ||
272 | default: | 272 | default: |
273 | bfa_assert(0); | 273 | bfa_sm_fault(ns->port->fcs, event); |
274 | } | 274 | } |
275 | } | 275 | } |
276 | 276 | ||
@@ -304,7 +304,7 @@ bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns, | |||
304 | break; | 304 | break; |
305 | 305 | ||
306 | default: | 306 | default: |
307 | bfa_assert(0); | 307 | bfa_sm_fault(ns->port->fcs, event); |
308 | } | 308 | } |
309 | } | 309 | } |
310 | 310 | ||
@@ -330,7 +330,7 @@ bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns, | |||
330 | break; | 330 | break; |
331 | 331 | ||
332 | default: | 332 | default: |
333 | bfa_assert(0); | 333 | bfa_sm_fault(ns->port->fcs, event); |
334 | } | 334 | } |
335 | } | 335 | } |
336 | 336 | ||
@@ -353,7 +353,7 @@ bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns, | |||
353 | break; | 353 | break; |
354 | 354 | ||
355 | default: | 355 | default: |
356 | bfa_assert(0); | 356 | bfa_sm_fault(ns->port->fcs, event); |
357 | } | 357 | } |
358 | } | 358 | } |
359 | 359 | ||
@@ -390,7 +390,7 @@ bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns, | |||
390 | break; | 390 | break; |
391 | 391 | ||
392 | default: | 392 | default: |
393 | bfa_assert(0); | 393 | bfa_sm_fault(ns->port->fcs, event); |
394 | } | 394 | } |
395 | } | 395 | } |
396 | 396 | ||
@@ -413,7 +413,7 @@ bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns, | |||
413 | break; | 413 | break; |
414 | 414 | ||
415 | default: | 415 | default: |
416 | bfa_assert(0); | 416 | bfa_sm_fault(ns->port->fcs, event); |
417 | } | 417 | } |
418 | } | 418 | } |
419 | 419 | ||
@@ -436,7 +436,7 @@ bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns, | |||
436 | break; | 436 | break; |
437 | 437 | ||
438 | default: | 438 | default: |
439 | bfa_assert(0); | 439 | bfa_sm_fault(ns->port->fcs, event); |
440 | } | 440 | } |
441 | } | 441 | } |
442 | 442 | ||
@@ -494,7 +494,7 @@ bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns, | |||
494 | break; | 494 | break; |
495 | 495 | ||
496 | default: | 496 | default: |
497 | bfa_assert(0); | 497 | bfa_sm_fault(ns->port->fcs, event); |
498 | } | 498 | } |
499 | } | 499 | } |
500 | 500 | ||
@@ -517,7 +517,7 @@ bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns, | |||
517 | break; | 517 | break; |
518 | 518 | ||
519 | default: | 519 | default: |
520 | bfa_assert(0); | 520 | bfa_sm_fault(ns->port->fcs, event); |
521 | } | 521 | } |
522 | } | 522 | } |
523 | static void | 523 | static void |
@@ -539,7 +539,7 @@ bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns, | |||
539 | break; | 539 | break; |
540 | 540 | ||
541 | default: | 541 | default: |
542 | bfa_assert(0); | 542 | bfa_sm_fault(ns->port->fcs, event); |
543 | } | 543 | } |
544 | } | 544 | } |
545 | 545 | ||
@@ -575,7 +575,7 @@ bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns, | |||
575 | break; | 575 | break; |
576 | 576 | ||
577 | default: | 577 | default: |
578 | bfa_assert(0); | 578 | bfa_sm_fault(ns->port->fcs, event); |
579 | } | 579 | } |
580 | } | 580 | } |
581 | 581 | ||
@@ -598,7 +598,7 @@ bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns, | |||
598 | break; | 598 | break; |
599 | 599 | ||
600 | default: | 600 | default: |
601 | bfa_assert(0); | 601 | bfa_sm_fault(ns->port->fcs, event); |
602 | } | 602 | } |
603 | } | 603 | } |
604 | 604 | ||
@@ -626,7 +626,7 @@ bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns, | |||
626 | break; | 626 | break; |
627 | 627 | ||
628 | default: | 628 | default: |
629 | bfa_assert(0); | 629 | bfa_sm_fault(ns->port->fcs, event); |
630 | } | 630 | } |
631 | } | 631 | } |
632 | 632 | ||
@@ -660,7 +660,7 @@ bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) | |||
660 | bfa_os_hton3b(FC_NAME_SERVER), | 660 | bfa_os_hton3b(FC_NAME_SERVER), |
661 | bfa_fcs_port_get_fcid(port), 0, | 661 | bfa_fcs_port_get_fcid(port), 0, |
662 | port->port_cfg.pwwn, port->port_cfg.nwwn, | 662 | port->port_cfg.pwwn, port->port_cfg.nwwn, |
663 | bfa_pport_get_maxfrsize(port->fcs->bfa)); | 663 | bfa_fcport_get_maxfrsize(port->fcs->bfa)); |
664 | 664 | ||
665 | bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, | 665 | bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, |
666 | FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response, | 666 | FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response, |
diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c index 9cf58bb138dc..8e73dd9a625a 100644 --- a/drivers/scsi/bfa/rport.c +++ b/drivers/scsi/bfa/rport.c | |||
@@ -224,7 +224,7 @@ bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
224 | break; | 224 | break; |
225 | 225 | ||
226 | default: | 226 | default: |
227 | bfa_assert(0); | 227 | bfa_sm_fault(rport->fcs, event); |
228 | } | 228 | } |
229 | } | 229 | } |
230 | 230 | ||
@@ -276,7 +276,7 @@ bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport, | |||
276 | break; | 276 | break; |
277 | 277 | ||
278 | default: | 278 | default: |
279 | bfa_assert(0); | 279 | bfa_sm_fault(rport->fcs, event); |
280 | } | 280 | } |
281 | } | 281 | } |
282 | 282 | ||
@@ -332,7 +332,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport, | |||
332 | break; | 332 | break; |
333 | 333 | ||
334 | default: | 334 | default: |
335 | bfa_assert(0); | 335 | bfa_sm_fault(rport->fcs, event); |
336 | } | 336 | } |
337 | } | 337 | } |
338 | 338 | ||
@@ -406,7 +406,7 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport, | |||
406 | break; | 406 | break; |
407 | 407 | ||
408 | default: | 408 | default: |
409 | bfa_assert(0); | 409 | bfa_sm_fault(rport->fcs, event); |
410 | } | 410 | } |
411 | } | 411 | } |
412 | 412 | ||
@@ -481,7 +481,7 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
481 | break; | 481 | break; |
482 | 482 | ||
483 | default: | 483 | default: |
484 | bfa_assert(0); | 484 | bfa_sm_fault(rport->fcs, event); |
485 | } | 485 | } |
486 | } | 486 | } |
487 | 487 | ||
@@ -534,7 +534,7 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, | |||
534 | break; | 534 | break; |
535 | 535 | ||
536 | default: | 536 | default: |
537 | bfa_assert(0); | 537 | bfa_sm_fault(rport->fcs, event); |
538 | } | 538 | } |
539 | } | 539 | } |
540 | 540 | ||
@@ -589,7 +589,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
589 | break; | 589 | break; |
590 | 590 | ||
591 | default: | 591 | default: |
592 | bfa_assert(0); | 592 | bfa_sm_fault(rport->fcs, event); |
593 | } | 593 | } |
594 | } | 594 | } |
595 | 595 | ||
@@ -646,7 +646,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport, | |||
646 | break; | 646 | break; |
647 | 647 | ||
648 | default: | 648 | default: |
649 | bfa_assert(0); | 649 | bfa_sm_fault(rport->fcs, event); |
650 | } | 650 | } |
651 | } | 651 | } |
652 | 652 | ||
@@ -704,7 +704,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
704 | break; | 704 | break; |
705 | 705 | ||
706 | default: | 706 | default: |
707 | bfa_assert(0); | 707 | bfa_sm_fault(rport->fcs, event); |
708 | } | 708 | } |
709 | } | 709 | } |
710 | 710 | ||
@@ -754,7 +754,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, | |||
754 | break; | 754 | break; |
755 | 755 | ||
756 | default: | 756 | default: |
757 | bfa_assert(0); | 757 | bfa_sm_fault(rport->fcs, event); |
758 | } | 758 | } |
759 | } | 759 | } |
760 | 760 | ||
@@ -816,7 +816,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
816 | break; | 816 | break; |
817 | 817 | ||
818 | default: | 818 | default: |
819 | bfa_assert(0); | 819 | bfa_sm_fault(rport->fcs, event); |
820 | } | 820 | } |
821 | } | 821 | } |
822 | 822 | ||
@@ -846,7 +846,7 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, | |||
846 | break; | 846 | break; |
847 | 847 | ||
848 | default: | 848 | default: |
849 | bfa_assert(0); | 849 | bfa_sm_fault(rport->fcs, event); |
850 | } | 850 | } |
851 | } | 851 | } |
852 | 852 | ||
@@ -869,7 +869,7 @@ bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport, | |||
869 | break; | 869 | break; |
870 | 870 | ||
871 | default: | 871 | default: |
872 | bfa_assert(0); | 872 | bfa_sm_fault(rport->fcs, event); |
873 | } | 873 | } |
874 | } | 874 | } |
875 | 875 | ||
@@ -905,7 +905,7 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport, | |||
905 | break; | 905 | break; |
906 | 906 | ||
907 | default: | 907 | default: |
908 | bfa_assert(0); | 908 | bfa_sm_fault(rport->fcs, event); |
909 | } | 909 | } |
910 | } | 910 | } |
911 | 911 | ||
@@ -925,10 +925,17 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, | |||
925 | case RPSM_EVENT_HCB_OFFLINE: | 925 | case RPSM_EVENT_HCB_OFFLINE: |
926 | case RPSM_EVENT_ADDRESS_CHANGE: | 926 | case RPSM_EVENT_ADDRESS_CHANGE: |
927 | if (bfa_fcs_port_is_online(rport->port)) { | 927 | if (bfa_fcs_port_is_online(rport->port)) { |
928 | bfa_sm_set_state(rport, | 928 | if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { |
929 | bfa_fcs_rport_sm_nsdisc_sending); | 929 | bfa_sm_set_state(rport, |
930 | rport->ns_retries = 0; | 930 | bfa_fcs_rport_sm_nsdisc_sending); |
931 | bfa_fcs_rport_send_gidpn(rport, NULL); | 931 | rport->ns_retries = 0; |
932 | bfa_fcs_rport_send_gidpn(rport, NULL); | ||
933 | } else { | ||
934 | bfa_sm_set_state(rport, | ||
935 | bfa_fcs_rport_sm_plogi_sending); | ||
936 | rport->plogi_retries = 0; | ||
937 | bfa_fcs_rport_send_plogi(rport, NULL); | ||
938 | } | ||
932 | } else { | 939 | } else { |
933 | rport->pid = 0; | 940 | rport->pid = 0; |
934 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); | 941 | bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); |
@@ -951,7 +958,7 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, | |||
951 | break; | 958 | break; |
952 | 959 | ||
953 | default: | 960 | default: |
954 | bfa_assert(0); | 961 | bfa_sm_fault(rport->fcs, event); |
955 | } | 962 | } |
956 | } | 963 | } |
957 | 964 | ||
@@ -1011,7 +1018,7 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, | |||
1011 | break; | 1018 | break; |
1012 | 1019 | ||
1013 | default: | 1020 | default: |
1014 | bfa_assert(0); | 1021 | bfa_sm_fault(rport->fcs, event); |
1015 | } | 1022 | } |
1016 | } | 1023 | } |
1017 | 1024 | ||
@@ -1038,7 +1045,7 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport, | |||
1038 | break; | 1045 | break; |
1039 | 1046 | ||
1040 | default: | 1047 | default: |
1041 | bfa_assert(0); | 1048 | bfa_sm_fault(rport->fcs, event); |
1042 | } | 1049 | } |
1043 | } | 1050 | } |
1044 | 1051 | ||
@@ -1073,7 +1080,7 @@ bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport, | |||
1073 | break; | 1080 | break; |
1074 | 1081 | ||
1075 | default: | 1082 | default: |
1076 | bfa_assert(0); | 1083 | bfa_sm_fault(rport->fcs, event); |
1077 | } | 1084 | } |
1078 | } | 1085 | } |
1079 | 1086 | ||
@@ -1132,7 +1139,7 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event) | |||
1132 | break; | 1139 | break; |
1133 | 1140 | ||
1134 | default: | 1141 | default: |
1135 | bfa_assert(0); | 1142 | bfa_sm_fault(rport->fcs, event); |
1136 | } | 1143 | } |
1137 | } | 1144 | } |
1138 | 1145 | ||
@@ -1188,7 +1195,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport, | |||
1188 | break; | 1195 | break; |
1189 | 1196 | ||
1190 | default: | 1197 | default: |
1191 | bfa_assert(0); | 1198 | bfa_sm_fault(rport->fcs, event); |
1192 | } | 1199 | } |
1193 | } | 1200 | } |
1194 | 1201 | ||
@@ -1249,7 +1256,7 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport, | |||
1249 | break; | 1256 | break; |
1250 | 1257 | ||
1251 | default: | 1258 | default: |
1252 | bfa_assert(0); | 1259 | bfa_sm_fault(rport->fcs, event); |
1253 | } | 1260 | } |
1254 | } | 1261 | } |
1255 | 1262 | ||
@@ -1334,7 +1341,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, | |||
1334 | break; | 1341 | break; |
1335 | 1342 | ||
1336 | default: | 1343 | default: |
1337 | bfa_assert(0); | 1344 | bfa_sm_fault(rport->fcs, event); |
1338 | } | 1345 | } |
1339 | } | 1346 | } |
1340 | 1347 | ||
@@ -1366,7 +1373,7 @@ bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) | |||
1366 | len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, | 1373 | len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, |
1367 | bfa_fcs_port_get_fcid(port), 0, | 1374 | bfa_fcs_port_get_fcid(port), 0, |
1368 | port->port_cfg.pwwn, port->port_cfg.nwwn, | 1375 | port->port_cfg.pwwn, port->port_cfg.nwwn, |
1369 | bfa_pport_get_maxfrsize(port->fcs->bfa)); | 1376 | bfa_fcport_get_maxfrsize(port->fcs->bfa)); |
1370 | 1377 | ||
1371 | bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, | 1378 | bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, |
1372 | FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response, | 1379 | FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response, |
@@ -1478,7 +1485,7 @@ bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) | |||
1478 | len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, | 1485 | len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, |
1479 | bfa_fcs_port_get_fcid(port), rport->reply_oxid, | 1486 | bfa_fcs_port_get_fcid(port), rport->reply_oxid, |
1480 | port->port_cfg.pwwn, port->port_cfg.nwwn, | 1487 | port->port_cfg.pwwn, port->port_cfg.nwwn, |
1481 | bfa_pport_get_maxfrsize(port->fcs->bfa)); | 1488 | bfa_fcport_get_maxfrsize(port->fcs->bfa)); |
1482 | 1489 | ||
1483 | bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, | 1490 | bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, |
1484 | FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); | 1491 | FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); |
@@ -1813,7 +1820,7 @@ bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport, | |||
1813 | /* | 1820 | /* |
1814 | * get curent speed from pport attributes from BFA | 1821 | * get curent speed from pport attributes from BFA |
1815 | */ | 1822 | */ |
1816 | bfa_pport_get_attr(port->fcs->bfa, &pport_attr); | 1823 | bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); |
1817 | 1824 | ||
1818 | speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed); | 1825 | speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed); |
1819 | 1826 | ||
@@ -2032,13 +2039,10 @@ bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport, | |||
2032 | 2039 | ||
2033 | switch (event) { | 2040 | switch (event) { |
2034 | case BFA_RPORT_AEN_ONLINE: | 2041 | case BFA_RPORT_AEN_ONLINE: |
2035 | bfa_log(logmod, BFA_AEN_RPORT_ONLINE, rpwwn_ptr, lpwwn_ptr); | ||
2036 | break; | ||
2037 | case BFA_RPORT_AEN_OFFLINE: | 2042 | case BFA_RPORT_AEN_OFFLINE: |
2038 | bfa_log(logmod, BFA_AEN_RPORT_OFFLINE, rpwwn_ptr, lpwwn_ptr); | ||
2039 | break; | ||
2040 | case BFA_RPORT_AEN_DISCONNECT: | 2043 | case BFA_RPORT_AEN_DISCONNECT: |
2041 | bfa_log(logmod, BFA_AEN_RPORT_DISCONNECT, rpwwn_ptr, lpwwn_ptr); | 2044 | bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, event), |
2045 | rpwwn_ptr, lpwwn_ptr); | ||
2042 | break; | 2046 | break; |
2043 | case BFA_RPORT_AEN_QOS_PRIO: | 2047 | case BFA_RPORT_AEN_QOS_PRIO: |
2044 | aen_data.rport.priv.qos = data->priv.qos; | 2048 | aen_data.rport.priv.qos = data->priv.qos; |
@@ -2164,7 +2168,7 @@ bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi) | |||
2164 | bfa_trc(port->fcs, port->fabric->bb_credit); | 2168 | bfa_trc(port->fcs, port->fabric->bb_credit); |
2165 | 2169 | ||
2166 | port->fabric->bb_credit = bfa_os_ntohs(plogi->csp.bbcred); | 2170 | port->fabric->bb_credit = bfa_os_ntohs(plogi->csp.bbcred); |
2167 | bfa_pport_set_tx_bbcredit(port->fcs->bfa, | 2171 | bfa_fcport_set_tx_bbcredit(port->fcs->bfa, |
2168 | port->fabric->bb_credit); | 2172 | port->fabric->bb_credit); |
2169 | } | 2173 | } |
2170 | 2174 | ||
@@ -2575,23 +2579,6 @@ bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, | |||
2575 | } | 2579 | } |
2576 | 2580 | ||
2577 | /** | 2581 | /** |
2578 | * Module initialization | ||
2579 | */ | ||
2580 | void | ||
2581 | bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs) | ||
2582 | { | ||
2583 | } | ||
2584 | |||
2585 | /** | ||
2586 | * Module cleanup | ||
2587 | */ | ||
2588 | void | ||
2589 | bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs) | ||
2590 | { | ||
2591 | bfa_fcs_modexit_comp(fcs); | ||
2592 | } | ||
2593 | |||
2594 | /** | ||
2595 | * Return state of rport. | 2582 | * Return state of rport. |
2596 | */ | 2583 | */ |
2597 | int | 2584 | int |
diff --git a/drivers/scsi/bfa/rport_api.c b/drivers/scsi/bfa/rport_api.c index 3dae1774181e..a441f41d2a64 100644 --- a/drivers/scsi/bfa/rport_api.c +++ b/drivers/scsi/bfa/rport_api.c | |||
@@ -102,7 +102,7 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport, | |||
102 | rport_attr->qos_attr = qos_attr; | 102 | rport_attr->qos_attr = qos_attr; |
103 | 103 | ||
104 | rport_attr->trl_enforced = BFA_FALSE; | 104 | rport_attr->trl_enforced = BFA_FALSE; |
105 | if (bfa_pport_is_ratelim(port->fcs->bfa)) { | 105 | if (bfa_fcport_is_ratelim(port->fcs->bfa)) { |
106 | if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) || | 106 | if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) || |
107 | (rport->rpf.rpsc_speed < | 107 | (rport->rpf.rpsc_speed < |
108 | bfa_fcs_port_get_rport_max_speed(port))) | 108 | bfa_fcs_port_get_rport_max_speed(port))) |
diff --git a/drivers/scsi/bfa/rport_ftrs.c b/drivers/scsi/bfa/rport_ftrs.c index e1932c885ac2..ae7bba67ae2a 100644 --- a/drivers/scsi/bfa/rport_ftrs.c +++ b/drivers/scsi/bfa/rport_ftrs.c | |||
@@ -91,7 +91,7 @@ bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) | |||
91 | break; | 91 | break; |
92 | 92 | ||
93 | default: | 93 | default: |
94 | bfa_assert(0); | 94 | bfa_sm_fault(rport->fcs, event); |
95 | } | 95 | } |
96 | } | 96 | } |
97 | 97 | ||
@@ -114,7 +114,7 @@ bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) | |||
114 | break; | 114 | break; |
115 | 115 | ||
116 | default: | 116 | default: |
117 | bfa_assert(0); | 117 | bfa_sm_fault(rport->fcs, event); |
118 | } | 118 | } |
119 | } | 119 | } |
120 | 120 | ||
@@ -160,7 +160,7 @@ bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) | |||
160 | break; | 160 | break; |
161 | 161 | ||
162 | default: | 162 | default: |
163 | bfa_assert(0); | 163 | bfa_sm_fault(rport->fcs, event); |
164 | } | 164 | } |
165 | } | 165 | } |
166 | 166 | ||
@@ -186,7 +186,7 @@ bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) | |||
186 | break; | 186 | break; |
187 | 187 | ||
188 | default: | 188 | default: |
189 | bfa_assert(0); | 189 | bfa_sm_fault(rport->fcs, event); |
190 | } | 190 | } |
191 | } | 191 | } |
192 | 192 | ||
@@ -206,7 +206,7 @@ bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) | |||
206 | break; | 206 | break; |
207 | 207 | ||
208 | default: | 208 | default: |
209 | bfa_assert(0); | 209 | bfa_sm_fault(rport->fcs, event); |
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
@@ -229,7 +229,7 @@ bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) | |||
229 | break; | 229 | break; |
230 | 230 | ||
231 | default: | 231 | default: |
232 | bfa_assert(0); | 232 | bfa_sm_fault(rport->fcs, event); |
233 | } | 233 | } |
234 | } | 234 | } |
235 | /** | 235 | /** |
diff --git a/drivers/scsi/bfa/scn.c b/drivers/scsi/bfa/scn.c index bd4771ff62c8..8fe09ba88a91 100644 --- a/drivers/scsi/bfa/scn.c +++ b/drivers/scsi/bfa/scn.c | |||
@@ -90,7 +90,7 @@ bfa_fcs_port_scn_sm_offline(struct bfa_fcs_port_scn_s *scn, | |||
90 | break; | 90 | break; |
91 | 91 | ||
92 | default: | 92 | default: |
93 | bfa_assert(0); | 93 | bfa_sm_fault(scn->port->fcs, event); |
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
@@ -109,7 +109,7 @@ bfa_fcs_port_scn_sm_sending_scr(struct bfa_fcs_port_scn_s *scn, | |||
109 | break; | 109 | break; |
110 | 110 | ||
111 | default: | 111 | default: |
112 | bfa_assert(0); | 112 | bfa_sm_fault(scn->port->fcs, event); |
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
@@ -137,7 +137,7 @@ bfa_fcs_port_scn_sm_scr(struct bfa_fcs_port_scn_s *scn, | |||
137 | break; | 137 | break; |
138 | 138 | ||
139 | default: | 139 | default: |
140 | bfa_assert(0); | 140 | bfa_sm_fault(scn->port->fcs, event); |
141 | } | 141 | } |
142 | } | 142 | } |
143 | 143 | ||
@@ -157,7 +157,7 @@ bfa_fcs_port_scn_sm_scr_retry(struct bfa_fcs_port_scn_s *scn, | |||
157 | break; | 157 | break; |
158 | 158 | ||
159 | default: | 159 | default: |
160 | bfa_assert(0); | 160 | bfa_sm_fault(scn->port->fcs, event); |
161 | } | 161 | } |
162 | } | 162 | } |
163 | 163 | ||
@@ -171,7 +171,7 @@ bfa_fcs_port_scn_sm_online(struct bfa_fcs_port_scn_s *scn, | |||
171 | break; | 171 | break; |
172 | 172 | ||
173 | default: | 173 | default: |
174 | bfa_assert(0); | 174 | bfa_sm_fault(scn->port->fcs, event); |
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c index e90f1e38c32d..27cd619a227a 100644 --- a/drivers/scsi/bfa/vport.c +++ b/drivers/scsi/bfa/vport.c | |||
@@ -122,7 +122,7 @@ bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, | |||
122 | break; | 122 | break; |
123 | 123 | ||
124 | default: | 124 | default: |
125 | bfa_assert(0); | 125 | bfa_sm_fault(__vport_fcs(vport), event); |
126 | } | 126 | } |
127 | } | 127 | } |
128 | 128 | ||
@@ -165,7 +165,7 @@ bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, | |||
165 | break; | 165 | break; |
166 | 166 | ||
167 | default: | 167 | default: |
168 | bfa_assert(0); | 168 | bfa_sm_fault(__vport_fcs(vport), event); |
169 | } | 169 | } |
170 | } | 170 | } |
171 | 171 | ||
@@ -202,7 +202,7 @@ bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, | |||
202 | break; | 202 | break; |
203 | 203 | ||
204 | default: | 204 | default: |
205 | bfa_assert(0); | 205 | bfa_sm_fault(__vport_fcs(vport), event); |
206 | } | 206 | } |
207 | } | 207 | } |
208 | 208 | ||
@@ -249,7 +249,7 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, | |||
249 | break; | 249 | break; |
250 | 250 | ||
251 | default: | 251 | default: |
252 | bfa_assert(0); | 252 | bfa_sm_fault(__vport_fcs(vport), event); |
253 | } | 253 | } |
254 | } | 254 | } |
255 | 255 | ||
@@ -283,7 +283,7 @@ bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, | |||
283 | break; | 283 | break; |
284 | 284 | ||
285 | default: | 285 | default: |
286 | bfa_assert(0); | 286 | bfa_sm_fault(__vport_fcs(vport), event); |
287 | } | 287 | } |
288 | } | 288 | } |
289 | 289 | ||
@@ -310,7 +310,7 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, | |||
310 | break; | 310 | break; |
311 | 311 | ||
312 | default: | 312 | default: |
313 | bfa_assert(0); | 313 | bfa_sm_fault(__vport_fcs(vport), event); |
314 | } | 314 | } |
315 | } | 315 | } |
316 | 316 | ||
@@ -339,7 +339,7 @@ bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, | |||
339 | break; | 339 | break; |
340 | 340 | ||
341 | default: | 341 | default: |
342 | bfa_assert(0); | 342 | bfa_sm_fault(__vport_fcs(vport), event); |
343 | } | 343 | } |
344 | } | 344 | } |
345 | 345 | ||
@@ -387,7 +387,7 @@ bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, | |||
387 | break; | 387 | break; |
388 | 388 | ||
389 | default: | 389 | default: |
390 | bfa_assert(0); | 390 | bfa_sm_fault(__vport_fcs(vport), event); |
391 | } | 391 | } |
392 | } | 392 | } |
393 | 393 | ||
@@ -419,7 +419,7 @@ bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, | |||
419 | break; | 419 | break; |
420 | 420 | ||
421 | default: | 421 | default: |
422 | bfa_assert(0); | 422 | bfa_sm_fault(__vport_fcs(vport), event); |
423 | } | 423 | } |
424 | } | 424 | } |
425 | 425 | ||
@@ -447,22 +447,8 @@ bfa_fcs_vport_aen_post(bfa_fcs_lport_t *port, enum bfa_lport_aen_event event) | |||
447 | 447 | ||
448 | bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX); | 448 | bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX); |
449 | 449 | ||
450 | switch (event) { | 450 | bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr, |
451 | case BFA_LPORT_AEN_NPIV_DUP_WWN: | 451 | role_str[role/2]); |
452 | bfa_log(logmod, BFA_AEN_LPORT_NPIV_DUP_WWN, lpwwn_ptr, | ||
453 | role_str[role / 2]); | ||
454 | break; | ||
455 | case BFA_LPORT_AEN_NPIV_FABRIC_MAX: | ||
456 | bfa_log(logmod, BFA_AEN_LPORT_NPIV_FABRIC_MAX, lpwwn_ptr, | ||
457 | role_str[role / 2]); | ||
458 | break; | ||
459 | case BFA_LPORT_AEN_NPIV_UNKNOWN: | ||
460 | bfa_log(logmod, BFA_AEN_LPORT_NPIV_UNKNOWN, lpwwn_ptr, | ||
461 | role_str[role / 2]); | ||
462 | break; | ||
463 | default: | ||
464 | break; | ||
465 | } | ||
466 | 452 | ||
467 | aen_data.lport.vf_id = port->fabric->vf_id; | 453 | aen_data.lport.vf_id = port->fabric->vf_id; |
468 | aen_data.lport.roles = role; | 454 | aen_data.lport.roles = role; |
@@ -478,7 +464,7 @@ static void | |||
478 | bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport) | 464 | bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport) |
479 | { | 465 | { |
480 | bfa_lps_fdisc(vport->lps, vport, | 466 | bfa_lps_fdisc(vport->lps, vport, |
481 | bfa_pport_get_maxfrsize(__vport_bfa(vport)), | 467 | bfa_fcport_get_maxfrsize(__vport_bfa(vport)), |
482 | __vport_pwwn(vport), __vport_nwwn(vport)); | 468 | __vport_pwwn(vport), __vport_nwwn(vport)); |
483 | vport->vport_stats.fdisc_sent++; | 469 | vport->vport_stats.fdisc_sent++; |
484 | } | 470 | } |
@@ -617,38 +603,6 @@ bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport) | |||
617 | } | 603 | } |
618 | 604 | ||
619 | /** | 605 | /** |
620 | * Module initialization | ||
621 | */ | ||
622 | void | ||
623 | bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs) | ||
624 | { | ||
625 | } | ||
626 | |||
627 | /** | ||
628 | * Module cleanup | ||
629 | */ | ||
630 | void | ||
631 | bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs) | ||
632 | { | ||
633 | bfa_fcs_modexit_comp(fcs); | ||
634 | } | ||
635 | |||
636 | u32 | ||
637 | bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs) | ||
638 | { | ||
639 | struct bfa_ioc_attr_s ioc_attr; | ||
640 | |||
641 | bfa_get_attr(fcs->bfa, &ioc_attr); | ||
642 | |||
643 | if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT) | ||
644 | return BFA_FCS_MAX_VPORTS_SUPP_CT; | ||
645 | else | ||
646 | return BFA_FCS_MAX_VPORTS_SUPP_CB; | ||
647 | } | ||
648 | |||
649 | |||
650 | |||
651 | /** | ||
652 | * fcs_vport_api Virtual port API | 606 | * fcs_vport_api Virtual port API |
653 | */ | 607 | */ |
654 | 608 | ||
@@ -684,7 +638,7 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, | |||
684 | return BFA_STATUS_VPORT_EXISTS; | 638 | return BFA_STATUS_VPORT_EXISTS; |
685 | 639 | ||
686 | if (bfa_fcs_fabric_vport_count(&fcs->fabric) == | 640 | if (bfa_fcs_fabric_vport_count(&fcs->fabric) == |
687 | bfa_fcs_vport_get_max(fcs)) | 641 | bfa_lps_get_max_vport(fcs->bfa)) |
688 | return BFA_STATUS_VPORT_MAX; | 642 | return BFA_STATUS_VPORT_MAX; |
689 | 643 | ||
690 | vport->lps = bfa_lps_alloc(fcs->bfa); | 644 | vport->lps = bfa_lps_alloc(fcs->bfa); |
@@ -694,7 +648,8 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, | |||
694 | vport->vport_drv = vport_drv; | 648 | vport->vport_drv = vport_drv; |
695 | bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); | 649 | bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); |
696 | 650 | ||
697 | bfa_fcs_lport_init(&vport->lport, fcs, vf_id, vport_cfg, vport); | 651 | bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport); |
652 | bfa_fcs_lport_init(&vport->lport, vport_cfg); | ||
698 | 653 | ||
699 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE); | 654 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE); |
700 | 655 | ||
@@ -888,4 +843,15 @@ bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg) | |||
888 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); | 843 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); |
889 | } | 844 | } |
890 | 845 | ||
846 | /** | ||
847 | * Received clear virtual link | ||
848 | */ | ||
849 | void | ||
850 | bfa_cb_lps_cvl_event(void *bfad, void *uarg) | ||
851 | { | ||
852 | struct bfa_fcs_vport_s *vport = uarg; | ||
891 | 853 | ||
854 | /* Send an Offline followed by an ONLINE */ | ||
855 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); | ||
856 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); | ||
857 | } | ||
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 1c4d1215769d..cb71dc984797 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c | |||
@@ -1989,7 +1989,7 @@ static struct scsi_host_template bnx2i_host_template = { | |||
1989 | .queuecommand = iscsi_queuecommand, | 1989 | .queuecommand = iscsi_queuecommand, |
1990 | .eh_abort_handler = iscsi_eh_abort, | 1990 | .eh_abort_handler = iscsi_eh_abort, |
1991 | .eh_device_reset_handler = iscsi_eh_device_reset, | 1991 | .eh_device_reset_handler = iscsi_eh_device_reset, |
1992 | .eh_target_reset_handler = iscsi_eh_target_reset, | 1992 | .eh_target_reset_handler = iscsi_eh_recover_target, |
1993 | .change_queue_depth = iscsi_change_queue_depth, | 1993 | .change_queue_depth = iscsi_change_queue_depth, |
1994 | .can_queue = 1024, | 1994 | .can_queue = 1024, |
1995 | .max_sectors = 127, | 1995 | .max_sectors = 127, |
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c index 412853c65372..b7c30585dadd 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c +++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c | |||
@@ -915,7 +915,7 @@ static struct scsi_host_template cxgb3i_host_template = { | |||
915 | .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, | 915 | .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, |
916 | .eh_abort_handler = iscsi_eh_abort, | 916 | .eh_abort_handler = iscsi_eh_abort, |
917 | .eh_device_reset_handler = iscsi_eh_device_reset, | 917 | .eh_device_reset_handler = iscsi_eh_device_reset, |
918 | .eh_target_reset_handler = iscsi_eh_target_reset, | 918 | .eh_target_reset_handler = iscsi_eh_recover_target, |
919 | .target_alloc = iscsi_target_alloc, | 919 | .target_alloc = iscsi_target_alloc, |
920 | .use_clustering = DISABLE_CLUSTERING, | 920 | .use_clustering = DISABLE_CLUSTERING, |
921 | .this_id = -1, | 921 | .this_id = -1, |
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index 61966750bd60..63032ec3db92 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c | |||
@@ -272,7 +272,7 @@ static struct request *get_req(struct scsi_device *sdev, int cmd, | |||
272 | int len = 0; | 272 | int len = 0; |
273 | 273 | ||
274 | rq = blk_get_request(sdev->request_queue, | 274 | rq = blk_get_request(sdev->request_queue, |
275 | (cmd == MODE_SELECT) ? WRITE : READ, GFP_NOIO); | 275 | (cmd != INQUIRY) ? WRITE : READ, GFP_NOIO); |
276 | if (!rq) { | 276 | if (!rq) { |
277 | sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed"); | 277 | sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed"); |
278 | return NULL; | 278 | return NULL; |
@@ -286,14 +286,17 @@ static struct request *get_req(struct scsi_device *sdev, int cmd, | |||
286 | len = sizeof(short_trespass); | 286 | len = sizeof(short_trespass); |
287 | rq->cmd_flags |= REQ_RW; | 287 | rq->cmd_flags |= REQ_RW; |
288 | rq->cmd[1] = 0x10; | 288 | rq->cmd[1] = 0x10; |
289 | rq->cmd[4] = len; | ||
289 | break; | 290 | break; |
290 | case MODE_SELECT_10: | 291 | case MODE_SELECT_10: |
291 | len = sizeof(long_trespass); | 292 | len = sizeof(long_trespass); |
292 | rq->cmd_flags |= REQ_RW; | 293 | rq->cmd_flags |= REQ_RW; |
293 | rq->cmd[1] = 0x10; | 294 | rq->cmd[1] = 0x10; |
295 | rq->cmd[8] = len; | ||
294 | break; | 296 | break; |
295 | case INQUIRY: | 297 | case INQUIRY: |
296 | len = CLARIION_BUFFER_SIZE; | 298 | len = CLARIION_BUFFER_SIZE; |
299 | rq->cmd[4] = len; | ||
297 | memset(buffer, 0, len); | 300 | memset(buffer, 0, len); |
298 | break; | 301 | break; |
299 | default: | 302 | default: |
@@ -301,7 +304,6 @@ static struct request *get_req(struct scsi_device *sdev, int cmd, | |||
301 | break; | 304 | break; |
302 | } | 305 | } |
303 | 306 | ||
304 | rq->cmd[4] = len; | ||
305 | rq->cmd_type = REQ_TYPE_BLOCK_PC; | 307 | rq->cmd_type = REQ_TYPE_BLOCK_PC; |
306 | rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | | 308 | rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | |
307 | REQ_FAILFAST_DRIVER; | 309 | REQ_FAILFAST_DRIVER; |
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 03697ba94251..183d3a43c280 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <scsi/scsi_cmnd.h> | 43 | #include <scsi/scsi_cmnd.h> |
44 | #include <scsi/scsi_device.h> | 44 | #include <scsi/scsi_device.h> |
45 | #include <scsi/scsi_host.h> | 45 | #include <scsi/scsi_host.h> |
46 | #include <scsi/scsi_tcq.h> | ||
46 | #include <linux/cciss_ioctl.h> | 47 | #include <linux/cciss_ioctl.h> |
47 | #include <linux/string.h> | 48 | #include <linux/string.h> |
48 | #include <linux/bitmap.h> | 49 | #include <linux/bitmap.h> |
@@ -52,7 +53,7 @@ | |||
52 | #include "hpsa.h" | 53 | #include "hpsa.h" |
53 | 54 | ||
54 | /* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */ | 55 | /* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */ |
55 | #define HPSA_DRIVER_VERSION "2.0.1-3" | 56 | #define HPSA_DRIVER_VERSION "2.0.2-1" |
56 | #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")" | 57 | #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")" |
57 | 58 | ||
58 | /* How long to wait (in milliseconds) for board to go into simple mode */ | 59 | /* How long to wait (in milliseconds) for board to go into simple mode */ |
@@ -134,6 +135,8 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd, | |||
134 | static void hpsa_scan_start(struct Scsi_Host *); | 135 | static void hpsa_scan_start(struct Scsi_Host *); |
135 | static int hpsa_scan_finished(struct Scsi_Host *sh, | 136 | static int hpsa_scan_finished(struct Scsi_Host *sh, |
136 | unsigned long elapsed_time); | 137 | unsigned long elapsed_time); |
138 | static int hpsa_change_queue_depth(struct scsi_device *sdev, | ||
139 | int qdepth, int reason); | ||
137 | 140 | ||
138 | static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd); | 141 | static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd); |
139 | static int hpsa_slave_alloc(struct scsi_device *sdev); | 142 | static int hpsa_slave_alloc(struct scsi_device *sdev); |
@@ -182,8 +185,8 @@ static struct scsi_host_template hpsa_driver_template = { | |||
182 | .queuecommand = hpsa_scsi_queue_command, | 185 | .queuecommand = hpsa_scsi_queue_command, |
183 | .scan_start = hpsa_scan_start, | 186 | .scan_start = hpsa_scan_start, |
184 | .scan_finished = hpsa_scan_finished, | 187 | .scan_finished = hpsa_scan_finished, |
188 | .change_queue_depth = hpsa_change_queue_depth, | ||
185 | .this_id = -1, | 189 | .this_id = -1, |
186 | .sg_tablesize = MAXSGENTRIES, | ||
187 | .use_clustering = ENABLE_CLUSTERING, | 190 | .use_clustering = ENABLE_CLUSTERING, |
188 | .eh_device_reset_handler = hpsa_eh_device_reset_handler, | 191 | .eh_device_reset_handler = hpsa_eh_device_reset_handler, |
189 | .ioctl = hpsa_ioctl, | 192 | .ioctl = hpsa_ioctl, |
@@ -208,133 +211,6 @@ static inline struct ctlr_info *shost_to_hba(struct Scsi_Host *sh) | |||
208 | return (struct ctlr_info *) *priv; | 211 | return (struct ctlr_info *) *priv; |
209 | } | 212 | } |
210 | 213 | ||
211 | static struct task_struct *hpsa_scan_thread; | ||
212 | static DEFINE_MUTEX(hpsa_scan_mutex); | ||
213 | static LIST_HEAD(hpsa_scan_q); | ||
214 | static int hpsa_scan_func(void *data); | ||
215 | |||
216 | /** | ||
217 | * add_to_scan_list() - add controller to rescan queue | ||
218 | * @h: Pointer to the controller. | ||
219 | * | ||
220 | * Adds the controller to the rescan queue if not already on the queue. | ||
221 | * | ||
222 | * returns 1 if added to the queue, 0 if skipped (could be on the | ||
223 | * queue already, or the controller could be initializing or shutting | ||
224 | * down). | ||
225 | **/ | ||
226 | static int add_to_scan_list(struct ctlr_info *h) | ||
227 | { | ||
228 | struct ctlr_info *test_h; | ||
229 | int found = 0; | ||
230 | int ret = 0; | ||
231 | |||
232 | if (h->busy_initializing) | ||
233 | return 0; | ||
234 | |||
235 | /* | ||
236 | * If we don't get the lock, it means the driver is unloading | ||
237 | * and there's no point in scheduling a new scan. | ||
238 | */ | ||
239 | if (!mutex_trylock(&h->busy_shutting_down)) | ||
240 | return 0; | ||
241 | |||
242 | mutex_lock(&hpsa_scan_mutex); | ||
243 | list_for_each_entry(test_h, &hpsa_scan_q, scan_list) { | ||
244 | if (test_h == h) { | ||
245 | found = 1; | ||
246 | break; | ||
247 | } | ||
248 | } | ||
249 | if (!found && !h->busy_scanning) { | ||
250 | INIT_COMPLETION(h->scan_wait); | ||
251 | list_add_tail(&h->scan_list, &hpsa_scan_q); | ||
252 | ret = 1; | ||
253 | } | ||
254 | mutex_unlock(&hpsa_scan_mutex); | ||
255 | mutex_unlock(&h->busy_shutting_down); | ||
256 | |||
257 | return ret; | ||
258 | } | ||
259 | |||
260 | /** | ||
261 | * remove_from_scan_list() - remove controller from rescan queue | ||
262 | * @h: Pointer to the controller. | ||
263 | * | ||
264 | * Removes the controller from the rescan queue if present. Blocks if | ||
265 | * the controller is currently conducting a rescan. The controller | ||
266 | * can be in one of three states: | ||
267 | * 1. Doesn't need a scan | ||
268 | * 2. On the scan list, but not scanning yet (we remove it) | ||
269 | * 3. Busy scanning (and not on the list). In this case we want to wait for | ||
270 | * the scan to complete to make sure the scanning thread for this | ||
271 | * controller is completely idle. | ||
272 | **/ | ||
273 | static void remove_from_scan_list(struct ctlr_info *h) | ||
274 | { | ||
275 | struct ctlr_info *test_h, *tmp_h; | ||
276 | |||
277 | mutex_lock(&hpsa_scan_mutex); | ||
278 | list_for_each_entry_safe(test_h, tmp_h, &hpsa_scan_q, scan_list) { | ||
279 | if (test_h == h) { /* state 2. */ | ||
280 | list_del(&h->scan_list); | ||
281 | complete_all(&h->scan_wait); | ||
282 | mutex_unlock(&hpsa_scan_mutex); | ||
283 | return; | ||
284 | } | ||
285 | } | ||
286 | if (h->busy_scanning) { /* state 3. */ | ||
287 | mutex_unlock(&hpsa_scan_mutex); | ||
288 | wait_for_completion(&h->scan_wait); | ||
289 | } else { /* state 1, nothing to do. */ | ||
290 | mutex_unlock(&hpsa_scan_mutex); | ||
291 | } | ||
292 | } | ||
293 | |||
294 | /* hpsa_scan_func() - kernel thread used to rescan controllers | ||
295 | * @data: Ignored. | ||
296 | * | ||
297 | * A kernel thread used scan for drive topology changes on | ||
298 | * controllers. The thread processes only one controller at a time | ||
299 | * using a queue. Controllers are added to the queue using | ||
300 | * add_to_scan_list() and removed from the queue either after done | ||
301 | * processing or using remove_from_scan_list(). | ||
302 | * | ||
303 | * returns 0. | ||
304 | **/ | ||
305 | static int hpsa_scan_func(__attribute__((unused)) void *data) | ||
306 | { | ||
307 | struct ctlr_info *h; | ||
308 | int host_no; | ||
309 | |||
310 | while (1) { | ||
311 | set_current_state(TASK_INTERRUPTIBLE); | ||
312 | schedule(); | ||
313 | if (kthread_should_stop()) | ||
314 | break; | ||
315 | |||
316 | while (1) { | ||
317 | mutex_lock(&hpsa_scan_mutex); | ||
318 | if (list_empty(&hpsa_scan_q)) { | ||
319 | mutex_unlock(&hpsa_scan_mutex); | ||
320 | break; | ||
321 | } | ||
322 | h = list_entry(hpsa_scan_q.next, struct ctlr_info, | ||
323 | scan_list); | ||
324 | list_del(&h->scan_list); | ||
325 | h->busy_scanning = 1; | ||
326 | mutex_unlock(&hpsa_scan_mutex); | ||
327 | host_no = h->scsi_host ? h->scsi_host->host_no : -1; | ||
328 | hpsa_scan_start(h->scsi_host); | ||
329 | complete_all(&h->scan_wait); | ||
330 | mutex_lock(&hpsa_scan_mutex); | ||
331 | h->busy_scanning = 0; | ||
332 | mutex_unlock(&hpsa_scan_mutex); | ||
333 | } | ||
334 | } | ||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | static int check_for_unit_attention(struct ctlr_info *h, | 214 | static int check_for_unit_attention(struct ctlr_info *h, |
339 | struct CommandList *c) | 215 | struct CommandList *c) |
340 | { | 216 | { |
@@ -352,21 +228,8 @@ static int check_for_unit_attention(struct ctlr_info *h, | |||
352 | break; | 228 | break; |
353 | case REPORT_LUNS_CHANGED: | 229 | case REPORT_LUNS_CHANGED: |
354 | dev_warn(&h->pdev->dev, "hpsa%d: report LUN data " | 230 | dev_warn(&h->pdev->dev, "hpsa%d: report LUN data " |
355 | "changed\n", h->ctlr); | 231 | "changed, action required\n", h->ctlr); |
356 | /* | 232 | /* |
357 | * Here, we could call add_to_scan_list and wake up the scan thread, | ||
358 | * except that it's quite likely that we will get more than one | ||
359 | * REPORT_LUNS_CHANGED condition in quick succession, which means | ||
360 | * that those which occur after the first one will likely happen | ||
361 | * *during* the hpsa_scan_thread's rescan. And the rescan code is not | ||
362 | * robust enough to restart in the middle, undoing what it has already | ||
363 | * done, and it's not clear that it's even possible to do this, since | ||
364 | * part of what it does is notify the SCSI mid layer, which starts | ||
365 | * doing it's own i/o to read partition tables and so on, and the | ||
366 | * driver doesn't have visibility to know what might need undoing. | ||
367 | * In any event, if possible, it is horribly complicated to get right | ||
368 | * so we just don't do it for now. | ||
369 | * | ||
370 | * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012. | 233 | * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012. |
371 | */ | 234 | */ |
372 | break; | 235 | break; |
@@ -393,10 +256,7 @@ static ssize_t host_store_rescan(struct device *dev, | |||
393 | struct ctlr_info *h; | 256 | struct ctlr_info *h; |
394 | struct Scsi_Host *shost = class_to_shost(dev); | 257 | struct Scsi_Host *shost = class_to_shost(dev); |
395 | h = shost_to_hba(shost); | 258 | h = shost_to_hba(shost); |
396 | if (add_to_scan_list(h)) { | 259 | hpsa_scan_start(h->scsi_host); |
397 | wake_up_process(hpsa_scan_thread); | ||
398 | wait_for_completion_interruptible(&h->scan_wait); | ||
399 | } | ||
400 | return count; | 260 | return count; |
401 | } | 261 | } |
402 | 262 | ||
@@ -983,6 +843,76 @@ static void hpsa_scsi_setup(struct ctlr_info *h) | |||
983 | spin_lock_init(&h->devlock); | 843 | spin_lock_init(&h->devlock); |
984 | } | 844 | } |
985 | 845 | ||
846 | static void hpsa_free_sg_chain_blocks(struct ctlr_info *h) | ||
847 | { | ||
848 | int i; | ||
849 | |||
850 | if (!h->cmd_sg_list) | ||
851 | return; | ||
852 | for (i = 0; i < h->nr_cmds; i++) { | ||
853 | kfree(h->cmd_sg_list[i]); | ||
854 | h->cmd_sg_list[i] = NULL; | ||
855 | } | ||
856 | kfree(h->cmd_sg_list); | ||
857 | h->cmd_sg_list = NULL; | ||
858 | } | ||
859 | |||
860 | static int hpsa_allocate_sg_chain_blocks(struct ctlr_info *h) | ||
861 | { | ||
862 | int i; | ||
863 | |||
864 | if (h->chainsize <= 0) | ||
865 | return 0; | ||
866 | |||
867 | h->cmd_sg_list = kzalloc(sizeof(*h->cmd_sg_list) * h->nr_cmds, | ||
868 | GFP_KERNEL); | ||
869 | if (!h->cmd_sg_list) | ||
870 | return -ENOMEM; | ||
871 | for (i = 0; i < h->nr_cmds; i++) { | ||
872 | h->cmd_sg_list[i] = kmalloc(sizeof(*h->cmd_sg_list[i]) * | ||
873 | h->chainsize, GFP_KERNEL); | ||
874 | if (!h->cmd_sg_list[i]) | ||
875 | goto clean; | ||
876 | } | ||
877 | return 0; | ||
878 | |||
879 | clean: | ||
880 | hpsa_free_sg_chain_blocks(h); | ||
881 | return -ENOMEM; | ||
882 | } | ||
883 | |||
884 | static void hpsa_map_sg_chain_block(struct ctlr_info *h, | ||
885 | struct CommandList *c) | ||
886 | { | ||
887 | struct SGDescriptor *chain_sg, *chain_block; | ||
888 | u64 temp64; | ||
889 | |||
890 | chain_sg = &c->SG[h->max_cmd_sg_entries - 1]; | ||
891 | chain_block = h->cmd_sg_list[c->cmdindex]; | ||
892 | chain_sg->Ext = HPSA_SG_CHAIN; | ||
893 | chain_sg->Len = sizeof(*chain_sg) * | ||
894 | (c->Header.SGTotal - h->max_cmd_sg_entries); | ||
895 | temp64 = pci_map_single(h->pdev, chain_block, chain_sg->Len, | ||
896 | PCI_DMA_TODEVICE); | ||
897 | chain_sg->Addr.lower = (u32) (temp64 & 0x0FFFFFFFFULL); | ||
898 | chain_sg->Addr.upper = (u32) ((temp64 >> 32) & 0x0FFFFFFFFULL); | ||
899 | } | ||
900 | |||
901 | static void hpsa_unmap_sg_chain_block(struct ctlr_info *h, | ||
902 | struct CommandList *c) | ||
903 | { | ||
904 | struct SGDescriptor *chain_sg; | ||
905 | union u64bit temp64; | ||
906 | |||
907 | if (c->Header.SGTotal <= h->max_cmd_sg_entries) | ||
908 | return; | ||
909 | |||
910 | chain_sg = &c->SG[h->max_cmd_sg_entries - 1]; | ||
911 | temp64.val32.lower = chain_sg->Addr.lower; | ||
912 | temp64.val32.upper = chain_sg->Addr.upper; | ||
913 | pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE); | ||
914 | } | ||
915 | |||
986 | static void complete_scsi_command(struct CommandList *cp, | 916 | static void complete_scsi_command(struct CommandList *cp, |
987 | int timeout, u32 tag) | 917 | int timeout, u32 tag) |
988 | { | 918 | { |
@@ -999,10 +929,12 @@ static void complete_scsi_command(struct CommandList *cp, | |||
999 | h = cp->h; | 929 | h = cp->h; |
1000 | 930 | ||
1001 | scsi_dma_unmap(cmd); /* undo the DMA mappings */ | 931 | scsi_dma_unmap(cmd); /* undo the DMA mappings */ |
932 | if (cp->Header.SGTotal > h->max_cmd_sg_entries) | ||
933 | hpsa_unmap_sg_chain_block(h, cp); | ||
1002 | 934 | ||
1003 | cmd->result = (DID_OK << 16); /* host byte */ | 935 | cmd->result = (DID_OK << 16); /* host byte */ |
1004 | cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ | 936 | cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ |
1005 | cmd->result |= (ei->ScsiStatus << 1); | 937 | cmd->result |= ei->ScsiStatus; |
1006 | 938 | ||
1007 | /* copy the sense data whether we need to or not. */ | 939 | /* copy the sense data whether we need to or not. */ |
1008 | memcpy(cmd->sense_buffer, ei->SenseInfo, | 940 | memcpy(cmd->sense_buffer, ei->SenseInfo, |
@@ -1203,6 +1135,7 @@ static int hpsa_scsi_detect(struct ctlr_info *h) | |||
1203 | sh->max_id = HPSA_MAX_LUN; | 1135 | sh->max_id = HPSA_MAX_LUN; |
1204 | sh->can_queue = h->nr_cmds; | 1136 | sh->can_queue = h->nr_cmds; |
1205 | sh->cmd_per_lun = h->nr_cmds; | 1137 | sh->cmd_per_lun = h->nr_cmds; |
1138 | sh->sg_tablesize = h->maxsgentries; | ||
1206 | h->scsi_host = sh; | 1139 | h->scsi_host = sh; |
1207 | sh->hostdata[0] = (unsigned long) h; | 1140 | sh->hostdata[0] = (unsigned long) h; |
1208 | sh->irq = h->intr[PERF_MODE_INT]; | 1141 | sh->irq = h->intr[PERF_MODE_INT]; |
@@ -1382,7 +1315,7 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr) | |||
1382 | 1315 | ||
1383 | if (c == NULL) { /* trouble... */ | 1316 | if (c == NULL) { /* trouble... */ |
1384 | dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); | 1317 | dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); |
1385 | return -1; | 1318 | return -ENOMEM; |
1386 | } | 1319 | } |
1387 | 1320 | ||
1388 | fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG); | 1321 | fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG); |
@@ -1904,16 +1837,17 @@ out: | |||
1904 | * dma mapping and fills in the scatter gather entries of the | 1837 | * dma mapping and fills in the scatter gather entries of the |
1905 | * hpsa command, cp. | 1838 | * hpsa command, cp. |
1906 | */ | 1839 | */ |
1907 | static int hpsa_scatter_gather(struct pci_dev *pdev, | 1840 | static int hpsa_scatter_gather(struct ctlr_info *h, |
1908 | struct CommandList *cp, | 1841 | struct CommandList *cp, |
1909 | struct scsi_cmnd *cmd) | 1842 | struct scsi_cmnd *cmd) |
1910 | { | 1843 | { |
1911 | unsigned int len; | 1844 | unsigned int len; |
1912 | struct scatterlist *sg; | 1845 | struct scatterlist *sg; |
1913 | u64 addr64; | 1846 | u64 addr64; |
1914 | int use_sg, i; | 1847 | int use_sg, i, sg_index, chained; |
1848 | struct SGDescriptor *curr_sg; | ||
1915 | 1849 | ||
1916 | BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES); | 1850 | BUG_ON(scsi_sg_count(cmd) > h->maxsgentries); |
1917 | 1851 | ||
1918 | use_sg = scsi_dma_map(cmd); | 1852 | use_sg = scsi_dma_map(cmd); |
1919 | if (use_sg < 0) | 1853 | if (use_sg < 0) |
@@ -1922,15 +1856,33 @@ static int hpsa_scatter_gather(struct pci_dev *pdev, | |||
1922 | if (!use_sg) | 1856 | if (!use_sg) |
1923 | goto sglist_finished; | 1857 | goto sglist_finished; |
1924 | 1858 | ||
1859 | curr_sg = cp->SG; | ||
1860 | chained = 0; | ||
1861 | sg_index = 0; | ||
1925 | scsi_for_each_sg(cmd, sg, use_sg, i) { | 1862 | scsi_for_each_sg(cmd, sg, use_sg, i) { |
1863 | if (i == h->max_cmd_sg_entries - 1 && | ||
1864 | use_sg > h->max_cmd_sg_entries) { | ||
1865 | chained = 1; | ||
1866 | curr_sg = h->cmd_sg_list[cp->cmdindex]; | ||
1867 | sg_index = 0; | ||
1868 | } | ||
1926 | addr64 = (u64) sg_dma_address(sg); | 1869 | addr64 = (u64) sg_dma_address(sg); |
1927 | len = sg_dma_len(sg); | 1870 | len = sg_dma_len(sg); |
1928 | cp->SG[i].Addr.lower = | 1871 | curr_sg->Addr.lower = (u32) (addr64 & 0x0FFFFFFFFULL); |
1929 | (u32) (addr64 & (u64) 0x00000000FFFFFFFF); | 1872 | curr_sg->Addr.upper = (u32) ((addr64 >> 32) & 0x0FFFFFFFFULL); |
1930 | cp->SG[i].Addr.upper = | 1873 | curr_sg->Len = len; |
1931 | (u32) ((addr64 >> 32) & (u64) 0x00000000FFFFFFFF); | 1874 | curr_sg->Ext = 0; /* we are not chaining */ |
1932 | cp->SG[i].Len = len; | 1875 | curr_sg++; |
1933 | cp->SG[i].Ext = 0; /* we are not chaining */ | 1876 | } |
1877 | |||
1878 | if (use_sg + chained > h->maxSG) | ||
1879 | h->maxSG = use_sg + chained; | ||
1880 | |||
1881 | if (chained) { | ||
1882 | cp->Header.SGList = h->max_cmd_sg_entries; | ||
1883 | cp->Header.SGTotal = (u16) (use_sg + 1); | ||
1884 | hpsa_map_sg_chain_block(h, cp); | ||
1885 | return 0; | ||
1934 | } | 1886 | } |
1935 | 1887 | ||
1936 | sglist_finished: | 1888 | sglist_finished: |
@@ -2026,7 +1978,7 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd, | |||
2026 | break; | 1978 | break; |
2027 | } | 1979 | } |
2028 | 1980 | ||
2029 | if (hpsa_scatter_gather(h->pdev, c, cmd) < 0) { /* Fill SG list */ | 1981 | if (hpsa_scatter_gather(h, c, cmd) < 0) { /* Fill SG list */ |
2030 | cmd_free(h, c); | 1982 | cmd_free(h, c); |
2031 | return SCSI_MLQUEUE_HOST_BUSY; | 1983 | return SCSI_MLQUEUE_HOST_BUSY; |
2032 | } | 1984 | } |
@@ -2077,6 +2029,23 @@ static int hpsa_scan_finished(struct Scsi_Host *sh, | |||
2077 | return finished; | 2029 | return finished; |
2078 | } | 2030 | } |
2079 | 2031 | ||
2032 | static int hpsa_change_queue_depth(struct scsi_device *sdev, | ||
2033 | int qdepth, int reason) | ||
2034 | { | ||
2035 | struct ctlr_info *h = sdev_to_hba(sdev); | ||
2036 | |||
2037 | if (reason != SCSI_QDEPTH_DEFAULT) | ||
2038 | return -ENOTSUPP; | ||
2039 | |||
2040 | if (qdepth < 1) | ||
2041 | qdepth = 1; | ||
2042 | else | ||
2043 | if (qdepth > h->nr_cmds) | ||
2044 | qdepth = h->nr_cmds; | ||
2045 | scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); | ||
2046 | return sdev->queue_depth; | ||
2047 | } | ||
2048 | |||
2080 | static void hpsa_unregister_scsi(struct ctlr_info *h) | 2049 | static void hpsa_unregister_scsi(struct ctlr_info *h) |
2081 | { | 2050 | { |
2082 | /* we are being forcibly unloaded, and may not refuse. */ | 2051 | /* we are being forcibly unloaded, and may not refuse. */ |
@@ -2961,7 +2930,7 @@ static irqreturn_t do_hpsa_intr(int irq, void *dev_id) | |||
2961 | return IRQ_HANDLED; | 2930 | return IRQ_HANDLED; |
2962 | } | 2931 | } |
2963 | 2932 | ||
2964 | /* Send a message CDB to the firmwart. */ | 2933 | /* Send a message CDB to the firmware. */ |
2965 | static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode, | 2934 | static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode, |
2966 | unsigned char type) | 2935 | unsigned char type) |
2967 | { | 2936 | { |
@@ -3296,7 +3265,7 @@ default_int_mode: | |||
3296 | h->intr[PERF_MODE_INT] = pdev->irq; | 3265 | h->intr[PERF_MODE_INT] = pdev->irq; |
3297 | } | 3266 | } |
3298 | 3267 | ||
3299 | static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) | 3268 | static int __devinit hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) |
3300 | { | 3269 | { |
3301 | ushort subsystem_vendor_id, subsystem_device_id, command; | 3270 | ushort subsystem_vendor_id, subsystem_device_id, command; |
3302 | u32 board_id, scratchpad = 0; | 3271 | u32 board_id, scratchpad = 0; |
@@ -3405,6 +3374,23 @@ static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) | |||
3405 | 3374 | ||
3406 | h->board_id = board_id; | 3375 | h->board_id = board_id; |
3407 | h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); | 3376 | h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); |
3377 | h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements)); | ||
3378 | |||
3379 | /* | ||
3380 | * Limit in-command s/g elements to 32 save dma'able memory. | ||
3381 | * Howvever spec says if 0, use 31 | ||
3382 | */ | ||
3383 | |||
3384 | h->max_cmd_sg_entries = 31; | ||
3385 | if (h->maxsgentries > 512) { | ||
3386 | h->max_cmd_sg_entries = 32; | ||
3387 | h->chainsize = h->maxsgentries - h->max_cmd_sg_entries + 1; | ||
3388 | h->maxsgentries--; /* save one for chain pointer */ | ||
3389 | } else { | ||
3390 | h->maxsgentries = 31; /* default to traditional values */ | ||
3391 | h->chainsize = 0; | ||
3392 | } | ||
3393 | |||
3408 | h->product_name = products[prod_index].product_name; | 3394 | h->product_name = products[prod_index].product_name; |
3409 | h->access = *(products[prod_index].access); | 3395 | h->access = *(products[prod_index].access); |
3410 | /* Allow room for some ioctls */ | 3396 | /* Allow room for some ioctls */ |
@@ -3532,8 +3518,6 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, | |||
3532 | h->busy_initializing = 1; | 3518 | h->busy_initializing = 1; |
3533 | INIT_HLIST_HEAD(&h->cmpQ); | 3519 | INIT_HLIST_HEAD(&h->cmpQ); |
3534 | INIT_HLIST_HEAD(&h->reqQ); | 3520 | INIT_HLIST_HEAD(&h->reqQ); |
3535 | mutex_init(&h->busy_shutting_down); | ||
3536 | init_completion(&h->scan_wait); | ||
3537 | rc = hpsa_pci_init(h, pdev); | 3521 | rc = hpsa_pci_init(h, pdev); |
3538 | if (rc != 0) | 3522 | if (rc != 0) |
3539 | goto clean1; | 3523 | goto clean1; |
@@ -3587,6 +3571,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, | |||
3587 | rc = -ENOMEM; | 3571 | rc = -ENOMEM; |
3588 | goto clean4; | 3572 | goto clean4; |
3589 | } | 3573 | } |
3574 | if (hpsa_allocate_sg_chain_blocks(h)) | ||
3575 | goto clean4; | ||
3590 | spin_lock_init(&h->lock); | 3576 | spin_lock_init(&h->lock); |
3591 | spin_lock_init(&h->scan_lock); | 3577 | spin_lock_init(&h->scan_lock); |
3592 | init_waitqueue_head(&h->scan_wait_queue); | 3578 | init_waitqueue_head(&h->scan_wait_queue); |
@@ -3609,6 +3595,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, | |||
3609 | return 1; | 3595 | return 1; |
3610 | 3596 | ||
3611 | clean4: | 3597 | clean4: |
3598 | hpsa_free_sg_chain_blocks(h); | ||
3612 | kfree(h->cmd_pool_bits); | 3599 | kfree(h->cmd_pool_bits); |
3613 | if (h->cmd_pool) | 3600 | if (h->cmd_pool) |
3614 | pci_free_consistent(h->pdev, | 3601 | pci_free_consistent(h->pdev, |
@@ -3681,11 +3668,10 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev) | |||
3681 | return; | 3668 | return; |
3682 | } | 3669 | } |
3683 | h = pci_get_drvdata(pdev); | 3670 | h = pci_get_drvdata(pdev); |
3684 | mutex_lock(&h->busy_shutting_down); | ||
3685 | remove_from_scan_list(h); | ||
3686 | hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */ | 3671 | hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */ |
3687 | hpsa_shutdown(pdev); | 3672 | hpsa_shutdown(pdev); |
3688 | iounmap(h->vaddr); | 3673 | iounmap(h->vaddr); |
3674 | hpsa_free_sg_chain_blocks(h); | ||
3689 | pci_free_consistent(h->pdev, | 3675 | pci_free_consistent(h->pdev, |
3690 | h->nr_cmds * sizeof(struct CommandList), | 3676 | h->nr_cmds * sizeof(struct CommandList), |
3691 | h->cmd_pool, h->cmd_pool_dhandle); | 3677 | h->cmd_pool, h->cmd_pool_dhandle); |
@@ -3703,7 +3689,6 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev) | |||
3703 | */ | 3689 | */ |
3704 | pci_release_regions(pdev); | 3690 | pci_release_regions(pdev); |
3705 | pci_set_drvdata(pdev, NULL); | 3691 | pci_set_drvdata(pdev, NULL); |
3706 | mutex_unlock(&h->busy_shutting_down); | ||
3707 | kfree(h); | 3692 | kfree(h); |
3708 | } | 3693 | } |
3709 | 3694 | ||
@@ -3857,23 +3842,12 @@ clean_up: | |||
3857 | */ | 3842 | */ |
3858 | static int __init hpsa_init(void) | 3843 | static int __init hpsa_init(void) |
3859 | { | 3844 | { |
3860 | int err; | 3845 | return pci_register_driver(&hpsa_pci_driver); |
3861 | /* Start the scan thread */ | ||
3862 | hpsa_scan_thread = kthread_run(hpsa_scan_func, NULL, "hpsa_scan"); | ||
3863 | if (IS_ERR(hpsa_scan_thread)) { | ||
3864 | err = PTR_ERR(hpsa_scan_thread); | ||
3865 | return -ENODEV; | ||
3866 | } | ||
3867 | err = pci_register_driver(&hpsa_pci_driver); | ||
3868 | if (err) | ||
3869 | kthread_stop(hpsa_scan_thread); | ||
3870 | return err; | ||
3871 | } | 3846 | } |
3872 | 3847 | ||
3873 | static void __exit hpsa_cleanup(void) | 3848 | static void __exit hpsa_cleanup(void) |
3874 | { | 3849 | { |
3875 | pci_unregister_driver(&hpsa_pci_driver); | 3850 | pci_unregister_driver(&hpsa_pci_driver); |
3876 | kthread_stop(hpsa_scan_thread); | ||
3877 | } | 3851 | } |
3878 | 3852 | ||
3879 | module_init(hpsa_init); | 3853 | module_init(hpsa_init); |
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index a0502b3ac17e..1bb5233b09a0 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h | |||
@@ -83,6 +83,10 @@ struct ctlr_info { | |||
83 | unsigned int maxQsinceinit; | 83 | unsigned int maxQsinceinit; |
84 | unsigned int maxSG; | 84 | unsigned int maxSG; |
85 | spinlock_t lock; | 85 | spinlock_t lock; |
86 | int maxsgentries; | ||
87 | u8 max_cmd_sg_entries; | ||
88 | int chainsize; | ||
89 | struct SGDescriptor **cmd_sg_list; | ||
86 | 90 | ||
87 | /* pointers to command and error info pool */ | 91 | /* pointers to command and error info pool */ |
88 | struct CommandList *cmd_pool; | 92 | struct CommandList *cmd_pool; |
@@ -97,9 +101,6 @@ struct ctlr_info { | |||
97 | int scan_finished; | 101 | int scan_finished; |
98 | spinlock_t scan_lock; | 102 | spinlock_t scan_lock; |
99 | wait_queue_head_t scan_wait_queue; | 103 | wait_queue_head_t scan_wait_queue; |
100 | struct mutex busy_shutting_down; | ||
101 | struct list_head scan_list; | ||
102 | struct completion scan_wait; | ||
103 | 104 | ||
104 | struct Scsi_Host *scsi_host; | 105 | struct Scsi_Host *scsi_host; |
105 | spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */ | 106 | spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */ |
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h index 3e0abdf76689..56fb9827681e 100644 --- a/drivers/scsi/hpsa_cmd.h +++ b/drivers/scsi/hpsa_cmd.h | |||
@@ -23,7 +23,8 @@ | |||
23 | 23 | ||
24 | /* general boundary defintions */ | 24 | /* general boundary defintions */ |
25 | #define SENSEINFOBYTES 32 /* may vary between hbas */ | 25 | #define SENSEINFOBYTES 32 /* may vary between hbas */ |
26 | #define MAXSGENTRIES 31 | 26 | #define MAXSGENTRIES 32 |
27 | #define HPSA_SG_CHAIN 0x80000000 | ||
27 | #define MAXREPLYQS 256 | 28 | #define MAXREPLYQS 256 |
28 | 29 | ||
29 | /* Command Status value */ | 30 | /* Command Status value */ |
@@ -305,20 +306,23 @@ struct CommandList { | |||
305 | int cmd_type; | 306 | int cmd_type; |
306 | long cmdindex; | 307 | long cmdindex; |
307 | struct hlist_node list; | 308 | struct hlist_node list; |
308 | struct CommandList *prev; | ||
309 | struct CommandList *next; | ||
310 | struct request *rq; | 309 | struct request *rq; |
311 | struct completion *waiting; | 310 | struct completion *waiting; |
312 | int retry_count; | ||
313 | void *scsi_cmd; | 311 | void *scsi_cmd; |
314 | 312 | ||
315 | /* on 64 bit architectures, to get this to be 32-byte-aligned | 313 | /* on 64 bit architectures, to get this to be 32-byte-aligned |
316 | * it so happens we need no padding, on 32 bit systems, | 314 | * it so happens we need PAD_64 bytes of padding, on 32 bit systems, |
317 | * we need 8 bytes of padding. This does that. | 315 | * we need PAD_32 bytes of padding (see below). This does that. |
316 | * If it happens that 64 bit and 32 bit systems need different | ||
317 | * padding, PAD_32 and PAD_64 can be set independently, and. | ||
318 | * the code below will do the right thing. | ||
318 | */ | 319 | */ |
319 | #define COMMANDLIST_PAD ((8 - sizeof(long))/4 * 8) | 320 | #define IS_32_BIT ((8 - sizeof(long))/4) |
321 | #define IS_64_BIT (!IS_32_BIT) | ||
322 | #define PAD_32 (4) | ||
323 | #define PAD_64 (4) | ||
324 | #define COMMANDLIST_PAD (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64) | ||
320 | u8 pad[COMMANDLIST_PAD]; | 325 | u8 pad[COMMANDLIST_PAD]; |
321 | |||
322 | }; | 326 | }; |
323 | 327 | ||
324 | /* Configuration Table Structure */ | 328 | /* Configuration Table Structure */ |
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 732f6d35b4a8..4e577e2fee38 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/kthread.h> | 30 | #include <linux/kthread.h> |
31 | #include <linux/of.h> | 31 | #include <linux/of.h> |
32 | #include <linux/pm.h> | ||
32 | #include <linux/stringify.h> | 33 | #include <linux/stringify.h> |
33 | #include <asm/firmware.h> | 34 | #include <asm/firmware.h> |
34 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
@@ -4736,6 +4737,27 @@ static int ibmvfc_remove(struct vio_dev *vdev) | |||
4736 | } | 4737 | } |
4737 | 4738 | ||
4738 | /** | 4739 | /** |
4740 | * ibmvfc_resume - Resume from suspend | ||
4741 | * @dev: device struct | ||
4742 | * | ||
4743 | * We may have lost an interrupt across suspend/resume, so kick the | ||
4744 | * interrupt handler | ||
4745 | * | ||
4746 | */ | ||
4747 | static int ibmvfc_resume(struct device *dev) | ||
4748 | { | ||
4749 | unsigned long flags; | ||
4750 | struct ibmvfc_host *vhost = dev_get_drvdata(dev); | ||
4751 | struct vio_dev *vdev = to_vio_dev(dev); | ||
4752 | |||
4753 | spin_lock_irqsave(vhost->host->host_lock, flags); | ||
4754 | vio_disable_interrupts(vdev); | ||
4755 | tasklet_schedule(&vhost->tasklet); | ||
4756 | spin_unlock_irqrestore(vhost->host->host_lock, flags); | ||
4757 | return 0; | ||
4758 | } | ||
4759 | |||
4760 | /** | ||
4739 | * ibmvfc_get_desired_dma - Calculate DMA resources needed by the driver | 4761 | * ibmvfc_get_desired_dma - Calculate DMA resources needed by the driver |
4740 | * @vdev: vio device struct | 4762 | * @vdev: vio device struct |
4741 | * | 4763 | * |
@@ -4755,6 +4777,10 @@ static struct vio_device_id ibmvfc_device_table[] __devinitdata = { | |||
4755 | }; | 4777 | }; |
4756 | MODULE_DEVICE_TABLE(vio, ibmvfc_device_table); | 4778 | MODULE_DEVICE_TABLE(vio, ibmvfc_device_table); |
4757 | 4779 | ||
4780 | static struct dev_pm_ops ibmvfc_pm_ops = { | ||
4781 | .resume = ibmvfc_resume | ||
4782 | }; | ||
4783 | |||
4758 | static struct vio_driver ibmvfc_driver = { | 4784 | static struct vio_driver ibmvfc_driver = { |
4759 | .id_table = ibmvfc_device_table, | 4785 | .id_table = ibmvfc_device_table, |
4760 | .probe = ibmvfc_probe, | 4786 | .probe = ibmvfc_probe, |
@@ -4763,6 +4789,7 @@ static struct vio_driver ibmvfc_driver = { | |||
4763 | .driver = { | 4789 | .driver = { |
4764 | .name = IBMVFC_NAME, | 4790 | .name = IBMVFC_NAME, |
4765 | .owner = THIS_MODULE, | 4791 | .owner = THIS_MODULE, |
4792 | .pm = &ibmvfc_pm_ops, | ||
4766 | } | 4793 | } |
4767 | }; | 4794 | }; |
4768 | 4795 | ||
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index e3a18e0ef276..dc1bcbe3b176 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -71,6 +71,7 @@ | |||
71 | #include <linux/dma-mapping.h> | 71 | #include <linux/dma-mapping.h> |
72 | #include <linux/delay.h> | 72 | #include <linux/delay.h> |
73 | #include <linux/of.h> | 73 | #include <linux/of.h> |
74 | #include <linux/pm.h> | ||
74 | #include <asm/firmware.h> | 75 | #include <asm/firmware.h> |
75 | #include <asm/vio.h> | 76 | #include <asm/vio.h> |
76 | #include <scsi/scsi.h> | 77 | #include <scsi/scsi.h> |
@@ -1991,6 +1992,19 @@ static int ibmvscsi_remove(struct vio_dev *vdev) | |||
1991 | } | 1992 | } |
1992 | 1993 | ||
1993 | /** | 1994 | /** |
1995 | * ibmvscsi_resume: Resume from suspend | ||
1996 | * @dev: device struct | ||
1997 | * | ||
1998 | * We may have lost an interrupt across suspend/resume, so kick the | ||
1999 | * interrupt handler | ||
2000 | */ | ||
2001 | static int ibmvscsi_resume(struct device *dev) | ||
2002 | { | ||
2003 | struct ibmvscsi_host_data *hostdata = dev_get_drvdata(dev); | ||
2004 | return ibmvscsi_ops->resume(hostdata); | ||
2005 | } | ||
2006 | |||
2007 | /** | ||
1994 | * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we | 2008 | * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we |
1995 | * support. | 2009 | * support. |
1996 | */ | 2010 | */ |
@@ -2000,6 +2014,10 @@ static struct vio_device_id ibmvscsi_device_table[] __devinitdata = { | |||
2000 | }; | 2014 | }; |
2001 | MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table); | 2015 | MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table); |
2002 | 2016 | ||
2017 | static struct dev_pm_ops ibmvscsi_pm_ops = { | ||
2018 | .resume = ibmvscsi_resume | ||
2019 | }; | ||
2020 | |||
2003 | static struct vio_driver ibmvscsi_driver = { | 2021 | static struct vio_driver ibmvscsi_driver = { |
2004 | .id_table = ibmvscsi_device_table, | 2022 | .id_table = ibmvscsi_device_table, |
2005 | .probe = ibmvscsi_probe, | 2023 | .probe = ibmvscsi_probe, |
@@ -2008,6 +2026,7 @@ static struct vio_driver ibmvscsi_driver = { | |||
2008 | .driver = { | 2026 | .driver = { |
2009 | .name = "ibmvscsi", | 2027 | .name = "ibmvscsi", |
2010 | .owner = THIS_MODULE, | 2028 | .owner = THIS_MODULE, |
2029 | .pm = &ibmvscsi_pm_ops, | ||
2011 | } | 2030 | } |
2012 | }; | 2031 | }; |
2013 | 2032 | ||
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index 76425303def0..9cb7c6a773e1 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h | |||
@@ -120,6 +120,7 @@ struct ibmvscsi_ops { | |||
120 | struct ibmvscsi_host_data *hostdata); | 120 | struct ibmvscsi_host_data *hostdata); |
121 | int (*send_crq)(struct ibmvscsi_host_data *hostdata, | 121 | int (*send_crq)(struct ibmvscsi_host_data *hostdata, |
122 | u64 word1, u64 word2); | 122 | u64 word1, u64 word2); |
123 | int (*resume) (struct ibmvscsi_host_data *hostdata); | ||
123 | }; | 124 | }; |
124 | 125 | ||
125 | extern struct ibmvscsi_ops iseriesvscsi_ops; | 126 | extern struct ibmvscsi_ops iseriesvscsi_ops; |
diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index 0775fdee5fa8..f4776451a754 100644 --- a/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c | |||
@@ -158,10 +158,16 @@ static int iseriesvscsi_send_crq(struct ibmvscsi_host_data *hostdata, | |||
158 | 0); | 158 | 0); |
159 | } | 159 | } |
160 | 160 | ||
161 | static int iseriesvscsi_resume(struct ibmvscsi_host_data *hostdata) | ||
162 | { | ||
163 | return 0; | ||
164 | } | ||
165 | |||
161 | struct ibmvscsi_ops iseriesvscsi_ops = { | 166 | struct ibmvscsi_ops iseriesvscsi_ops = { |
162 | .init_crq_queue = iseriesvscsi_init_crq_queue, | 167 | .init_crq_queue = iseriesvscsi_init_crq_queue, |
163 | .release_crq_queue = iseriesvscsi_release_crq_queue, | 168 | .release_crq_queue = iseriesvscsi_release_crq_queue, |
164 | .reset_crq_queue = iseriesvscsi_reset_crq_queue, | 169 | .reset_crq_queue = iseriesvscsi_reset_crq_queue, |
165 | .reenable_crq_queue = iseriesvscsi_reenable_crq_queue, | 170 | .reenable_crq_queue = iseriesvscsi_reenable_crq_queue, |
166 | .send_crq = iseriesvscsi_send_crq, | 171 | .send_crq = iseriesvscsi_send_crq, |
172 | .resume = iseriesvscsi_resume, | ||
167 | }; | 173 | }; |
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 462a8574dad9..63a30cbbf9de 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c | |||
@@ -334,10 +334,23 @@ static int rpavscsi_reenable_crq_queue(struct crq_queue *queue, | |||
334 | return rc; | 334 | return rc; |
335 | } | 335 | } |
336 | 336 | ||
337 | /** | ||
338 | * rpavscsi_resume: - resume after suspend | ||
339 | * @hostdata: ibmvscsi_host_data of host | ||
340 | * | ||
341 | */ | ||
342 | static int rpavscsi_resume(struct ibmvscsi_host_data *hostdata) | ||
343 | { | ||
344 | vio_disable_interrupts(to_vio_dev(hostdata->dev)); | ||
345 | tasklet_schedule(&hostdata->srp_task); | ||
346 | return 0; | ||
347 | } | ||
348 | |||
337 | struct ibmvscsi_ops rpavscsi_ops = { | 349 | struct ibmvscsi_ops rpavscsi_ops = { |
338 | .init_crq_queue = rpavscsi_init_crq_queue, | 350 | .init_crq_queue = rpavscsi_init_crq_queue, |
339 | .release_crq_queue = rpavscsi_release_crq_queue, | 351 | .release_crq_queue = rpavscsi_release_crq_queue, |
340 | .reset_crq_queue = rpavscsi_reset_crq_queue, | 352 | .reset_crq_queue = rpavscsi_reset_crq_queue, |
341 | .reenable_crq_queue = rpavscsi_reenable_crq_queue, | 353 | .reenable_crq_queue = rpavscsi_reenable_crq_queue, |
342 | .send_crq = rpavscsi_send_crq, | 354 | .send_crq = rpavscsi_send_crq, |
355 | .resume = rpavscsi_resume, | ||
343 | }; | 356 | }; |
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 032f0d0e6cb4..c79cd98eb6bf 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -72,6 +72,8 @@ | |||
72 | #include <linux/moduleparam.h> | 72 | #include <linux/moduleparam.h> |
73 | #include <linux/libata.h> | 73 | #include <linux/libata.h> |
74 | #include <linux/hdreg.h> | 74 | #include <linux/hdreg.h> |
75 | #include <linux/reboot.h> | ||
76 | #include <linux/stringify.h> | ||
75 | #include <asm/io.h> | 77 | #include <asm/io.h> |
76 | #include <asm/irq.h> | 78 | #include <asm/irq.h> |
77 | #include <asm/processor.h> | 79 | #include <asm/processor.h> |
@@ -91,8 +93,8 @@ static unsigned int ipr_max_speed = 1; | |||
91 | static int ipr_testmode = 0; | 93 | static int ipr_testmode = 0; |
92 | static unsigned int ipr_fastfail = 0; | 94 | static unsigned int ipr_fastfail = 0; |
93 | static unsigned int ipr_transop_timeout = 0; | 95 | static unsigned int ipr_transop_timeout = 0; |
94 | static unsigned int ipr_enable_cache = 1; | ||
95 | static unsigned int ipr_debug = 0; | 96 | static unsigned int ipr_debug = 0; |
97 | static unsigned int ipr_max_devs = IPR_DEFAULT_SIS64_DEVS; | ||
96 | static unsigned int ipr_dual_ioa_raid = 1; | 98 | static unsigned int ipr_dual_ioa_raid = 1; |
97 | static DEFINE_SPINLOCK(ipr_driver_lock); | 99 | static DEFINE_SPINLOCK(ipr_driver_lock); |
98 | 100 | ||
@@ -104,13 +106,20 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { | |||
104 | { | 106 | { |
105 | .set_interrupt_mask_reg = 0x0022C, | 107 | .set_interrupt_mask_reg = 0x0022C, |
106 | .clr_interrupt_mask_reg = 0x00230, | 108 | .clr_interrupt_mask_reg = 0x00230, |
109 | .clr_interrupt_mask_reg32 = 0x00230, | ||
107 | .sense_interrupt_mask_reg = 0x0022C, | 110 | .sense_interrupt_mask_reg = 0x0022C, |
111 | .sense_interrupt_mask_reg32 = 0x0022C, | ||
108 | .clr_interrupt_reg = 0x00228, | 112 | .clr_interrupt_reg = 0x00228, |
113 | .clr_interrupt_reg32 = 0x00228, | ||
109 | .sense_interrupt_reg = 0x00224, | 114 | .sense_interrupt_reg = 0x00224, |
115 | .sense_interrupt_reg32 = 0x00224, | ||
110 | .ioarrin_reg = 0x00404, | 116 | .ioarrin_reg = 0x00404, |
111 | .sense_uproc_interrupt_reg = 0x00214, | 117 | .sense_uproc_interrupt_reg = 0x00214, |
118 | .sense_uproc_interrupt_reg32 = 0x00214, | ||
112 | .set_uproc_interrupt_reg = 0x00214, | 119 | .set_uproc_interrupt_reg = 0x00214, |
113 | .clr_uproc_interrupt_reg = 0x00218 | 120 | .set_uproc_interrupt_reg32 = 0x00214, |
121 | .clr_uproc_interrupt_reg = 0x00218, | ||
122 | .clr_uproc_interrupt_reg32 = 0x00218 | ||
114 | } | 123 | } |
115 | }, | 124 | }, |
116 | { /* Snipe and Scamp */ | 125 | { /* Snipe and Scamp */ |
@@ -119,25 +128,59 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { | |||
119 | { | 128 | { |
120 | .set_interrupt_mask_reg = 0x00288, | 129 | .set_interrupt_mask_reg = 0x00288, |
121 | .clr_interrupt_mask_reg = 0x0028C, | 130 | .clr_interrupt_mask_reg = 0x0028C, |
131 | .clr_interrupt_mask_reg32 = 0x0028C, | ||
122 | .sense_interrupt_mask_reg = 0x00288, | 132 | .sense_interrupt_mask_reg = 0x00288, |
133 | .sense_interrupt_mask_reg32 = 0x00288, | ||
123 | .clr_interrupt_reg = 0x00284, | 134 | .clr_interrupt_reg = 0x00284, |
135 | .clr_interrupt_reg32 = 0x00284, | ||
124 | .sense_interrupt_reg = 0x00280, | 136 | .sense_interrupt_reg = 0x00280, |
137 | .sense_interrupt_reg32 = 0x00280, | ||
125 | .ioarrin_reg = 0x00504, | 138 | .ioarrin_reg = 0x00504, |
126 | .sense_uproc_interrupt_reg = 0x00290, | 139 | .sense_uproc_interrupt_reg = 0x00290, |
140 | .sense_uproc_interrupt_reg32 = 0x00290, | ||
127 | .set_uproc_interrupt_reg = 0x00290, | 141 | .set_uproc_interrupt_reg = 0x00290, |
128 | .clr_uproc_interrupt_reg = 0x00294 | 142 | .set_uproc_interrupt_reg32 = 0x00290, |
143 | .clr_uproc_interrupt_reg = 0x00294, | ||
144 | .clr_uproc_interrupt_reg32 = 0x00294 | ||
145 | } | ||
146 | }, | ||
147 | { /* CRoC */ | ||
148 | .mailbox = 0x00040, | ||
149 | .cache_line_size = 0x20, | ||
150 | { | ||
151 | .set_interrupt_mask_reg = 0x00010, | ||
152 | .clr_interrupt_mask_reg = 0x00018, | ||
153 | .clr_interrupt_mask_reg32 = 0x0001C, | ||
154 | .sense_interrupt_mask_reg = 0x00010, | ||
155 | .sense_interrupt_mask_reg32 = 0x00014, | ||
156 | .clr_interrupt_reg = 0x00008, | ||
157 | .clr_interrupt_reg32 = 0x0000C, | ||
158 | .sense_interrupt_reg = 0x00000, | ||
159 | .sense_interrupt_reg32 = 0x00004, | ||
160 | .ioarrin_reg = 0x00070, | ||
161 | .sense_uproc_interrupt_reg = 0x00020, | ||
162 | .sense_uproc_interrupt_reg32 = 0x00024, | ||
163 | .set_uproc_interrupt_reg = 0x00020, | ||
164 | .set_uproc_interrupt_reg32 = 0x00024, | ||
165 | .clr_uproc_interrupt_reg = 0x00028, | ||
166 | .clr_uproc_interrupt_reg32 = 0x0002C, | ||
167 | .init_feedback_reg = 0x0005C, | ||
168 | .dump_addr_reg = 0x00064, | ||
169 | .dump_data_reg = 0x00068 | ||
129 | } | 170 | } |
130 | }, | 171 | }, |
131 | }; | 172 | }; |
132 | 173 | ||
133 | static const struct ipr_chip_t ipr_chip[] = { | 174 | static const struct ipr_chip_t ipr_chip[] = { |
134 | { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, &ipr_chip_cfg[0] }, | 175 | { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, |
135 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, &ipr_chip_cfg[0] }, | 176 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, |
136 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] }, | 177 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, |
137 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] }, | 178 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, |
138 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, &ipr_chip_cfg[0] }, | 179 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, IPR_SIS32, &ipr_chip_cfg[0] }, |
139 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, &ipr_chip_cfg[1] }, | 180 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] }, |
140 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, &ipr_chip_cfg[1] } | 181 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] }, |
182 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] }, | ||
183 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] } | ||
141 | }; | 184 | }; |
142 | 185 | ||
143 | static int ipr_max_bus_speeds [] = { | 186 | static int ipr_max_bus_speeds [] = { |
@@ -156,12 +199,13 @@ module_param_named(fastfail, ipr_fastfail, int, S_IRUGO | S_IWUSR); | |||
156 | MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries"); | 199 | MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries"); |
157 | module_param_named(transop_timeout, ipr_transop_timeout, int, 0); | 200 | module_param_named(transop_timeout, ipr_transop_timeout, int, 0); |
158 | MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)"); | 201 | MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)"); |
159 | module_param_named(enable_cache, ipr_enable_cache, int, 0); | ||
160 | MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)"); | ||
161 | module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR); | 202 | module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR); |
162 | MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); | 203 | MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); |
163 | module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0); | 204 | module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0); |
164 | MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)"); | 205 | MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)"); |
206 | module_param_named(max_devs, ipr_max_devs, int, 0); | ||
207 | MODULE_PARM_DESC(max_devs, "Specify the maximum number of physical devices. " | ||
208 | "[Default=" __stringify(IPR_DEFAULT_SIS64_DEVS) "]"); | ||
165 | MODULE_LICENSE("GPL"); | 209 | MODULE_LICENSE("GPL"); |
166 | MODULE_VERSION(IPR_DRIVER_VERSION); | 210 | MODULE_VERSION(IPR_DRIVER_VERSION); |
167 | 211 | ||
@@ -180,6 +224,20 @@ struct ipr_error_table_t ipr_error_table[] = { | |||
180 | "FFFE: Soft device bus error recovered by the IOA"}, | 224 | "FFFE: Soft device bus error recovered by the IOA"}, |
181 | {0x01088100, 0, IPR_DEFAULT_LOG_LEVEL, | 225 | {0x01088100, 0, IPR_DEFAULT_LOG_LEVEL, |
182 | "4101: Soft device bus fabric error"}, | 226 | "4101: Soft device bus fabric error"}, |
227 | {0x01100100, 0, IPR_DEFAULT_LOG_LEVEL, | ||
228 | "FFFC: Logical block guard error recovered by the device"}, | ||
229 | {0x01100300, 0, IPR_DEFAULT_LOG_LEVEL, | ||
230 | "FFFC: Logical block reference tag error recovered by the device"}, | ||
231 | {0x01108300, 0, IPR_DEFAULT_LOG_LEVEL, | ||
232 | "4171: Recovered scatter list tag / sequence number error"}, | ||
233 | {0x01109000, 0, IPR_DEFAULT_LOG_LEVEL, | ||
234 | "FF3D: Recovered logical block CRC error on IOA to Host transfer"}, | ||
235 | {0x01109200, 0, IPR_DEFAULT_LOG_LEVEL, | ||
236 | "4171: Recovered logical block sequence number error on IOA to Host transfer"}, | ||
237 | {0x0110A000, 0, IPR_DEFAULT_LOG_LEVEL, | ||
238 | "FFFD: Recovered logical block reference tag error detected by the IOA"}, | ||
239 | {0x0110A100, 0, IPR_DEFAULT_LOG_LEVEL, | ||
240 | "FFFD: Logical block guard error recovered by the IOA"}, | ||
183 | {0x01170600, 0, IPR_DEFAULT_LOG_LEVEL, | 241 | {0x01170600, 0, IPR_DEFAULT_LOG_LEVEL, |
184 | "FFF9: Device sector reassign successful"}, | 242 | "FFF9: Device sector reassign successful"}, |
185 | {0x01170900, 0, IPR_DEFAULT_LOG_LEVEL, | 243 | {0x01170900, 0, IPR_DEFAULT_LOG_LEVEL, |
@@ -236,12 +294,28 @@ struct ipr_error_table_t ipr_error_table[] = { | |||
236 | "3120: SCSI bus is not operational"}, | 294 | "3120: SCSI bus is not operational"}, |
237 | {0x04088100, 0, IPR_DEFAULT_LOG_LEVEL, | 295 | {0x04088100, 0, IPR_DEFAULT_LOG_LEVEL, |
238 | "4100: Hard device bus fabric error"}, | 296 | "4100: Hard device bus fabric error"}, |
297 | {0x04100100, 0, IPR_DEFAULT_LOG_LEVEL, | ||
298 | "310C: Logical block guard error detected by the device"}, | ||
299 | {0x04100300, 0, IPR_DEFAULT_LOG_LEVEL, | ||
300 | "310C: Logical block reference tag error detected by the device"}, | ||
301 | {0x04108300, 1, IPR_DEFAULT_LOG_LEVEL, | ||
302 | "4170: Scatter list tag / sequence number error"}, | ||
303 | {0x04109000, 1, IPR_DEFAULT_LOG_LEVEL, | ||
304 | "8150: Logical block CRC error on IOA to Host transfer"}, | ||
305 | {0x04109200, 1, IPR_DEFAULT_LOG_LEVEL, | ||
306 | "4170: Logical block sequence number error on IOA to Host transfer"}, | ||
307 | {0x0410A000, 0, IPR_DEFAULT_LOG_LEVEL, | ||
308 | "310D: Logical block reference tag error detected by the IOA"}, | ||
309 | {0x0410A100, 0, IPR_DEFAULT_LOG_LEVEL, | ||
310 | "310D: Logical block guard error detected by the IOA"}, | ||
239 | {0x04118000, 0, IPR_DEFAULT_LOG_LEVEL, | 311 | {0x04118000, 0, IPR_DEFAULT_LOG_LEVEL, |
240 | "9000: IOA reserved area data check"}, | 312 | "9000: IOA reserved area data check"}, |
241 | {0x04118100, 0, IPR_DEFAULT_LOG_LEVEL, | 313 | {0x04118100, 0, IPR_DEFAULT_LOG_LEVEL, |
242 | "9001: IOA reserved area invalid data pattern"}, | 314 | "9001: IOA reserved area invalid data pattern"}, |
243 | {0x04118200, 0, IPR_DEFAULT_LOG_LEVEL, | 315 | {0x04118200, 0, IPR_DEFAULT_LOG_LEVEL, |
244 | "9002: IOA reserved area LRC error"}, | 316 | "9002: IOA reserved area LRC error"}, |
317 | {0x04118300, 1, IPR_DEFAULT_LOG_LEVEL, | ||
318 | "Hardware Error, IOA metadata access error"}, | ||
245 | {0x04320000, 0, IPR_DEFAULT_LOG_LEVEL, | 319 | {0x04320000, 0, IPR_DEFAULT_LOG_LEVEL, |
246 | "102E: Out of alternate sectors for disk storage"}, | 320 | "102E: Out of alternate sectors for disk storage"}, |
247 | {0x04330000, 1, IPR_DEFAULT_LOG_LEVEL, | 321 | {0x04330000, 1, IPR_DEFAULT_LOG_LEVEL, |
@@ -306,6 +380,8 @@ struct ipr_error_table_t ipr_error_table[] = { | |||
306 | "Illegal request, commands not allowed to this device"}, | 380 | "Illegal request, commands not allowed to this device"}, |
307 | {0x05258100, 0, 0, | 381 | {0x05258100, 0, 0, |
308 | "Illegal request, command not allowed to a secondary adapter"}, | 382 | "Illegal request, command not allowed to a secondary adapter"}, |
383 | {0x05258200, 0, 0, | ||
384 | "Illegal request, command not allowed to a non-optimized resource"}, | ||
309 | {0x05260000, 0, 0, | 385 | {0x05260000, 0, 0, |
310 | "Illegal request, invalid field in parameter list"}, | 386 | "Illegal request, invalid field in parameter list"}, |
311 | {0x05260100, 0, 0, | 387 | {0x05260100, 0, 0, |
@@ -468,7 +544,10 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd, | |||
468 | trace_entry->time = jiffies; | 544 | trace_entry->time = jiffies; |
469 | trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0]; | 545 | trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0]; |
470 | trace_entry->type = type; | 546 | trace_entry->type = type; |
471 | trace_entry->ata_op_code = ipr_cmd->ioarcb.add_data.u.regs.command; | 547 | if (ipr_cmd->ioa_cfg->sis64) |
548 | trace_entry->ata_op_code = ipr_cmd->i.ata_ioadl.regs.command; | ||
549 | else | ||
550 | trace_entry->ata_op_code = ipr_cmd->ioarcb.u.add_data.u.regs.command; | ||
472 | trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff; | 551 | trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff; |
473 | trace_entry->res_handle = ipr_cmd->ioarcb.res_handle; | 552 | trace_entry->res_handle = ipr_cmd->ioarcb.res_handle; |
474 | trace_entry->u.add_data = add_data; | 553 | trace_entry->u.add_data = add_data; |
@@ -488,16 +567,23 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd) | |||
488 | { | 567 | { |
489 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 568 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
490 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; | 569 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; |
491 | dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr); | 570 | dma_addr_t dma_addr = ipr_cmd->dma_addr; |
492 | 571 | ||
493 | memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); | 572 | memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); |
494 | ioarcb->write_data_transfer_length = 0; | 573 | ioarcb->data_transfer_length = 0; |
495 | ioarcb->read_data_transfer_length = 0; | 574 | ioarcb->read_data_transfer_length = 0; |
496 | ioarcb->write_ioadl_len = 0; | 575 | ioarcb->ioadl_len = 0; |
497 | ioarcb->read_ioadl_len = 0; | 576 | ioarcb->read_ioadl_len = 0; |
498 | ioarcb->write_ioadl_addr = | 577 | |
499 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); | 578 | if (ipr_cmd->ioa_cfg->sis64) |
500 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | 579 | ioarcb->u.sis64_addr_data.data_ioadl_addr = |
580 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); | ||
581 | else { | ||
582 | ioarcb->write_ioadl_addr = | ||
583 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); | ||
584 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | ||
585 | } | ||
586 | |||
501 | ioasa->ioasc = 0; | 587 | ioasa->ioasc = 0; |
502 | ioasa->residual_data_len = 0; | 588 | ioasa->residual_data_len = 0; |
503 | ioasa->u.gata.status = 0; | 589 | ioasa->u.gata.status = 0; |
@@ -562,10 +648,15 @@ static void ipr_mask_and_clear_interrupts(struct ipr_ioa_cfg *ioa_cfg, | |||
562 | ioa_cfg->allow_interrupts = 0; | 648 | ioa_cfg->allow_interrupts = 0; |
563 | 649 | ||
564 | /* Set interrupt mask to stop all new interrupts */ | 650 | /* Set interrupt mask to stop all new interrupts */ |
565 | writel(~0, ioa_cfg->regs.set_interrupt_mask_reg); | 651 | if (ioa_cfg->sis64) |
652 | writeq(~0, ioa_cfg->regs.set_interrupt_mask_reg); | ||
653 | else | ||
654 | writel(~0, ioa_cfg->regs.set_interrupt_mask_reg); | ||
566 | 655 | ||
567 | /* Clear any pending interrupts */ | 656 | /* Clear any pending interrupts */ |
568 | writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg); | 657 | if (ioa_cfg->sis64) |
658 | writel(~0, ioa_cfg->regs.clr_interrupt_reg); | ||
659 | writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg32); | ||
569 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); | 660 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); |
570 | } | 661 | } |
571 | 662 | ||
@@ -693,6 +784,35 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg) | |||
693 | } | 784 | } |
694 | 785 | ||
695 | /** | 786 | /** |
787 | * ipr_send_command - Send driver initiated requests. | ||
788 | * @ipr_cmd: ipr command struct | ||
789 | * | ||
790 | * This function sends a command to the adapter using the correct write call. | ||
791 | * In the case of sis64, calculate the ioarcb size required. Then or in the | ||
792 | * appropriate bits. | ||
793 | * | ||
794 | * Return value: | ||
795 | * none | ||
796 | **/ | ||
797 | static void ipr_send_command(struct ipr_cmnd *ipr_cmd) | ||
798 | { | ||
799 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
800 | dma_addr_t send_dma_addr = ipr_cmd->dma_addr; | ||
801 | |||
802 | if (ioa_cfg->sis64) { | ||
803 | /* The default size is 256 bytes */ | ||
804 | send_dma_addr |= 0x1; | ||
805 | |||
806 | /* If the number of ioadls * size of ioadl > 128 bytes, | ||
807 | then use a 512 byte ioarcb */ | ||
808 | if (ipr_cmd->dma_use_sg * sizeof(struct ipr_ioadl64_desc) > 128 ) | ||
809 | send_dma_addr |= 0x4; | ||
810 | writeq(send_dma_addr, ioa_cfg->regs.ioarrin_reg); | ||
811 | } else | ||
812 | writel(send_dma_addr, ioa_cfg->regs.ioarrin_reg); | ||
813 | } | ||
814 | |||
815 | /** | ||
696 | * ipr_do_req - Send driver initiated requests. | 816 | * ipr_do_req - Send driver initiated requests. |
697 | * @ipr_cmd: ipr command struct | 817 | * @ipr_cmd: ipr command struct |
698 | * @done: done function | 818 | * @done: done function |
@@ -724,8 +844,8 @@ static void ipr_do_req(struct ipr_cmnd *ipr_cmd, | |||
724 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0); | 844 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0); |
725 | 845 | ||
726 | mb(); | 846 | mb(); |
727 | writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr), | 847 | |
728 | ioa_cfg->regs.ioarrin_reg); | 848 | ipr_send_command(ipr_cmd); |
729 | } | 849 | } |
730 | 850 | ||
731 | /** | 851 | /** |
@@ -747,6 +867,51 @@ static void ipr_internal_cmd_done(struct ipr_cmnd *ipr_cmd) | |||
747 | } | 867 | } |
748 | 868 | ||
749 | /** | 869 | /** |
870 | * ipr_init_ioadl - initialize the ioadl for the correct SIS type | ||
871 | * @ipr_cmd: ipr command struct | ||
872 | * @dma_addr: dma address | ||
873 | * @len: transfer length | ||
874 | * @flags: ioadl flag value | ||
875 | * | ||
876 | * This function initializes an ioadl in the case where there is only a single | ||
877 | * descriptor. | ||
878 | * | ||
879 | * Return value: | ||
880 | * nothing | ||
881 | **/ | ||
882 | static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr, | ||
883 | u32 len, int flags) | ||
884 | { | ||
885 | struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl; | ||
886 | struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; | ||
887 | |||
888 | ipr_cmd->dma_use_sg = 1; | ||
889 | |||
890 | if (ipr_cmd->ioa_cfg->sis64) { | ||
891 | ioadl64->flags = cpu_to_be32(flags); | ||
892 | ioadl64->data_len = cpu_to_be32(len); | ||
893 | ioadl64->address = cpu_to_be64(dma_addr); | ||
894 | |||
895 | ipr_cmd->ioarcb.ioadl_len = | ||
896 | cpu_to_be32(sizeof(struct ipr_ioadl64_desc)); | ||
897 | ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len); | ||
898 | } else { | ||
899 | ioadl->flags_and_data_len = cpu_to_be32(flags | len); | ||
900 | ioadl->address = cpu_to_be32(dma_addr); | ||
901 | |||
902 | if (flags == IPR_IOADL_FLAGS_READ_LAST) { | ||
903 | ipr_cmd->ioarcb.read_ioadl_len = | ||
904 | cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | ||
905 | ipr_cmd->ioarcb.read_data_transfer_length = cpu_to_be32(len); | ||
906 | } else { | ||
907 | ipr_cmd->ioarcb.ioadl_len = | ||
908 | cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | ||
909 | ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len); | ||
910 | } | ||
911 | } | ||
912 | } | ||
913 | |||
914 | /** | ||
750 | * ipr_send_blocking_cmd - Send command and sleep on its completion. | 915 | * ipr_send_blocking_cmd - Send command and sleep on its completion. |
751 | * @ipr_cmd: ipr command struct | 916 | * @ipr_cmd: ipr command struct |
752 | * @timeout_func: function to invoke if command times out | 917 | * @timeout_func: function to invoke if command times out |
@@ -803,11 +968,8 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type, | |||
803 | ioarcb->cmd_pkt.cdb[7] = (sizeof(hostrcb->hcam) >> 8) & 0xff; | 968 | ioarcb->cmd_pkt.cdb[7] = (sizeof(hostrcb->hcam) >> 8) & 0xff; |
804 | ioarcb->cmd_pkt.cdb[8] = sizeof(hostrcb->hcam) & 0xff; | 969 | ioarcb->cmd_pkt.cdb[8] = sizeof(hostrcb->hcam) & 0xff; |
805 | 970 | ||
806 | ioarcb->read_data_transfer_length = cpu_to_be32(sizeof(hostrcb->hcam)); | 971 | ipr_init_ioadl(ipr_cmd, hostrcb->hostrcb_dma, |
807 | ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | 972 | sizeof(hostrcb->hcam), IPR_IOADL_FLAGS_READ_LAST); |
808 | ipr_cmd->ioadl[0].flags_and_data_len = | ||
809 | cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(hostrcb->hcam)); | ||
810 | ipr_cmd->ioadl[0].address = cpu_to_be32(hostrcb->hostrcb_dma); | ||
811 | 973 | ||
812 | if (type == IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE) | 974 | if (type == IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE) |
813 | ipr_cmd->done = ipr_process_ccn; | 975 | ipr_cmd->done = ipr_process_ccn; |
@@ -817,22 +979,54 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type, | |||
817 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR); | 979 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR); |
818 | 980 | ||
819 | mb(); | 981 | mb(); |
820 | writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr), | 982 | |
821 | ioa_cfg->regs.ioarrin_reg); | 983 | ipr_send_command(ipr_cmd); |
822 | } else { | 984 | } else { |
823 | list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q); | 985 | list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q); |
824 | } | 986 | } |
825 | } | 987 | } |
826 | 988 | ||
827 | /** | 989 | /** |
990 | * ipr_update_ata_class - Update the ata class in the resource entry | ||
991 | * @res: resource entry struct | ||
992 | * @proto: cfgte device bus protocol value | ||
993 | * | ||
994 | * Return value: | ||
995 | * none | ||
996 | **/ | ||
997 | static void ipr_update_ata_class(struct ipr_resource_entry *res, unsigned int proto) | ||
998 | { | ||
999 | switch(proto) { | ||
1000 | case IPR_PROTO_SATA: | ||
1001 | case IPR_PROTO_SAS_STP: | ||
1002 | res->ata_class = ATA_DEV_ATA; | ||
1003 | break; | ||
1004 | case IPR_PROTO_SATA_ATAPI: | ||
1005 | case IPR_PROTO_SAS_STP_ATAPI: | ||
1006 | res->ata_class = ATA_DEV_ATAPI; | ||
1007 | break; | ||
1008 | default: | ||
1009 | res->ata_class = ATA_DEV_UNKNOWN; | ||
1010 | break; | ||
1011 | }; | ||
1012 | } | ||
1013 | |||
1014 | /** | ||
828 | * ipr_init_res_entry - Initialize a resource entry struct. | 1015 | * ipr_init_res_entry - Initialize a resource entry struct. |
829 | * @res: resource entry struct | 1016 | * @res: resource entry struct |
1017 | * @cfgtew: config table entry wrapper struct | ||
830 | * | 1018 | * |
831 | * Return value: | 1019 | * Return value: |
832 | * none | 1020 | * none |
833 | **/ | 1021 | **/ |
834 | static void ipr_init_res_entry(struct ipr_resource_entry *res) | 1022 | static void ipr_init_res_entry(struct ipr_resource_entry *res, |
1023 | struct ipr_config_table_entry_wrapper *cfgtew) | ||
835 | { | 1024 | { |
1025 | int found = 0; | ||
1026 | unsigned int proto; | ||
1027 | struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg; | ||
1028 | struct ipr_resource_entry *gscsi_res = NULL; | ||
1029 | |||
836 | res->needs_sync_complete = 0; | 1030 | res->needs_sync_complete = 0; |
837 | res->in_erp = 0; | 1031 | res->in_erp = 0; |
838 | res->add_to_ml = 0; | 1032 | res->add_to_ml = 0; |
@@ -840,6 +1034,205 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res) | |||
840 | res->resetting_device = 0; | 1034 | res->resetting_device = 0; |
841 | res->sdev = NULL; | 1035 | res->sdev = NULL; |
842 | res->sata_port = NULL; | 1036 | res->sata_port = NULL; |
1037 | |||
1038 | if (ioa_cfg->sis64) { | ||
1039 | proto = cfgtew->u.cfgte64->proto; | ||
1040 | res->res_flags = cfgtew->u.cfgte64->res_flags; | ||
1041 | res->qmodel = IPR_QUEUEING_MODEL64(res); | ||
1042 | res->type = cfgtew->u.cfgte64->res_type & 0x0f; | ||
1043 | |||
1044 | memcpy(res->res_path, &cfgtew->u.cfgte64->res_path, | ||
1045 | sizeof(res->res_path)); | ||
1046 | |||
1047 | res->bus = 0; | ||
1048 | res->lun = scsilun_to_int(&res->dev_lun); | ||
1049 | |||
1050 | if (res->type == IPR_RES_TYPE_GENERIC_SCSI) { | ||
1051 | list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue) { | ||
1052 | if (gscsi_res->dev_id == cfgtew->u.cfgte64->dev_id) { | ||
1053 | found = 1; | ||
1054 | res->target = gscsi_res->target; | ||
1055 | break; | ||
1056 | } | ||
1057 | } | ||
1058 | if (!found) { | ||
1059 | res->target = find_first_zero_bit(ioa_cfg->target_ids, | ||
1060 | ioa_cfg->max_devs_supported); | ||
1061 | set_bit(res->target, ioa_cfg->target_ids); | ||
1062 | } | ||
1063 | |||
1064 | memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun, | ||
1065 | sizeof(res->dev_lun.scsi_lun)); | ||
1066 | } else if (res->type == IPR_RES_TYPE_IOAFP) { | ||
1067 | res->bus = IPR_IOAFP_VIRTUAL_BUS; | ||
1068 | res->target = 0; | ||
1069 | } else if (res->type == IPR_RES_TYPE_ARRAY) { | ||
1070 | res->bus = IPR_ARRAY_VIRTUAL_BUS; | ||
1071 | res->target = find_first_zero_bit(ioa_cfg->array_ids, | ||
1072 | ioa_cfg->max_devs_supported); | ||
1073 | set_bit(res->target, ioa_cfg->array_ids); | ||
1074 | } else if (res->type == IPR_RES_TYPE_VOLUME_SET) { | ||
1075 | res->bus = IPR_VSET_VIRTUAL_BUS; | ||
1076 | res->target = find_first_zero_bit(ioa_cfg->vset_ids, | ||
1077 | ioa_cfg->max_devs_supported); | ||
1078 | set_bit(res->target, ioa_cfg->vset_ids); | ||
1079 | } else { | ||
1080 | res->target = find_first_zero_bit(ioa_cfg->target_ids, | ||
1081 | ioa_cfg->max_devs_supported); | ||
1082 | set_bit(res->target, ioa_cfg->target_ids); | ||
1083 | } | ||
1084 | } else { | ||
1085 | proto = cfgtew->u.cfgte->proto; | ||
1086 | res->qmodel = IPR_QUEUEING_MODEL(res); | ||
1087 | res->flags = cfgtew->u.cfgte->flags; | ||
1088 | if (res->flags & IPR_IS_IOA_RESOURCE) | ||
1089 | res->type = IPR_RES_TYPE_IOAFP; | ||
1090 | else | ||
1091 | res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f; | ||
1092 | |||
1093 | res->bus = cfgtew->u.cfgte->res_addr.bus; | ||
1094 | res->target = cfgtew->u.cfgte->res_addr.target; | ||
1095 | res->lun = cfgtew->u.cfgte->res_addr.lun; | ||
1096 | } | ||
1097 | |||
1098 | ipr_update_ata_class(res, proto); | ||
1099 | } | ||
1100 | |||
1101 | /** | ||
1102 | * ipr_is_same_device - Determine if two devices are the same. | ||
1103 | * @res: resource entry struct | ||
1104 | * @cfgtew: config table entry wrapper struct | ||
1105 | * | ||
1106 | * Return value: | ||
1107 | * 1 if the devices are the same / 0 otherwise | ||
1108 | **/ | ||
1109 | static int ipr_is_same_device(struct ipr_resource_entry *res, | ||
1110 | struct ipr_config_table_entry_wrapper *cfgtew) | ||
1111 | { | ||
1112 | if (res->ioa_cfg->sis64) { | ||
1113 | if (!memcmp(&res->dev_id, &cfgtew->u.cfgte64->dev_id, | ||
1114 | sizeof(cfgtew->u.cfgte64->dev_id)) && | ||
1115 | !memcmp(&res->lun, &cfgtew->u.cfgte64->lun, | ||
1116 | sizeof(cfgtew->u.cfgte64->lun))) { | ||
1117 | return 1; | ||
1118 | } | ||
1119 | } else { | ||
1120 | if (res->bus == cfgtew->u.cfgte->res_addr.bus && | ||
1121 | res->target == cfgtew->u.cfgte->res_addr.target && | ||
1122 | res->lun == cfgtew->u.cfgte->res_addr.lun) | ||
1123 | return 1; | ||
1124 | } | ||
1125 | |||
1126 | return 0; | ||
1127 | } | ||
1128 | |||
1129 | /** | ||
1130 | * ipr_format_resource_path - Format the resource path for printing. | ||
1131 | * @res_path: resource path | ||
1132 | * @buf: buffer | ||
1133 | * | ||
1134 | * Return value: | ||
1135 | * pointer to buffer | ||
1136 | **/ | ||
1137 | static char *ipr_format_resource_path(u8 *res_path, char *buffer) | ||
1138 | { | ||
1139 | int i; | ||
1140 | |||
1141 | sprintf(buffer, "%02X", res_path[0]); | ||
1142 | for (i=1; res_path[i] != 0xff; i++) | ||
1143 | sprintf(buffer, "%s-%02X", buffer, res_path[i]); | ||
1144 | |||
1145 | return buffer; | ||
1146 | } | ||
1147 | |||
1148 | /** | ||
1149 | * ipr_update_res_entry - Update the resource entry. | ||
1150 | * @res: resource entry struct | ||
1151 | * @cfgtew: config table entry wrapper struct | ||
1152 | * | ||
1153 | * Return value: | ||
1154 | * none | ||
1155 | **/ | ||
1156 | static void ipr_update_res_entry(struct ipr_resource_entry *res, | ||
1157 | struct ipr_config_table_entry_wrapper *cfgtew) | ||
1158 | { | ||
1159 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
1160 | unsigned int proto; | ||
1161 | int new_path = 0; | ||
1162 | |||
1163 | if (res->ioa_cfg->sis64) { | ||
1164 | res->flags = cfgtew->u.cfgte64->flags; | ||
1165 | res->res_flags = cfgtew->u.cfgte64->res_flags; | ||
1166 | res->type = cfgtew->u.cfgte64->res_type & 0x0f; | ||
1167 | |||
1168 | memcpy(&res->std_inq_data, &cfgtew->u.cfgte64->std_inq_data, | ||
1169 | sizeof(struct ipr_std_inq_data)); | ||
1170 | |||
1171 | res->qmodel = IPR_QUEUEING_MODEL64(res); | ||
1172 | proto = cfgtew->u.cfgte64->proto; | ||
1173 | res->res_handle = cfgtew->u.cfgte64->res_handle; | ||
1174 | res->dev_id = cfgtew->u.cfgte64->dev_id; | ||
1175 | |||
1176 | memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun, | ||
1177 | sizeof(res->dev_lun.scsi_lun)); | ||
1178 | |||
1179 | if (memcmp(res->res_path, &cfgtew->u.cfgte64->res_path, | ||
1180 | sizeof(res->res_path))) { | ||
1181 | memcpy(res->res_path, &cfgtew->u.cfgte64->res_path, | ||
1182 | sizeof(res->res_path)); | ||
1183 | new_path = 1; | ||
1184 | } | ||
1185 | |||
1186 | if (res->sdev && new_path) | ||
1187 | sdev_printk(KERN_INFO, res->sdev, "Resource path: %s\n", | ||
1188 | ipr_format_resource_path(&res->res_path[0], &buffer[0])); | ||
1189 | } else { | ||
1190 | res->flags = cfgtew->u.cfgte->flags; | ||
1191 | if (res->flags & IPR_IS_IOA_RESOURCE) | ||
1192 | res->type = IPR_RES_TYPE_IOAFP; | ||
1193 | else | ||
1194 | res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f; | ||
1195 | |||
1196 | memcpy(&res->std_inq_data, &cfgtew->u.cfgte->std_inq_data, | ||
1197 | sizeof(struct ipr_std_inq_data)); | ||
1198 | |||
1199 | res->qmodel = IPR_QUEUEING_MODEL(res); | ||
1200 | proto = cfgtew->u.cfgte->proto; | ||
1201 | res->res_handle = cfgtew->u.cfgte->res_handle; | ||
1202 | } | ||
1203 | |||
1204 | ipr_update_ata_class(res, proto); | ||
1205 | } | ||
1206 | |||
1207 | /** | ||
1208 | * ipr_clear_res_target - Clear the bit in the bit map representing the target | ||
1209 | * for the resource. | ||
1210 | * @res: resource entry struct | ||
1211 | * @cfgtew: config table entry wrapper struct | ||
1212 | * | ||
1213 | * Return value: | ||
1214 | * none | ||
1215 | **/ | ||
1216 | static void ipr_clear_res_target(struct ipr_resource_entry *res) | ||
1217 | { | ||
1218 | struct ipr_resource_entry *gscsi_res = NULL; | ||
1219 | struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg; | ||
1220 | |||
1221 | if (!ioa_cfg->sis64) | ||
1222 | return; | ||
1223 | |||
1224 | if (res->bus == IPR_ARRAY_VIRTUAL_BUS) | ||
1225 | clear_bit(res->target, ioa_cfg->array_ids); | ||
1226 | else if (res->bus == IPR_VSET_VIRTUAL_BUS) | ||
1227 | clear_bit(res->target, ioa_cfg->vset_ids); | ||
1228 | else if (res->bus == 0 && res->type == IPR_RES_TYPE_GENERIC_SCSI) { | ||
1229 | list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue) | ||
1230 | if (gscsi_res->dev_id == res->dev_id && gscsi_res != res) | ||
1231 | return; | ||
1232 | clear_bit(res->target, ioa_cfg->target_ids); | ||
1233 | |||
1234 | } else if (res->bus == 0) | ||
1235 | clear_bit(res->target, ioa_cfg->target_ids); | ||
843 | } | 1236 | } |
844 | 1237 | ||
845 | /** | 1238 | /** |
@@ -851,17 +1244,24 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res) | |||
851 | * none | 1244 | * none |
852 | **/ | 1245 | **/ |
853 | static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, | 1246 | static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, |
854 | struct ipr_hostrcb *hostrcb) | 1247 | struct ipr_hostrcb *hostrcb) |
855 | { | 1248 | { |
856 | struct ipr_resource_entry *res = NULL; | 1249 | struct ipr_resource_entry *res = NULL; |
857 | struct ipr_config_table_entry *cfgte; | 1250 | struct ipr_config_table_entry_wrapper cfgtew; |
1251 | __be32 cc_res_handle; | ||
1252 | |||
858 | u32 is_ndn = 1; | 1253 | u32 is_ndn = 1; |
859 | 1254 | ||
860 | cfgte = &hostrcb->hcam.u.ccn.cfgte; | 1255 | if (ioa_cfg->sis64) { |
1256 | cfgtew.u.cfgte64 = &hostrcb->hcam.u.ccn.u.cfgte64; | ||
1257 | cc_res_handle = cfgtew.u.cfgte64->res_handle; | ||
1258 | } else { | ||
1259 | cfgtew.u.cfgte = &hostrcb->hcam.u.ccn.u.cfgte; | ||
1260 | cc_res_handle = cfgtew.u.cfgte->res_handle; | ||
1261 | } | ||
861 | 1262 | ||
862 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { | 1263 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
863 | if (!memcmp(&res->cfgte.res_addr, &cfgte->res_addr, | 1264 | if (res->res_handle == cc_res_handle) { |
864 | sizeof(cfgte->res_addr))) { | ||
865 | is_ndn = 0; | 1265 | is_ndn = 0; |
866 | break; | 1266 | break; |
867 | } | 1267 | } |
@@ -879,20 +1279,22 @@ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, | |||
879 | struct ipr_resource_entry, queue); | 1279 | struct ipr_resource_entry, queue); |
880 | 1280 | ||
881 | list_del(&res->queue); | 1281 | list_del(&res->queue); |
882 | ipr_init_res_entry(res); | 1282 | ipr_init_res_entry(res, &cfgtew); |
883 | list_add_tail(&res->queue, &ioa_cfg->used_res_q); | 1283 | list_add_tail(&res->queue, &ioa_cfg->used_res_q); |
884 | } | 1284 | } |
885 | 1285 | ||
886 | memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry)); | 1286 | ipr_update_res_entry(res, &cfgtew); |
887 | 1287 | ||
888 | if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) { | 1288 | if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) { |
889 | if (res->sdev) { | 1289 | if (res->sdev) { |
890 | res->del_from_ml = 1; | 1290 | res->del_from_ml = 1; |
891 | res->cfgte.res_handle = IPR_INVALID_RES_HANDLE; | 1291 | res->res_handle = IPR_INVALID_RES_HANDLE; |
892 | if (ioa_cfg->allow_ml_add_del) | 1292 | if (ioa_cfg->allow_ml_add_del) |
893 | schedule_work(&ioa_cfg->work_q); | 1293 | schedule_work(&ioa_cfg->work_q); |
894 | } else | 1294 | } else { |
1295 | ipr_clear_res_target(res); | ||
895 | list_move_tail(&res->queue, &ioa_cfg->free_res_q); | 1296 | list_move_tail(&res->queue, &ioa_cfg->free_res_q); |
1297 | } | ||
896 | } else if (!res->sdev) { | 1298 | } else if (!res->sdev) { |
897 | res->add_to_ml = 1; | 1299 | res->add_to_ml = 1; |
898 | if (ioa_cfg->allow_ml_add_del) | 1300 | if (ioa_cfg->allow_ml_add_del) |
@@ -1044,8 +1446,12 @@ static void ipr_log_ext_vpd(struct ipr_ext_vpd *vpd) | |||
1044 | static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg, | 1446 | static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg, |
1045 | struct ipr_hostrcb *hostrcb) | 1447 | struct ipr_hostrcb *hostrcb) |
1046 | { | 1448 | { |
1047 | struct ipr_hostrcb_type_12_error *error = | 1449 | struct ipr_hostrcb_type_12_error *error; |
1048 | &hostrcb->hcam.u.error.u.type_12_error; | 1450 | |
1451 | if (ioa_cfg->sis64) | ||
1452 | error = &hostrcb->hcam.u.error64.u.type_12_error; | ||
1453 | else | ||
1454 | error = &hostrcb->hcam.u.error.u.type_12_error; | ||
1049 | 1455 | ||
1050 | ipr_err("-----Current Configuration-----\n"); | 1456 | ipr_err("-----Current Configuration-----\n"); |
1051 | ipr_err("Cache Directory Card Information:\n"); | 1457 | ipr_err("Cache Directory Card Information:\n"); |
@@ -1138,6 +1544,48 @@ static void ipr_log_enhanced_config_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1138 | } | 1544 | } |
1139 | 1545 | ||
1140 | /** | 1546 | /** |
1547 | * ipr_log_sis64_config_error - Log a device error. | ||
1548 | * @ioa_cfg: ioa config struct | ||
1549 | * @hostrcb: hostrcb struct | ||
1550 | * | ||
1551 | * Return value: | ||
1552 | * none | ||
1553 | **/ | ||
1554 | static void ipr_log_sis64_config_error(struct ipr_ioa_cfg *ioa_cfg, | ||
1555 | struct ipr_hostrcb *hostrcb) | ||
1556 | { | ||
1557 | int errors_logged, i; | ||
1558 | struct ipr_hostrcb64_device_data_entry_enhanced *dev_entry; | ||
1559 | struct ipr_hostrcb_type_23_error *error; | ||
1560 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
1561 | |||
1562 | error = &hostrcb->hcam.u.error64.u.type_23_error; | ||
1563 | errors_logged = be32_to_cpu(error->errors_logged); | ||
1564 | |||
1565 | ipr_err("Device Errors Detected/Logged: %d/%d\n", | ||
1566 | be32_to_cpu(error->errors_detected), errors_logged); | ||
1567 | |||
1568 | dev_entry = error->dev; | ||
1569 | |||
1570 | for (i = 0; i < errors_logged; i++, dev_entry++) { | ||
1571 | ipr_err_separator; | ||
1572 | |||
1573 | ipr_err("Device %d : %s", i + 1, | ||
1574 | ipr_format_resource_path(&dev_entry->res_path[0], &buffer[0])); | ||
1575 | ipr_log_ext_vpd(&dev_entry->vpd); | ||
1576 | |||
1577 | ipr_err("-----New Device Information-----\n"); | ||
1578 | ipr_log_ext_vpd(&dev_entry->new_vpd); | ||
1579 | |||
1580 | ipr_err("Cache Directory Card Information:\n"); | ||
1581 | ipr_log_ext_vpd(&dev_entry->ioa_last_with_dev_vpd); | ||
1582 | |||
1583 | ipr_err("Adapter Card Information:\n"); | ||
1584 | ipr_log_ext_vpd(&dev_entry->cfc_last_with_dev_vpd); | ||
1585 | } | ||
1586 | } | ||
1587 | |||
1588 | /** | ||
1141 | * ipr_log_config_error - Log a configuration error. | 1589 | * ipr_log_config_error - Log a configuration error. |
1142 | * @ioa_cfg: ioa config struct | 1590 | * @ioa_cfg: ioa config struct |
1143 | * @hostrcb: hostrcb struct | 1591 | * @hostrcb: hostrcb struct |
@@ -1331,7 +1779,11 @@ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1331 | { | 1779 | { |
1332 | struct ipr_hostrcb_type_17_error *error; | 1780 | struct ipr_hostrcb_type_17_error *error; |
1333 | 1781 | ||
1334 | error = &hostrcb->hcam.u.error.u.type_17_error; | 1782 | if (ioa_cfg->sis64) |
1783 | error = &hostrcb->hcam.u.error64.u.type_17_error; | ||
1784 | else | ||
1785 | error = &hostrcb->hcam.u.error.u.type_17_error; | ||
1786 | |||
1335 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; | 1787 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; |
1336 | strim(error->failure_reason); | 1788 | strim(error->failure_reason); |
1337 | 1789 | ||
@@ -1438,6 +1890,42 @@ static void ipr_log_fabric_path(struct ipr_hostrcb *hostrcb, | |||
1438 | fabric->ioa_port, fabric->cascaded_expander, fabric->phy); | 1890 | fabric->ioa_port, fabric->cascaded_expander, fabric->phy); |
1439 | } | 1891 | } |
1440 | 1892 | ||
1893 | /** | ||
1894 | * ipr_log64_fabric_path - Log a fabric path error | ||
1895 | * @hostrcb: hostrcb struct | ||
1896 | * @fabric: fabric descriptor | ||
1897 | * | ||
1898 | * Return value: | ||
1899 | * none | ||
1900 | **/ | ||
1901 | static void ipr_log64_fabric_path(struct ipr_hostrcb *hostrcb, | ||
1902 | struct ipr_hostrcb64_fabric_desc *fabric) | ||
1903 | { | ||
1904 | int i, j; | ||
1905 | u8 path_state = fabric->path_state; | ||
1906 | u8 active = path_state & IPR_PATH_ACTIVE_MASK; | ||
1907 | u8 state = path_state & IPR_PATH_STATE_MASK; | ||
1908 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
1909 | |||
1910 | for (i = 0; i < ARRAY_SIZE(path_active_desc); i++) { | ||
1911 | if (path_active_desc[i].active != active) | ||
1912 | continue; | ||
1913 | |||
1914 | for (j = 0; j < ARRAY_SIZE(path_state_desc); j++) { | ||
1915 | if (path_state_desc[j].state != state) | ||
1916 | continue; | ||
1917 | |||
1918 | ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s\n", | ||
1919 | path_active_desc[i].desc, path_state_desc[j].desc, | ||
1920 | ipr_format_resource_path(&fabric->res_path[0], &buffer[0])); | ||
1921 | return; | ||
1922 | } | ||
1923 | } | ||
1924 | |||
1925 | ipr_err("Path state=%02X Resource Path=%s\n", path_state, | ||
1926 | ipr_format_resource_path(&fabric->res_path[0], &buffer[0])); | ||
1927 | } | ||
1928 | |||
1441 | static const struct { | 1929 | static const struct { |
1442 | u8 type; | 1930 | u8 type; |
1443 | char *desc; | 1931 | char *desc; |
@@ -1547,6 +2035,49 @@ static void ipr_log_path_elem(struct ipr_hostrcb *hostrcb, | |||
1547 | } | 2035 | } |
1548 | 2036 | ||
1549 | /** | 2037 | /** |
2038 | * ipr_log64_path_elem - Log a fabric path element. | ||
2039 | * @hostrcb: hostrcb struct | ||
2040 | * @cfg: fabric path element struct | ||
2041 | * | ||
2042 | * Return value: | ||
2043 | * none | ||
2044 | **/ | ||
2045 | static void ipr_log64_path_elem(struct ipr_hostrcb *hostrcb, | ||
2046 | struct ipr_hostrcb64_config_element *cfg) | ||
2047 | { | ||
2048 | int i, j; | ||
2049 | u8 desc_id = cfg->descriptor_id & IPR_DESCRIPTOR_MASK; | ||
2050 | u8 type = cfg->type_status & IPR_PATH_CFG_TYPE_MASK; | ||
2051 | u8 status = cfg->type_status & IPR_PATH_CFG_STATUS_MASK; | ||
2052 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
2053 | |||
2054 | if (type == IPR_PATH_CFG_NOT_EXIST || desc_id != IPR_DESCRIPTOR_SIS64) | ||
2055 | return; | ||
2056 | |||
2057 | for (i = 0; i < ARRAY_SIZE(path_type_desc); i++) { | ||
2058 | if (path_type_desc[i].type != type) | ||
2059 | continue; | ||
2060 | |||
2061 | for (j = 0; j < ARRAY_SIZE(path_status_desc); j++) { | ||
2062 | if (path_status_desc[j].status != status) | ||
2063 | continue; | ||
2064 | |||
2065 | ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s, Link rate=%s, WWN=%08X%08X\n", | ||
2066 | path_status_desc[j].desc, path_type_desc[i].desc, | ||
2067 | ipr_format_resource_path(&cfg->res_path[0], &buffer[0]), | ||
2068 | link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], | ||
2069 | be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); | ||
2070 | return; | ||
2071 | } | ||
2072 | } | ||
2073 | ipr_hcam_err(hostrcb, "Path element=%02X: Resource Path=%s, Link rate=%s " | ||
2074 | "WWN=%08X%08X\n", cfg->type_status, | ||
2075 | ipr_format_resource_path(&cfg->res_path[0], &buffer[0]), | ||
2076 | link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], | ||
2077 | be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); | ||
2078 | } | ||
2079 | |||
2080 | /** | ||
1550 | * ipr_log_fabric_error - Log a fabric error. | 2081 | * ipr_log_fabric_error - Log a fabric error. |
1551 | * @ioa_cfg: ioa config struct | 2082 | * @ioa_cfg: ioa config struct |
1552 | * @hostrcb: hostrcb struct | 2083 | * @hostrcb: hostrcb struct |
@@ -1584,6 +2115,96 @@ static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1584 | } | 2115 | } |
1585 | 2116 | ||
1586 | /** | 2117 | /** |
2118 | * ipr_log_sis64_array_error - Log a sis64 array error. | ||
2119 | * @ioa_cfg: ioa config struct | ||
2120 | * @hostrcb: hostrcb struct | ||
2121 | * | ||
2122 | * Return value: | ||
2123 | * none | ||
2124 | **/ | ||
2125 | static void ipr_log_sis64_array_error(struct ipr_ioa_cfg *ioa_cfg, | ||
2126 | struct ipr_hostrcb *hostrcb) | ||
2127 | { | ||
2128 | int i, num_entries; | ||
2129 | struct ipr_hostrcb_type_24_error *error; | ||
2130 | struct ipr_hostrcb64_array_data_entry *array_entry; | ||
2131 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
2132 | const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' }; | ||
2133 | |||
2134 | error = &hostrcb->hcam.u.error64.u.type_24_error; | ||
2135 | |||
2136 | ipr_err_separator; | ||
2137 | |||
2138 | ipr_err("RAID %s Array Configuration: %s\n", | ||
2139 | error->protection_level, | ||
2140 | ipr_format_resource_path(&error->last_res_path[0], &buffer[0])); | ||
2141 | |||
2142 | ipr_err_separator; | ||
2143 | |||
2144 | array_entry = error->array_member; | ||
2145 | num_entries = min_t(u32, be32_to_cpu(error->num_entries), | ||
2146 | sizeof(error->array_member)); | ||
2147 | |||
2148 | for (i = 0; i < num_entries; i++, array_entry++) { | ||
2149 | |||
2150 | if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN)) | ||
2151 | continue; | ||
2152 | |||
2153 | if (error->exposed_mode_adn == i) | ||
2154 | ipr_err("Exposed Array Member %d:\n", i); | ||
2155 | else | ||
2156 | ipr_err("Array Member %d:\n", i); | ||
2157 | |||
2158 | ipr_err("Array Member %d:\n", i); | ||
2159 | ipr_log_ext_vpd(&array_entry->vpd); | ||
2160 | ipr_err("Current Location: %s", | ||
2161 | ipr_format_resource_path(&array_entry->res_path[0], &buffer[0])); | ||
2162 | ipr_err("Expected Location: %s", | ||
2163 | ipr_format_resource_path(&array_entry->expected_res_path[0], &buffer[0])); | ||
2164 | |||
2165 | ipr_err_separator; | ||
2166 | } | ||
2167 | } | ||
2168 | |||
2169 | /** | ||
2170 | * ipr_log_sis64_fabric_error - Log a sis64 fabric error. | ||
2171 | * @ioa_cfg: ioa config struct | ||
2172 | * @hostrcb: hostrcb struct | ||
2173 | * | ||
2174 | * Return value: | ||
2175 | * none | ||
2176 | **/ | ||
2177 | static void ipr_log_sis64_fabric_error(struct ipr_ioa_cfg *ioa_cfg, | ||
2178 | struct ipr_hostrcb *hostrcb) | ||
2179 | { | ||
2180 | struct ipr_hostrcb_type_30_error *error; | ||
2181 | struct ipr_hostrcb64_fabric_desc *fabric; | ||
2182 | struct ipr_hostrcb64_config_element *cfg; | ||
2183 | int i, add_len; | ||
2184 | |||
2185 | error = &hostrcb->hcam.u.error64.u.type_30_error; | ||
2186 | |||
2187 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; | ||
2188 | ipr_hcam_err(hostrcb, "%s\n", error->failure_reason); | ||
2189 | |||
2190 | add_len = be32_to_cpu(hostrcb->hcam.length) - | ||
2191 | (offsetof(struct ipr_hostrcb64_error, u) + | ||
2192 | offsetof(struct ipr_hostrcb_type_30_error, desc)); | ||
2193 | |||
2194 | for (i = 0, fabric = error->desc; i < error->num_entries; i++) { | ||
2195 | ipr_log64_fabric_path(hostrcb, fabric); | ||
2196 | for_each_fabric_cfg(fabric, cfg) | ||
2197 | ipr_log64_path_elem(hostrcb, cfg); | ||
2198 | |||
2199 | add_len -= be16_to_cpu(fabric->length); | ||
2200 | fabric = (struct ipr_hostrcb64_fabric_desc *) | ||
2201 | ((unsigned long)fabric + be16_to_cpu(fabric->length)); | ||
2202 | } | ||
2203 | |||
2204 | ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len); | ||
2205 | } | ||
2206 | |||
2207 | /** | ||
1587 | * ipr_log_generic_error - Log an adapter error. | 2208 | * ipr_log_generic_error - Log an adapter error. |
1588 | * @ioa_cfg: ioa config struct | 2209 | * @ioa_cfg: ioa config struct |
1589 | * @hostrcb: hostrcb struct | 2210 | * @hostrcb: hostrcb struct |
@@ -1642,13 +2263,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, | |||
1642 | if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST) | 2263 | if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST) |
1643 | dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n"); | 2264 | dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n"); |
1644 | 2265 | ||
1645 | ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); | 2266 | if (ioa_cfg->sis64) |
2267 | ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc); | ||
2268 | else | ||
2269 | ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc); | ||
1646 | 2270 | ||
1647 | if (ioasc == IPR_IOASC_BUS_WAS_RESET || | 2271 | if (!ioa_cfg->sis64 && (ioasc == IPR_IOASC_BUS_WAS_RESET || |
1648 | ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER) { | 2272 | ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER)) { |
1649 | /* Tell the midlayer we had a bus reset so it will handle the UA properly */ | 2273 | /* Tell the midlayer we had a bus reset so it will handle the UA properly */ |
1650 | scsi_report_bus_reset(ioa_cfg->host, | 2274 | scsi_report_bus_reset(ioa_cfg->host, |
1651 | hostrcb->hcam.u.error.failing_dev_res_addr.bus); | 2275 | hostrcb->hcam.u.error.fd_res_addr.bus); |
1652 | } | 2276 | } |
1653 | 2277 | ||
1654 | error_index = ipr_get_error(ioasc); | 2278 | error_index = ipr_get_error(ioasc); |
@@ -1696,6 +2320,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, | |||
1696 | case IPR_HOST_RCB_OVERLAY_ID_20: | 2320 | case IPR_HOST_RCB_OVERLAY_ID_20: |
1697 | ipr_log_fabric_error(ioa_cfg, hostrcb); | 2321 | ipr_log_fabric_error(ioa_cfg, hostrcb); |
1698 | break; | 2322 | break; |
2323 | case IPR_HOST_RCB_OVERLAY_ID_23: | ||
2324 | ipr_log_sis64_config_error(ioa_cfg, hostrcb); | ||
2325 | break; | ||
2326 | case IPR_HOST_RCB_OVERLAY_ID_24: | ||
2327 | case IPR_HOST_RCB_OVERLAY_ID_26: | ||
2328 | ipr_log_sis64_array_error(ioa_cfg, hostrcb); | ||
2329 | break; | ||
2330 | case IPR_HOST_RCB_OVERLAY_ID_30: | ||
2331 | ipr_log_sis64_fabric_error(ioa_cfg, hostrcb); | ||
2332 | break; | ||
1699 | case IPR_HOST_RCB_OVERLAY_ID_1: | 2333 | case IPR_HOST_RCB_OVERLAY_ID_1: |
1700 | case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: | 2334 | case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: |
1701 | default: | 2335 | default: |
@@ -1720,7 +2354,12 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd) | |||
1720 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 2354 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
1721 | struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; | 2355 | struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; |
1722 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 2356 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); |
1723 | u32 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); | 2357 | u32 fd_ioasc; |
2358 | |||
2359 | if (ioa_cfg->sis64) | ||
2360 | fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc); | ||
2361 | else | ||
2362 | fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc); | ||
1724 | 2363 | ||
1725 | list_del(&hostrcb->queue); | 2364 | list_del(&hostrcb->queue); |
1726 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); | 2365 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); |
@@ -1845,12 +2484,14 @@ static const struct ipr_ses_table_entry * | |||
1845 | ipr_find_ses_entry(struct ipr_resource_entry *res) | 2484 | ipr_find_ses_entry(struct ipr_resource_entry *res) |
1846 | { | 2485 | { |
1847 | int i, j, matches; | 2486 | int i, j, matches; |
2487 | struct ipr_std_inq_vpids *vpids; | ||
1848 | const struct ipr_ses_table_entry *ste = ipr_ses_table; | 2488 | const struct ipr_ses_table_entry *ste = ipr_ses_table; |
1849 | 2489 | ||
1850 | for (i = 0; i < ARRAY_SIZE(ipr_ses_table); i++, ste++) { | 2490 | for (i = 0; i < ARRAY_SIZE(ipr_ses_table); i++, ste++) { |
1851 | for (j = 0, matches = 0; j < IPR_PROD_ID_LEN; j++) { | 2491 | for (j = 0, matches = 0; j < IPR_PROD_ID_LEN; j++) { |
1852 | if (ste->compare_product_id_byte[j] == 'X') { | 2492 | if (ste->compare_product_id_byte[j] == 'X') { |
1853 | if (res->cfgte.std_inq_data.vpids.product_id[j] == ste->product_id[j]) | 2493 | vpids = &res->std_inq_data.vpids; |
2494 | if (vpids->product_id[j] == ste->product_id[j]) | ||
1854 | matches++; | 2495 | matches++; |
1855 | else | 2496 | else |
1856 | break; | 2497 | break; |
@@ -1885,10 +2526,10 @@ static u32 ipr_get_max_scsi_speed(struct ipr_ioa_cfg *ioa_cfg, u8 bus, u8 bus_wi | |||
1885 | 2526 | ||
1886 | /* Loop through each config table entry in the config table buffer */ | 2527 | /* Loop through each config table entry in the config table buffer */ |
1887 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { | 2528 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
1888 | if (!(IPR_IS_SES_DEVICE(res->cfgte.std_inq_data))) | 2529 | if (!(IPR_IS_SES_DEVICE(res->std_inq_data))) |
1889 | continue; | 2530 | continue; |
1890 | 2531 | ||
1891 | if (bus != res->cfgte.res_addr.bus) | 2532 | if (bus != res->bus) |
1892 | continue; | 2533 | continue; |
1893 | 2534 | ||
1894 | if (!(ste = ipr_find_ses_entry(res))) | 2535 | if (!(ste = ipr_find_ses_entry(res))) |
@@ -1934,6 +2575,31 @@ static int ipr_wait_iodbg_ack(struct ipr_ioa_cfg *ioa_cfg, int max_delay) | |||
1934 | } | 2575 | } |
1935 | 2576 | ||
1936 | /** | 2577 | /** |
2578 | * ipr_get_sis64_dump_data_section - Dump IOA memory | ||
2579 | * @ioa_cfg: ioa config struct | ||
2580 | * @start_addr: adapter address to dump | ||
2581 | * @dest: destination kernel buffer | ||
2582 | * @length_in_words: length to dump in 4 byte words | ||
2583 | * | ||
2584 | * Return value: | ||
2585 | * 0 on success | ||
2586 | **/ | ||
2587 | static int ipr_get_sis64_dump_data_section(struct ipr_ioa_cfg *ioa_cfg, | ||
2588 | u32 start_addr, | ||
2589 | __be32 *dest, u32 length_in_words) | ||
2590 | { | ||
2591 | int i; | ||
2592 | |||
2593 | for (i = 0; i < length_in_words; i++) { | ||
2594 | writel(start_addr+(i*4), ioa_cfg->regs.dump_addr_reg); | ||
2595 | *dest = cpu_to_be32(readl(ioa_cfg->regs.dump_data_reg)); | ||
2596 | dest++; | ||
2597 | } | ||
2598 | |||
2599 | return 0; | ||
2600 | } | ||
2601 | |||
2602 | /** | ||
1937 | * ipr_get_ldump_data_section - Dump IOA memory | 2603 | * ipr_get_ldump_data_section - Dump IOA memory |
1938 | * @ioa_cfg: ioa config struct | 2604 | * @ioa_cfg: ioa config struct |
1939 | * @start_addr: adapter address to dump | 2605 | * @start_addr: adapter address to dump |
@@ -1950,9 +2616,13 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, | |||
1950 | volatile u32 temp_pcii_reg; | 2616 | volatile u32 temp_pcii_reg; |
1951 | int i, delay = 0; | 2617 | int i, delay = 0; |
1952 | 2618 | ||
2619 | if (ioa_cfg->sis64) | ||
2620 | return ipr_get_sis64_dump_data_section(ioa_cfg, start_addr, | ||
2621 | dest, length_in_words); | ||
2622 | |||
1953 | /* Write IOA interrupt reg starting LDUMP state */ | 2623 | /* Write IOA interrupt reg starting LDUMP state */ |
1954 | writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT), | 2624 | writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT), |
1955 | ioa_cfg->regs.set_uproc_interrupt_reg); | 2625 | ioa_cfg->regs.set_uproc_interrupt_reg32); |
1956 | 2626 | ||
1957 | /* Wait for IO debug acknowledge */ | 2627 | /* Wait for IO debug acknowledge */ |
1958 | if (ipr_wait_iodbg_ack(ioa_cfg, | 2628 | if (ipr_wait_iodbg_ack(ioa_cfg, |
@@ -1971,7 +2641,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, | |||
1971 | 2641 | ||
1972 | /* Signal address valid - clear IOA Reset alert */ | 2642 | /* Signal address valid - clear IOA Reset alert */ |
1973 | writel(IPR_UPROCI_RESET_ALERT, | 2643 | writel(IPR_UPROCI_RESET_ALERT, |
1974 | ioa_cfg->regs.clr_uproc_interrupt_reg); | 2644 | ioa_cfg->regs.clr_uproc_interrupt_reg32); |
1975 | 2645 | ||
1976 | for (i = 0; i < length_in_words; i++) { | 2646 | for (i = 0; i < length_in_words; i++) { |
1977 | /* Wait for IO debug acknowledge */ | 2647 | /* Wait for IO debug acknowledge */ |
@@ -1996,10 +2666,10 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, | |||
1996 | 2666 | ||
1997 | /* Signal end of block transfer. Set reset alert then clear IO debug ack */ | 2667 | /* Signal end of block transfer. Set reset alert then clear IO debug ack */ |
1998 | writel(IPR_UPROCI_RESET_ALERT, | 2668 | writel(IPR_UPROCI_RESET_ALERT, |
1999 | ioa_cfg->regs.set_uproc_interrupt_reg); | 2669 | ioa_cfg->regs.set_uproc_interrupt_reg32); |
2000 | 2670 | ||
2001 | writel(IPR_UPROCI_IO_DEBUG_ALERT, | 2671 | writel(IPR_UPROCI_IO_DEBUG_ALERT, |
2002 | ioa_cfg->regs.clr_uproc_interrupt_reg); | 2672 | ioa_cfg->regs.clr_uproc_interrupt_reg32); |
2003 | 2673 | ||
2004 | /* Signal dump data received - Clear IO debug Ack */ | 2674 | /* Signal dump data received - Clear IO debug Ack */ |
2005 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, | 2675 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, |
@@ -2008,7 +2678,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, | |||
2008 | /* Wait for IOA to signal LDUMP exit - IOA reset alert will be cleared */ | 2678 | /* Wait for IOA to signal LDUMP exit - IOA reset alert will be cleared */ |
2009 | while (delay < IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC) { | 2679 | while (delay < IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC) { |
2010 | temp_pcii_reg = | 2680 | temp_pcii_reg = |
2011 | readl(ioa_cfg->regs.sense_uproc_interrupt_reg); | 2681 | readl(ioa_cfg->regs.sense_uproc_interrupt_reg32); |
2012 | 2682 | ||
2013 | if (!(temp_pcii_reg & IPR_UPROCI_RESET_ALERT)) | 2683 | if (!(temp_pcii_reg & IPR_UPROCI_RESET_ALERT)) |
2014 | return 0; | 2684 | return 0; |
@@ -2207,6 +2877,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) | |||
2207 | u32 num_entries, start_off, end_off; | 2877 | u32 num_entries, start_off, end_off; |
2208 | u32 bytes_to_copy, bytes_copied, rc; | 2878 | u32 bytes_to_copy, bytes_copied, rc; |
2209 | struct ipr_sdt *sdt; | 2879 | struct ipr_sdt *sdt; |
2880 | int valid = 1; | ||
2210 | int i; | 2881 | int i; |
2211 | 2882 | ||
2212 | ENTER; | 2883 | ENTER; |
@@ -2220,7 +2891,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) | |||
2220 | 2891 | ||
2221 | start_addr = readl(ioa_cfg->ioa_mailbox); | 2892 | start_addr = readl(ioa_cfg->ioa_mailbox); |
2222 | 2893 | ||
2223 | if (!ipr_sdt_is_fmt2(start_addr)) { | 2894 | if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(start_addr)) { |
2224 | dev_err(&ioa_cfg->pdev->dev, | 2895 | dev_err(&ioa_cfg->pdev->dev, |
2225 | "Invalid dump table format: %lx\n", start_addr); | 2896 | "Invalid dump table format: %lx\n", start_addr); |
2226 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 2897 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
@@ -2249,7 +2920,6 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) | |||
2249 | 2920 | ||
2250 | /* IOA Dump entry */ | 2921 | /* IOA Dump entry */ |
2251 | ipr_init_dump_entry_hdr(&ioa_dump->hdr); | 2922 | ipr_init_dump_entry_hdr(&ioa_dump->hdr); |
2252 | ioa_dump->format = IPR_SDT_FMT2; | ||
2253 | ioa_dump->hdr.len = 0; | 2923 | ioa_dump->hdr.len = 0; |
2254 | ioa_dump->hdr.data_type = IPR_DUMP_DATA_TYPE_BINARY; | 2924 | ioa_dump->hdr.data_type = IPR_DUMP_DATA_TYPE_BINARY; |
2255 | ioa_dump->hdr.id = IPR_DUMP_IOA_DUMP_ID; | 2925 | ioa_dump->hdr.id = IPR_DUMP_IOA_DUMP_ID; |
@@ -2264,7 +2934,8 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) | |||
2264 | sizeof(struct ipr_sdt) / sizeof(__be32)); | 2934 | sizeof(struct ipr_sdt) / sizeof(__be32)); |
2265 | 2935 | ||
2266 | /* Smart Dump table is ready to use and the first entry is valid */ | 2936 | /* Smart Dump table is ready to use and the first entry is valid */ |
2267 | if (rc || (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE)) { | 2937 | if (rc || ((be32_to_cpu(sdt->hdr.state) != IPR_FMT3_SDT_READY_TO_USE) && |
2938 | (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) { | ||
2268 | dev_err(&ioa_cfg->pdev->dev, | 2939 | dev_err(&ioa_cfg->pdev->dev, |
2269 | "Dump of IOA failed. Dump table not valid: %d, %X.\n", | 2940 | "Dump of IOA failed. Dump table not valid: %d, %X.\n", |
2270 | rc, be32_to_cpu(sdt->hdr.state)); | 2941 | rc, be32_to_cpu(sdt->hdr.state)); |
@@ -2288,12 +2959,19 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) | |||
2288 | } | 2959 | } |
2289 | 2960 | ||
2290 | if (sdt->entry[i].flags & IPR_SDT_VALID_ENTRY) { | 2961 | if (sdt->entry[i].flags & IPR_SDT_VALID_ENTRY) { |
2291 | sdt_word = be32_to_cpu(sdt->entry[i].bar_str_offset); | 2962 | sdt_word = be32_to_cpu(sdt->entry[i].start_token); |
2292 | start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK; | 2963 | if (ioa_cfg->sis64) |
2293 | end_off = be32_to_cpu(sdt->entry[i].end_offset); | 2964 | bytes_to_copy = be32_to_cpu(sdt->entry[i].end_token); |
2294 | 2965 | else { | |
2295 | if (ipr_sdt_is_fmt2(sdt_word) && sdt_word) { | 2966 | start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK; |
2296 | bytes_to_copy = end_off - start_off; | 2967 | end_off = be32_to_cpu(sdt->entry[i].end_token); |
2968 | |||
2969 | if (ipr_sdt_is_fmt2(sdt_word) && sdt_word) | ||
2970 | bytes_to_copy = end_off - start_off; | ||
2971 | else | ||
2972 | valid = 0; | ||
2973 | } | ||
2974 | if (valid) { | ||
2297 | if (bytes_to_copy > IPR_MAX_IOA_DUMP_SIZE) { | 2975 | if (bytes_to_copy > IPR_MAX_IOA_DUMP_SIZE) { |
2298 | sdt->entry[i].flags &= ~IPR_SDT_VALID_ENTRY; | 2976 | sdt->entry[i].flags &= ~IPR_SDT_VALID_ENTRY; |
2299 | continue; | 2977 | continue; |
@@ -2422,9 +3100,9 @@ restart: | |||
2422 | 3100 | ||
2423 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { | 3101 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
2424 | if (res->add_to_ml) { | 3102 | if (res->add_to_ml) { |
2425 | bus = res->cfgte.res_addr.bus; | 3103 | bus = res->bus; |
2426 | target = res->cfgte.res_addr.target; | 3104 | target = res->target; |
2427 | lun = res->cfgte.res_addr.lun; | 3105 | lun = res->lun; |
2428 | res->add_to_ml = 0; | 3106 | res->add_to_ml = 0; |
2429 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 3107 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
2430 | scsi_add_device(ioa_cfg->host, bus, target, lun); | 3108 | scsi_add_device(ioa_cfg->host, bus, target, lun); |
@@ -2478,105 +3156,6 @@ static struct bin_attribute ipr_trace_attr = { | |||
2478 | }; | 3156 | }; |
2479 | #endif | 3157 | #endif |
2480 | 3158 | ||
2481 | static const struct { | ||
2482 | enum ipr_cache_state state; | ||
2483 | char *name; | ||
2484 | } cache_state [] = { | ||
2485 | { CACHE_NONE, "none" }, | ||
2486 | { CACHE_DISABLED, "disabled" }, | ||
2487 | { CACHE_ENABLED, "enabled" } | ||
2488 | }; | ||
2489 | |||
2490 | /** | ||
2491 | * ipr_show_write_caching - Show the write caching attribute | ||
2492 | * @dev: device struct | ||
2493 | * @buf: buffer | ||
2494 | * | ||
2495 | * Return value: | ||
2496 | * number of bytes printed to buffer | ||
2497 | **/ | ||
2498 | static ssize_t ipr_show_write_caching(struct device *dev, | ||
2499 | struct device_attribute *attr, char *buf) | ||
2500 | { | ||
2501 | struct Scsi_Host *shost = class_to_shost(dev); | ||
2502 | struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; | ||
2503 | unsigned long lock_flags = 0; | ||
2504 | int i, len = 0; | ||
2505 | |||
2506 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | ||
2507 | for (i = 0; i < ARRAY_SIZE(cache_state); i++) { | ||
2508 | if (cache_state[i].state == ioa_cfg->cache_state) { | ||
2509 | len = snprintf(buf, PAGE_SIZE, "%s\n", cache_state[i].name); | ||
2510 | break; | ||
2511 | } | ||
2512 | } | ||
2513 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
2514 | return len; | ||
2515 | } | ||
2516 | |||
2517 | |||
2518 | /** | ||
2519 | * ipr_store_write_caching - Enable/disable adapter write cache | ||
2520 | * @dev: device struct | ||
2521 | * @buf: buffer | ||
2522 | * @count: buffer size | ||
2523 | * | ||
2524 | * This function will enable/disable adapter write cache. | ||
2525 | * | ||
2526 | * Return value: | ||
2527 | * count on success / other on failure | ||
2528 | **/ | ||
2529 | static ssize_t ipr_store_write_caching(struct device *dev, | ||
2530 | struct device_attribute *attr, | ||
2531 | const char *buf, size_t count) | ||
2532 | { | ||
2533 | struct Scsi_Host *shost = class_to_shost(dev); | ||
2534 | struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; | ||
2535 | unsigned long lock_flags = 0; | ||
2536 | enum ipr_cache_state new_state = CACHE_INVALID; | ||
2537 | int i; | ||
2538 | |||
2539 | if (!capable(CAP_SYS_ADMIN)) | ||
2540 | return -EACCES; | ||
2541 | if (ioa_cfg->cache_state == CACHE_NONE) | ||
2542 | return -EINVAL; | ||
2543 | |||
2544 | for (i = 0; i < ARRAY_SIZE(cache_state); i++) { | ||
2545 | if (!strncmp(cache_state[i].name, buf, strlen(cache_state[i].name))) { | ||
2546 | new_state = cache_state[i].state; | ||
2547 | break; | ||
2548 | } | ||
2549 | } | ||
2550 | |||
2551 | if (new_state != CACHE_DISABLED && new_state != CACHE_ENABLED) | ||
2552 | return -EINVAL; | ||
2553 | |||
2554 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | ||
2555 | if (ioa_cfg->cache_state == new_state) { | ||
2556 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
2557 | return count; | ||
2558 | } | ||
2559 | |||
2560 | ioa_cfg->cache_state = new_state; | ||
2561 | dev_info(&ioa_cfg->pdev->dev, "%s adapter write cache.\n", | ||
2562 | new_state == CACHE_ENABLED ? "Enabling" : "Disabling"); | ||
2563 | if (!ioa_cfg->in_reset_reload) | ||
2564 | ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL); | ||
2565 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
2566 | wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); | ||
2567 | |||
2568 | return count; | ||
2569 | } | ||
2570 | |||
2571 | static struct device_attribute ipr_ioa_cache_attr = { | ||
2572 | .attr = { | ||
2573 | .name = "write_cache", | ||
2574 | .mode = S_IRUGO | S_IWUSR, | ||
2575 | }, | ||
2576 | .show = ipr_show_write_caching, | ||
2577 | .store = ipr_store_write_caching | ||
2578 | }; | ||
2579 | |||
2580 | /** | 3159 | /** |
2581 | * ipr_show_fw_version - Show the firmware version | 3160 | * ipr_show_fw_version - Show the firmware version |
2582 | * @dev: class device struct | 3161 | * @dev: class device struct |
@@ -2976,6 +3555,37 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist, | |||
2976 | } | 3555 | } |
2977 | 3556 | ||
2978 | /** | 3557 | /** |
3558 | * ipr_build_ucode_ioadl64 - Build a microcode download IOADL | ||
3559 | * @ipr_cmd: ipr command struct | ||
3560 | * @sglist: scatter/gather list | ||
3561 | * | ||
3562 | * Builds a microcode download IOA data list (IOADL). | ||
3563 | * | ||
3564 | **/ | ||
3565 | static void ipr_build_ucode_ioadl64(struct ipr_cmnd *ipr_cmd, | ||
3566 | struct ipr_sglist *sglist) | ||
3567 | { | ||
3568 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | ||
3569 | struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; | ||
3570 | struct scatterlist *scatterlist = sglist->scatterlist; | ||
3571 | int i; | ||
3572 | |||
3573 | ipr_cmd->dma_use_sg = sglist->num_dma_sg; | ||
3574 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | ||
3575 | ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len); | ||
3576 | |||
3577 | ioarcb->ioadl_len = | ||
3578 | cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg); | ||
3579 | for (i = 0; i < ipr_cmd->dma_use_sg; i++) { | ||
3580 | ioadl64[i].flags = cpu_to_be32(IPR_IOADL_FLAGS_WRITE); | ||
3581 | ioadl64[i].data_len = cpu_to_be32(sg_dma_len(&scatterlist[i])); | ||
3582 | ioadl64[i].address = cpu_to_be64(sg_dma_address(&scatterlist[i])); | ||
3583 | } | ||
3584 | |||
3585 | ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST); | ||
3586 | } | ||
3587 | |||
3588 | /** | ||
2979 | * ipr_build_ucode_ioadl - Build a microcode download IOADL | 3589 | * ipr_build_ucode_ioadl - Build a microcode download IOADL |
2980 | * @ipr_cmd: ipr command struct | 3590 | * @ipr_cmd: ipr command struct |
2981 | * @sglist: scatter/gather list | 3591 | * @sglist: scatter/gather list |
@@ -2987,14 +3597,15 @@ static void ipr_build_ucode_ioadl(struct ipr_cmnd *ipr_cmd, | |||
2987 | struct ipr_sglist *sglist) | 3597 | struct ipr_sglist *sglist) |
2988 | { | 3598 | { |
2989 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 3599 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
2990 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | 3600 | struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl; |
2991 | struct scatterlist *scatterlist = sglist->scatterlist; | 3601 | struct scatterlist *scatterlist = sglist->scatterlist; |
2992 | int i; | 3602 | int i; |
2993 | 3603 | ||
2994 | ipr_cmd->dma_use_sg = sglist->num_dma_sg; | 3604 | ipr_cmd->dma_use_sg = sglist->num_dma_sg; |
2995 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | 3605 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; |
2996 | ioarcb->write_data_transfer_length = cpu_to_be32(sglist->buffer_len); | 3606 | ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len); |
2997 | ioarcb->write_ioadl_len = | 3607 | |
3608 | ioarcb->ioadl_len = | ||
2998 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); | 3609 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); |
2999 | 3610 | ||
3000 | for (i = 0; i < ipr_cmd->dma_use_sg; i++) { | 3611 | for (i = 0; i < ipr_cmd->dma_use_sg; i++) { |
@@ -3146,7 +3757,6 @@ static struct device_attribute *ipr_ioa_attrs[] = { | |||
3146 | &ipr_ioa_state_attr, | 3757 | &ipr_ioa_state_attr, |
3147 | &ipr_ioa_reset_attr, | 3758 | &ipr_ioa_reset_attr, |
3148 | &ipr_update_fw_attr, | 3759 | &ipr_update_fw_attr, |
3149 | &ipr_ioa_cache_attr, | ||
3150 | NULL, | 3760 | NULL, |
3151 | }; | 3761 | }; |
3152 | 3762 | ||
@@ -3450,7 +4060,7 @@ static ssize_t ipr_show_adapter_handle(struct device *dev, struct device_attribu | |||
3450 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | 4060 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); |
3451 | res = (struct ipr_resource_entry *)sdev->hostdata; | 4061 | res = (struct ipr_resource_entry *)sdev->hostdata; |
3452 | if (res) | 4062 | if (res) |
3453 | len = snprintf(buf, PAGE_SIZE, "%08X\n", res->cfgte.res_handle); | 4063 | len = snprintf(buf, PAGE_SIZE, "%08X\n", res->res_handle); |
3454 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 4064 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
3455 | return len; | 4065 | return len; |
3456 | } | 4066 | } |
@@ -3463,8 +4073,43 @@ static struct device_attribute ipr_adapter_handle_attr = { | |||
3463 | .show = ipr_show_adapter_handle | 4073 | .show = ipr_show_adapter_handle |
3464 | }; | 4074 | }; |
3465 | 4075 | ||
4076 | /** | ||
4077 | * ipr_show_resource_path - Show the resource path for this device. | ||
4078 | * @dev: device struct | ||
4079 | * @buf: buffer | ||
4080 | * | ||
4081 | * Return value: | ||
4082 | * number of bytes printed to buffer | ||
4083 | **/ | ||
4084 | static ssize_t ipr_show_resource_path(struct device *dev, struct device_attribute *attr, char *buf) | ||
4085 | { | ||
4086 | struct scsi_device *sdev = to_scsi_device(dev); | ||
4087 | struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata; | ||
4088 | struct ipr_resource_entry *res; | ||
4089 | unsigned long lock_flags = 0; | ||
4090 | ssize_t len = -ENXIO; | ||
4091 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
4092 | |||
4093 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | ||
4094 | res = (struct ipr_resource_entry *)sdev->hostdata; | ||
4095 | if (res) | ||
4096 | len = snprintf(buf, PAGE_SIZE, "%s\n", | ||
4097 | ipr_format_resource_path(&res->res_path[0], &buffer[0])); | ||
4098 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
4099 | return len; | ||
4100 | } | ||
4101 | |||
4102 | static struct device_attribute ipr_resource_path_attr = { | ||
4103 | .attr = { | ||
4104 | .name = "resource_path", | ||
4105 | .mode = S_IRUSR, | ||
4106 | }, | ||
4107 | .show = ipr_show_resource_path | ||
4108 | }; | ||
4109 | |||
3466 | static struct device_attribute *ipr_dev_attrs[] = { | 4110 | static struct device_attribute *ipr_dev_attrs[] = { |
3467 | &ipr_adapter_handle_attr, | 4111 | &ipr_adapter_handle_attr, |
4112 | &ipr_resource_path_attr, | ||
3468 | NULL, | 4113 | NULL, |
3469 | }; | 4114 | }; |
3470 | 4115 | ||
@@ -3517,9 +4162,9 @@ static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget) | |||
3517 | struct ipr_resource_entry *res; | 4162 | struct ipr_resource_entry *res; |
3518 | 4163 | ||
3519 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { | 4164 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
3520 | if ((res->cfgte.res_addr.bus == starget->channel) && | 4165 | if ((res->bus == starget->channel) && |
3521 | (res->cfgte.res_addr.target == starget->id) && | 4166 | (res->target == starget->id) && |
3522 | (res->cfgte.res_addr.lun == 0)) { | 4167 | (res->lun == 0)) { |
3523 | return res; | 4168 | return res; |
3524 | } | 4169 | } |
3525 | } | 4170 | } |
@@ -3589,6 +4234,17 @@ static int ipr_target_alloc(struct scsi_target *starget) | |||
3589 | static void ipr_target_destroy(struct scsi_target *starget) | 4234 | static void ipr_target_destroy(struct scsi_target *starget) |
3590 | { | 4235 | { |
3591 | struct ipr_sata_port *sata_port = starget->hostdata; | 4236 | struct ipr_sata_port *sata_port = starget->hostdata; |
4237 | struct Scsi_Host *shost = dev_to_shost(&starget->dev); | ||
4238 | struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; | ||
4239 | |||
4240 | if (ioa_cfg->sis64) { | ||
4241 | if (starget->channel == IPR_ARRAY_VIRTUAL_BUS) | ||
4242 | clear_bit(starget->id, ioa_cfg->array_ids); | ||
4243 | else if (starget->channel == IPR_VSET_VIRTUAL_BUS) | ||
4244 | clear_bit(starget->id, ioa_cfg->vset_ids); | ||
4245 | else if (starget->channel == 0) | ||
4246 | clear_bit(starget->id, ioa_cfg->target_ids); | ||
4247 | } | ||
3592 | 4248 | ||
3593 | if (sata_port) { | 4249 | if (sata_port) { |
3594 | starget->hostdata = NULL; | 4250 | starget->hostdata = NULL; |
@@ -3610,9 +4266,9 @@ static struct ipr_resource_entry *ipr_find_sdev(struct scsi_device *sdev) | |||
3610 | struct ipr_resource_entry *res; | 4266 | struct ipr_resource_entry *res; |
3611 | 4267 | ||
3612 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { | 4268 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
3613 | if ((res->cfgte.res_addr.bus == sdev->channel) && | 4269 | if ((res->bus == sdev->channel) && |
3614 | (res->cfgte.res_addr.target == sdev->id) && | 4270 | (res->target == sdev->id) && |
3615 | (res->cfgte.res_addr.lun == sdev->lun)) | 4271 | (res->lun == sdev->lun)) |
3616 | return res; | 4272 | return res; |
3617 | } | 4273 | } |
3618 | 4274 | ||
@@ -3661,6 +4317,7 @@ static int ipr_slave_configure(struct scsi_device *sdev) | |||
3661 | struct ipr_resource_entry *res; | 4317 | struct ipr_resource_entry *res; |
3662 | struct ata_port *ap = NULL; | 4318 | struct ata_port *ap = NULL; |
3663 | unsigned long lock_flags = 0; | 4319 | unsigned long lock_flags = 0; |
4320 | char buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
3664 | 4321 | ||
3665 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | 4322 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); |
3666 | res = sdev->hostdata; | 4323 | res = sdev->hostdata; |
@@ -3687,6 +4344,9 @@ static int ipr_slave_configure(struct scsi_device *sdev) | |||
3687 | ata_sas_slave_configure(sdev, ap); | 4344 | ata_sas_slave_configure(sdev, ap); |
3688 | } else | 4345 | } else |
3689 | scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); | 4346 | scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); |
4347 | if (ioa_cfg->sis64) | ||
4348 | sdev_printk(KERN_INFO, sdev, "Resource path: %s\n", | ||
4349 | ipr_format_resource_path(&res->res_path[0], &buffer[0])); | ||
3690 | return 0; | 4350 | return 0; |
3691 | } | 4351 | } |
3692 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 4352 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
@@ -3828,14 +4488,19 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, | |||
3828 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); | 4488 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); |
3829 | ioarcb = &ipr_cmd->ioarcb; | 4489 | ioarcb = &ipr_cmd->ioarcb; |
3830 | cmd_pkt = &ioarcb->cmd_pkt; | 4490 | cmd_pkt = &ioarcb->cmd_pkt; |
3831 | regs = &ioarcb->add_data.u.regs; | ||
3832 | 4491 | ||
3833 | ioarcb->res_handle = res->cfgte.res_handle; | 4492 | if (ipr_cmd->ioa_cfg->sis64) { |
4493 | regs = &ipr_cmd->i.ata_ioadl.regs; | ||
4494 | ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb)); | ||
4495 | } else | ||
4496 | regs = &ioarcb->u.add_data.u.regs; | ||
4497 | |||
4498 | ioarcb->res_handle = res->res_handle; | ||
3834 | cmd_pkt->request_type = IPR_RQTYPE_IOACMD; | 4499 | cmd_pkt->request_type = IPR_RQTYPE_IOACMD; |
3835 | cmd_pkt->cdb[0] = IPR_RESET_DEVICE; | 4500 | cmd_pkt->cdb[0] = IPR_RESET_DEVICE; |
3836 | if (ipr_is_gata(res)) { | 4501 | if (ipr_is_gata(res)) { |
3837 | cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET; | 4502 | cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET; |
3838 | ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(regs->flags)); | 4503 | ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(regs->flags)); |
3839 | regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; | 4504 | regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; |
3840 | } | 4505 | } |
3841 | 4506 | ||
@@ -3880,19 +4545,7 @@ static int ipr_sata_reset(struct ata_link *link, unsigned int *classes, | |||
3880 | res = sata_port->res; | 4545 | res = sata_port->res; |
3881 | if (res) { | 4546 | if (res) { |
3882 | rc = ipr_device_reset(ioa_cfg, res); | 4547 | rc = ipr_device_reset(ioa_cfg, res); |
3883 | switch(res->cfgte.proto) { | 4548 | *classes = res->ata_class; |
3884 | case IPR_PROTO_SATA: | ||
3885 | case IPR_PROTO_SAS_STP: | ||
3886 | *classes = ATA_DEV_ATA; | ||
3887 | break; | ||
3888 | case IPR_PROTO_SATA_ATAPI: | ||
3889 | case IPR_PROTO_SAS_STP_ATAPI: | ||
3890 | *classes = ATA_DEV_ATAPI; | ||
3891 | break; | ||
3892 | default: | ||
3893 | *classes = ATA_DEV_UNKNOWN; | ||
3894 | break; | ||
3895 | }; | ||
3896 | } | 4549 | } |
3897 | 4550 | ||
3898 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 4551 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
@@ -3937,7 +4590,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) | |||
3937 | return FAILED; | 4590 | return FAILED; |
3938 | 4591 | ||
3939 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { | 4592 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { |
3940 | if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { | 4593 | if (ipr_cmd->ioarcb.res_handle == res->res_handle) { |
3941 | if (ipr_cmd->scsi_cmd) | 4594 | if (ipr_cmd->scsi_cmd) |
3942 | ipr_cmd->done = ipr_scsi_eh_done; | 4595 | ipr_cmd->done = ipr_scsi_eh_done; |
3943 | if (ipr_cmd->qc) | 4596 | if (ipr_cmd->qc) |
@@ -3959,7 +4612,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) | |||
3959 | spin_lock_irq(scsi_cmd->device->host->host_lock); | 4612 | spin_lock_irq(scsi_cmd->device->host->host_lock); |
3960 | 4613 | ||
3961 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { | 4614 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { |
3962 | if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { | 4615 | if (ipr_cmd->ioarcb.res_handle == res->res_handle) { |
3963 | rc = -EIO; | 4616 | rc = -EIO; |
3964 | break; | 4617 | break; |
3965 | } | 4618 | } |
@@ -3998,13 +4651,13 @@ static void ipr_bus_reset_done(struct ipr_cmnd *ipr_cmd) | |||
3998 | struct ipr_resource_entry *res; | 4651 | struct ipr_resource_entry *res; |
3999 | 4652 | ||
4000 | ENTER; | 4653 | ENTER; |
4001 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { | 4654 | if (!ioa_cfg->sis64) |
4002 | if (!memcmp(&res->cfgte.res_handle, &ipr_cmd->ioarcb.res_handle, | 4655 | list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
4003 | sizeof(res->cfgte.res_handle))) { | 4656 | if (res->res_handle == ipr_cmd->ioarcb.res_handle) { |
4004 | scsi_report_bus_reset(ioa_cfg->host, res->cfgte.res_addr.bus); | 4657 | scsi_report_bus_reset(ioa_cfg->host, res->bus); |
4005 | break; | 4658 | break; |
4659 | } | ||
4006 | } | 4660 | } |
4007 | } | ||
4008 | 4661 | ||
4009 | /* | 4662 | /* |
4010 | * If abort has not completed, indicate the reset has, else call the | 4663 | * If abort has not completed, indicate the reset has, else call the |
@@ -4102,7 +4755,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd) | |||
4102 | return SUCCESS; | 4755 | return SUCCESS; |
4103 | 4756 | ||
4104 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); | 4757 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); |
4105 | ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle; | 4758 | ipr_cmd->ioarcb.res_handle = res->res_handle; |
4106 | cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; | 4759 | cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; |
4107 | cmd_pkt->request_type = IPR_RQTYPE_IOACMD; | 4760 | cmd_pkt->request_type = IPR_RQTYPE_IOACMD; |
4108 | cmd_pkt->cdb[0] = IPR_CANCEL_ALL_REQUESTS; | 4761 | cmd_pkt->cdb[0] = IPR_CANCEL_ALL_REQUESTS; |
@@ -4239,11 +4892,29 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
4239 | return IRQ_NONE; | 4892 | return IRQ_NONE; |
4240 | } | 4893 | } |
4241 | 4894 | ||
4242 | int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 4895 | int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32); |
4243 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | 4896 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; |
4244 | 4897 | ||
4245 | /* If an interrupt on the adapter did not occur, ignore it */ | 4898 | /* If an interrupt on the adapter did not occur, ignore it. |
4899 | * Or in the case of SIS 64, check for a stage change interrupt. | ||
4900 | */ | ||
4246 | if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) { | 4901 | if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) { |
4902 | if (ioa_cfg->sis64) { | ||
4903 | int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | ||
4904 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | ||
4905 | if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) { | ||
4906 | |||
4907 | /* clear stage change */ | ||
4908 | writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg); | ||
4909 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | ||
4910 | list_del(&ioa_cfg->reset_cmd->queue); | ||
4911 | del_timer(&ioa_cfg->reset_cmd->timer); | ||
4912 | ipr_reset_ioa_job(ioa_cfg->reset_cmd); | ||
4913 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
4914 | return IRQ_HANDLED; | ||
4915 | } | ||
4916 | } | ||
4917 | |||
4247 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 4918 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
4248 | return IRQ_NONE; | 4919 | return IRQ_NONE; |
4249 | } | 4920 | } |
@@ -4286,8 +4957,8 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
4286 | if (ipr_cmd != NULL) { | 4957 | if (ipr_cmd != NULL) { |
4287 | /* Clear the PCI interrupt */ | 4958 | /* Clear the PCI interrupt */ |
4288 | do { | 4959 | do { |
4289 | writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg); | 4960 | writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); |
4290 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | 4961 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; |
4291 | } while (int_reg & IPR_PCII_HRRQ_UPDATED && | 4962 | } while (int_reg & IPR_PCII_HRRQ_UPDATED && |
4292 | num_hrrq++ < IPR_MAX_HRRQ_RETRIES); | 4963 | num_hrrq++ < IPR_MAX_HRRQ_RETRIES); |
4293 | 4964 | ||
@@ -4309,6 +4980,53 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
4309 | } | 4980 | } |
4310 | 4981 | ||
4311 | /** | 4982 | /** |
4983 | * ipr_build_ioadl64 - Build a scatter/gather list and map the buffer | ||
4984 | * @ioa_cfg: ioa config struct | ||
4985 | * @ipr_cmd: ipr command struct | ||
4986 | * | ||
4987 | * Return value: | ||
4988 | * 0 on success / -1 on failure | ||
4989 | **/ | ||
4990 | static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg, | ||
4991 | struct ipr_cmnd *ipr_cmd) | ||
4992 | { | ||
4993 | int i, nseg; | ||
4994 | struct scatterlist *sg; | ||
4995 | u32 length; | ||
4996 | u32 ioadl_flags = 0; | ||
4997 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; | ||
4998 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | ||
4999 | struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; | ||
5000 | |||
5001 | length = scsi_bufflen(scsi_cmd); | ||
5002 | if (!length) | ||
5003 | return 0; | ||
5004 | |||
5005 | nseg = scsi_dma_map(scsi_cmd); | ||
5006 | if (nseg < 0) { | ||
5007 | dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n"); | ||
5008 | return -1; | ||
5009 | } | ||
5010 | |||
5011 | ipr_cmd->dma_use_sg = nseg; | ||
5012 | |||
5013 | if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) { | ||
5014 | ioadl_flags = IPR_IOADL_FLAGS_WRITE; | ||
5015 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | ||
5016 | } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) | ||
5017 | ioadl_flags = IPR_IOADL_FLAGS_READ; | ||
5018 | |||
5019 | scsi_for_each_sg(scsi_cmd, sg, ipr_cmd->dma_use_sg, i) { | ||
5020 | ioadl64[i].flags = cpu_to_be32(ioadl_flags); | ||
5021 | ioadl64[i].data_len = cpu_to_be32(sg_dma_len(sg)); | ||
5022 | ioadl64[i].address = cpu_to_be64(sg_dma_address(sg)); | ||
5023 | } | ||
5024 | |||
5025 | ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST); | ||
5026 | return 0; | ||
5027 | } | ||
5028 | |||
5029 | /** | ||
4312 | * ipr_build_ioadl - Build a scatter/gather list and map the buffer | 5030 | * ipr_build_ioadl - Build a scatter/gather list and map the buffer |
4313 | * @ioa_cfg: ioa config struct | 5031 | * @ioa_cfg: ioa config struct |
4314 | * @ipr_cmd: ipr command struct | 5032 | * @ipr_cmd: ipr command struct |
@@ -4325,7 +5043,7 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, | |||
4325 | u32 ioadl_flags = 0; | 5043 | u32 ioadl_flags = 0; |
4326 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; | 5044 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; |
4327 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 5045 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
4328 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | 5046 | struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl; |
4329 | 5047 | ||
4330 | length = scsi_bufflen(scsi_cmd); | 5048 | length = scsi_bufflen(scsi_cmd); |
4331 | if (!length) | 5049 | if (!length) |
@@ -4342,8 +5060,8 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, | |||
4342 | if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) { | 5060 | if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) { |
4343 | ioadl_flags = IPR_IOADL_FLAGS_WRITE; | 5061 | ioadl_flags = IPR_IOADL_FLAGS_WRITE; |
4344 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | 5062 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; |
4345 | ioarcb->write_data_transfer_length = cpu_to_be32(length); | 5063 | ioarcb->data_transfer_length = cpu_to_be32(length); |
4346 | ioarcb->write_ioadl_len = | 5064 | ioarcb->ioadl_len = |
4347 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); | 5065 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); |
4348 | } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) { | 5066 | } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) { |
4349 | ioadl_flags = IPR_IOADL_FLAGS_READ; | 5067 | ioadl_flags = IPR_IOADL_FLAGS_READ; |
@@ -4352,11 +5070,10 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, | |||
4352 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); | 5070 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); |
4353 | } | 5071 | } |
4354 | 5072 | ||
4355 | if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) { | 5073 | if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->u.add_data.u.ioadl)) { |
4356 | ioadl = ioarcb->add_data.u.ioadl; | 5074 | ioadl = ioarcb->u.add_data.u.ioadl; |
4357 | ioarcb->write_ioadl_addr = | 5075 | ioarcb->write_ioadl_addr = cpu_to_be32((ipr_cmd->dma_addr) + |
4358 | cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) + | 5076 | offsetof(struct ipr_ioarcb, u.add_data)); |
4359 | offsetof(struct ipr_ioarcb, add_data)); | ||
4360 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | 5077 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; |
4361 | } | 5078 | } |
4362 | 5079 | ||
@@ -4446,18 +5163,24 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) | |||
4446 | { | 5163 | { |
4447 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 5164 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
4448 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; | 5165 | struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; |
4449 | dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr); | 5166 | dma_addr_t dma_addr = ipr_cmd->dma_addr; |
4450 | 5167 | ||
4451 | memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); | 5168 | memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); |
4452 | ioarcb->write_data_transfer_length = 0; | 5169 | ioarcb->data_transfer_length = 0; |
4453 | ioarcb->read_data_transfer_length = 0; | 5170 | ioarcb->read_data_transfer_length = 0; |
4454 | ioarcb->write_ioadl_len = 0; | 5171 | ioarcb->ioadl_len = 0; |
4455 | ioarcb->read_ioadl_len = 0; | 5172 | ioarcb->read_ioadl_len = 0; |
4456 | ioasa->ioasc = 0; | 5173 | ioasa->ioasc = 0; |
4457 | ioasa->residual_data_len = 0; | 5174 | ioasa->residual_data_len = 0; |
4458 | ioarcb->write_ioadl_addr = | 5175 | |
4459 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); | 5176 | if (ipr_cmd->ioa_cfg->sis64) |
4460 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | 5177 | ioarcb->u.sis64_addr_data.data_ioadl_addr = |
5178 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); | ||
5179 | else { | ||
5180 | ioarcb->write_ioadl_addr = | ||
5181 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); | ||
5182 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | ||
5183 | } | ||
4461 | } | 5184 | } |
4462 | 5185 | ||
4463 | /** | 5186 | /** |
@@ -4489,15 +5212,8 @@ static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd) | |||
4489 | cmd_pkt->flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; | 5212 | cmd_pkt->flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; |
4490 | cmd_pkt->timeout = cpu_to_be16(IPR_REQUEST_SENSE_TIMEOUT / HZ); | 5213 | cmd_pkt->timeout = cpu_to_be16(IPR_REQUEST_SENSE_TIMEOUT / HZ); |
4491 | 5214 | ||
4492 | ipr_cmd->ioadl[0].flags_and_data_len = | 5215 | ipr_init_ioadl(ipr_cmd, ipr_cmd->sense_buffer_dma, |
4493 | cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | SCSI_SENSE_BUFFERSIZE); | 5216 | SCSI_SENSE_BUFFERSIZE, IPR_IOADL_FLAGS_READ_LAST); |
4494 | ipr_cmd->ioadl[0].address = | ||
4495 | cpu_to_be32(ipr_cmd->sense_buffer_dma); | ||
4496 | |||
4497 | ipr_cmd->ioarcb.read_ioadl_len = | ||
4498 | cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | ||
4499 | ipr_cmd->ioarcb.read_data_transfer_length = | ||
4500 | cpu_to_be32(SCSI_SENSE_BUFFERSIZE); | ||
4501 | 5217 | ||
4502 | ipr_do_req(ipr_cmd, ipr_erp_done, ipr_timeout, | 5218 | ipr_do_req(ipr_cmd, ipr_erp_done, ipr_timeout, |
4503 | IPR_REQUEST_SENSE_TIMEOUT * 2); | 5219 | IPR_REQUEST_SENSE_TIMEOUT * 2); |
@@ -4893,9 +5609,9 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd, | |||
4893 | 5609 | ||
4894 | memcpy(ioarcb->cmd_pkt.cdb, scsi_cmd->cmnd, scsi_cmd->cmd_len); | 5610 | memcpy(ioarcb->cmd_pkt.cdb, scsi_cmd->cmnd, scsi_cmd->cmd_len); |
4895 | ipr_cmd->scsi_cmd = scsi_cmd; | 5611 | ipr_cmd->scsi_cmd = scsi_cmd; |
4896 | ioarcb->res_handle = res->cfgte.res_handle; | 5612 | ioarcb->res_handle = res->res_handle; |
4897 | ipr_cmd->done = ipr_scsi_done; | 5613 | ipr_cmd->done = ipr_scsi_done; |
4898 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr)); | 5614 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res)); |
4899 | 5615 | ||
4900 | if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) { | 5616 | if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) { |
4901 | if (scsi_cmd->underflow == 0) | 5617 | if (scsi_cmd->underflow == 0) |
@@ -4916,13 +5632,16 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd, | |||
4916 | (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) | 5632 | (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) |
4917 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | 5633 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; |
4918 | 5634 | ||
4919 | if (likely(rc == 0)) | 5635 | if (likely(rc == 0)) { |
4920 | rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); | 5636 | if (ioa_cfg->sis64) |
5637 | rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd); | ||
5638 | else | ||
5639 | rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); | ||
5640 | } | ||
4921 | 5641 | ||
4922 | if (likely(rc == 0)) { | 5642 | if (likely(rc == 0)) { |
4923 | mb(); | 5643 | mb(); |
4924 | writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr), | 5644 | ipr_send_command(ipr_cmd); |
4925 | ioa_cfg->regs.ioarrin_reg); | ||
4926 | } else { | 5645 | } else { |
4927 | list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q); | 5646 | list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q); |
4928 | return SCSI_MLQUEUE_HOST_BUSY; | 5647 | return SCSI_MLQUEUE_HOST_BUSY; |
@@ -5035,20 +5754,9 @@ static void ipr_ata_phy_reset(struct ata_port *ap) | |||
5035 | goto out_unlock; | 5754 | goto out_unlock; |
5036 | } | 5755 | } |
5037 | 5756 | ||
5038 | switch(res->cfgte.proto) { | 5757 | ap->link.device[0].class = res->ata_class; |
5039 | case IPR_PROTO_SATA: | 5758 | if (ap->link.device[0].class == ATA_DEV_UNKNOWN) |
5040 | case IPR_PROTO_SAS_STP: | ||
5041 | ap->link.device[0].class = ATA_DEV_ATA; | ||
5042 | break; | ||
5043 | case IPR_PROTO_SATA_ATAPI: | ||
5044 | case IPR_PROTO_SAS_STP_ATAPI: | ||
5045 | ap->link.device[0].class = ATA_DEV_ATAPI; | ||
5046 | break; | ||
5047 | default: | ||
5048 | ap->link.device[0].class = ATA_DEV_UNKNOWN; | ||
5049 | ata_port_disable(ap); | 5759 | ata_port_disable(ap); |
5050 | break; | ||
5051 | }; | ||
5052 | 5760 | ||
5053 | out_unlock: | 5761 | out_unlock: |
5054 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); | 5762 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); |
@@ -5134,8 +5842,7 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd) | |||
5134 | ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); | 5842 | ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); |
5135 | 5843 | ||
5136 | if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET) | 5844 | if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET) |
5137 | scsi_report_device_reset(ioa_cfg->host, res->cfgte.res_addr.bus, | 5845 | scsi_report_device_reset(ioa_cfg->host, res->bus, res->target); |
5138 | res->cfgte.res_addr.target); | ||
5139 | 5846 | ||
5140 | if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) | 5847 | if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) |
5141 | qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status); | 5848 | qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status); |
@@ -5146,6 +5853,52 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd) | |||
5146 | } | 5853 | } |
5147 | 5854 | ||
5148 | /** | 5855 | /** |
5856 | * ipr_build_ata_ioadl64 - Build an ATA scatter/gather list | ||
5857 | * @ipr_cmd: ipr command struct | ||
5858 | * @qc: ATA queued command | ||
5859 | * | ||
5860 | **/ | ||
5861 | static void ipr_build_ata_ioadl64(struct ipr_cmnd *ipr_cmd, | ||
5862 | struct ata_queued_cmd *qc) | ||
5863 | { | ||
5864 | u32 ioadl_flags = 0; | ||
5865 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | ||
5866 | struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; | ||
5867 | struct ipr_ioadl64_desc *last_ioadl64 = NULL; | ||
5868 | int len = qc->nbytes; | ||
5869 | struct scatterlist *sg; | ||
5870 | unsigned int si; | ||
5871 | dma_addr_t dma_addr = ipr_cmd->dma_addr; | ||
5872 | |||
5873 | if (len == 0) | ||
5874 | return; | ||
5875 | |||
5876 | if (qc->dma_dir == DMA_TO_DEVICE) { | ||
5877 | ioadl_flags = IPR_IOADL_FLAGS_WRITE; | ||
5878 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | ||
5879 | } else if (qc->dma_dir == DMA_FROM_DEVICE) | ||
5880 | ioadl_flags = IPR_IOADL_FLAGS_READ; | ||
5881 | |||
5882 | ioarcb->data_transfer_length = cpu_to_be32(len); | ||
5883 | ioarcb->ioadl_len = | ||
5884 | cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg); | ||
5885 | ioarcb->u.sis64_addr_data.data_ioadl_addr = | ||
5886 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ata_ioadl)); | ||
5887 | |||
5888 | for_each_sg(qc->sg, sg, qc->n_elem, si) { | ||
5889 | ioadl64->flags = cpu_to_be32(ioadl_flags); | ||
5890 | ioadl64->data_len = cpu_to_be32(sg_dma_len(sg)); | ||
5891 | ioadl64->address = cpu_to_be64(sg_dma_address(sg)); | ||
5892 | |||
5893 | last_ioadl64 = ioadl64; | ||
5894 | ioadl64++; | ||
5895 | } | ||
5896 | |||
5897 | if (likely(last_ioadl64)) | ||
5898 | last_ioadl64->flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST); | ||
5899 | } | ||
5900 | |||
5901 | /** | ||
5149 | * ipr_build_ata_ioadl - Build an ATA scatter/gather list | 5902 | * ipr_build_ata_ioadl - Build an ATA scatter/gather list |
5150 | * @ipr_cmd: ipr command struct | 5903 | * @ipr_cmd: ipr command struct |
5151 | * @qc: ATA queued command | 5904 | * @qc: ATA queued command |
@@ -5156,7 +5909,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, | |||
5156 | { | 5909 | { |
5157 | u32 ioadl_flags = 0; | 5910 | u32 ioadl_flags = 0; |
5158 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 5911 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
5159 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | 5912 | struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl; |
5160 | struct ipr_ioadl_desc *last_ioadl = NULL; | 5913 | struct ipr_ioadl_desc *last_ioadl = NULL; |
5161 | int len = qc->nbytes; | 5914 | int len = qc->nbytes; |
5162 | struct scatterlist *sg; | 5915 | struct scatterlist *sg; |
@@ -5168,8 +5921,8 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, | |||
5168 | if (qc->dma_dir == DMA_TO_DEVICE) { | 5921 | if (qc->dma_dir == DMA_TO_DEVICE) { |
5169 | ioadl_flags = IPR_IOADL_FLAGS_WRITE; | 5922 | ioadl_flags = IPR_IOADL_FLAGS_WRITE; |
5170 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | 5923 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; |
5171 | ioarcb->write_data_transfer_length = cpu_to_be32(len); | 5924 | ioarcb->data_transfer_length = cpu_to_be32(len); |
5172 | ioarcb->write_ioadl_len = | 5925 | ioarcb->ioadl_len = |
5173 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); | 5926 | cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); |
5174 | } else if (qc->dma_dir == DMA_FROM_DEVICE) { | 5927 | } else if (qc->dma_dir == DMA_FROM_DEVICE) { |
5175 | ioadl_flags = IPR_IOADL_FLAGS_READ; | 5928 | ioadl_flags = IPR_IOADL_FLAGS_READ; |
@@ -5212,25 +5965,34 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) | |||
5212 | 5965 | ||
5213 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); | 5966 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); |
5214 | ioarcb = &ipr_cmd->ioarcb; | 5967 | ioarcb = &ipr_cmd->ioarcb; |
5215 | regs = &ioarcb->add_data.u.regs; | ||
5216 | 5968 | ||
5217 | memset(&ioarcb->add_data, 0, sizeof(ioarcb->add_data)); | 5969 | if (ioa_cfg->sis64) { |
5218 | ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(ioarcb->add_data.u.regs)); | 5970 | regs = &ipr_cmd->i.ata_ioadl.regs; |
5971 | ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb)); | ||
5972 | } else | ||
5973 | regs = &ioarcb->u.add_data.u.regs; | ||
5974 | |||
5975 | memset(regs, 0, sizeof(*regs)); | ||
5976 | ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(*regs)); | ||
5219 | 5977 | ||
5220 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); | 5978 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); |
5221 | ipr_cmd->qc = qc; | 5979 | ipr_cmd->qc = qc; |
5222 | ipr_cmd->done = ipr_sata_done; | 5980 | ipr_cmd->done = ipr_sata_done; |
5223 | ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle; | 5981 | ipr_cmd->ioarcb.res_handle = res->res_handle; |
5224 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU; | 5982 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU; |
5225 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC; | 5983 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC; |
5226 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; | 5984 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; |
5227 | ipr_cmd->dma_use_sg = qc->n_elem; | 5985 | ipr_cmd->dma_use_sg = qc->n_elem; |
5228 | 5986 | ||
5229 | ipr_build_ata_ioadl(ipr_cmd, qc); | 5987 | if (ioa_cfg->sis64) |
5988 | ipr_build_ata_ioadl64(ipr_cmd, qc); | ||
5989 | else | ||
5990 | ipr_build_ata_ioadl(ipr_cmd, qc); | ||
5991 | |||
5230 | regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; | 5992 | regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; |
5231 | ipr_copy_sata_tf(regs, &qc->tf); | 5993 | ipr_copy_sata_tf(regs, &qc->tf); |
5232 | memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN); | 5994 | memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN); |
5233 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr)); | 5995 | ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res)); |
5234 | 5996 | ||
5235 | switch (qc->tf.protocol) { | 5997 | switch (qc->tf.protocol) { |
5236 | case ATA_PROT_NODATA: | 5998 | case ATA_PROT_NODATA: |
@@ -5257,8 +6019,9 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) | |||
5257 | } | 6019 | } |
5258 | 6020 | ||
5259 | mb(); | 6021 | mb(); |
5260 | writel(be32_to_cpu(ioarcb->ioarcb_host_pci_addr), | 6022 | |
5261 | ioa_cfg->regs.ioarrin_reg); | 6023 | ipr_send_command(ipr_cmd); |
6024 | |||
5262 | return 0; | 6025 | return 0; |
5263 | } | 6026 | } |
5264 | 6027 | ||
@@ -5459,7 +6222,7 @@ static void ipr_set_sup_dev_dflt(struct ipr_supported_device *supported_dev, | |||
5459 | * ipr_set_supported_devs - Send Set Supported Devices for a device | 6222 | * ipr_set_supported_devs - Send Set Supported Devices for a device |
5460 | * @ipr_cmd: ipr command struct | 6223 | * @ipr_cmd: ipr command struct |
5461 | * | 6224 | * |
5462 | * This function send a Set Supported Devices to the adapter | 6225 | * This function sends a Set Supported Devices to the adapter |
5463 | * | 6226 | * |
5464 | * Return value: | 6227 | * Return value: |
5465 | * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN | 6228 | * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN |
@@ -5468,7 +6231,6 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) | |||
5468 | { | 6231 | { |
5469 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6232 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
5470 | struct ipr_supported_device *supp_dev = &ioa_cfg->vpd_cbs->supp_dev; | 6233 | struct ipr_supported_device *supp_dev = &ioa_cfg->vpd_cbs->supp_dev; |
5471 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | ||
5472 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6234 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
5473 | struct ipr_resource_entry *res = ipr_cmd->u.res; | 6235 | struct ipr_resource_entry *res = ipr_cmd->u.res; |
5474 | 6236 | ||
@@ -5479,28 +6241,28 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) | |||
5479 | continue; | 6241 | continue; |
5480 | 6242 | ||
5481 | ipr_cmd->u.res = res; | 6243 | ipr_cmd->u.res = res; |
5482 | ipr_set_sup_dev_dflt(supp_dev, &res->cfgte.std_inq_data.vpids); | 6244 | ipr_set_sup_dev_dflt(supp_dev, &res->std_inq_data.vpids); |
5483 | 6245 | ||
5484 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | 6246 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); |
5485 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; | 6247 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; |
5486 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | 6248 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; |
5487 | 6249 | ||
5488 | ioarcb->cmd_pkt.cdb[0] = IPR_SET_SUPPORTED_DEVICES; | 6250 | ioarcb->cmd_pkt.cdb[0] = IPR_SET_SUPPORTED_DEVICES; |
6251 | ioarcb->cmd_pkt.cdb[1] = IPR_SET_ALL_SUPPORTED_DEVICES; | ||
5489 | ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_supported_device) >> 8) & 0xff; | 6252 | ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_supported_device) >> 8) & 0xff; |
5490 | ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_supported_device) & 0xff; | 6253 | ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_supported_device) & 0xff; |
5491 | 6254 | ||
5492 | ioadl->flags_and_data_len = cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST | | 6255 | ipr_init_ioadl(ipr_cmd, |
5493 | sizeof(struct ipr_supported_device)); | 6256 | ioa_cfg->vpd_cbs_dma + |
5494 | ioadl->address = cpu_to_be32(ioa_cfg->vpd_cbs_dma + | 6257 | offsetof(struct ipr_misc_cbs, supp_dev), |
5495 | offsetof(struct ipr_misc_cbs, supp_dev)); | 6258 | sizeof(struct ipr_supported_device), |
5496 | ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | 6259 | IPR_IOADL_FLAGS_WRITE_LAST); |
5497 | ioarcb->write_data_transfer_length = | ||
5498 | cpu_to_be32(sizeof(struct ipr_supported_device)); | ||
5499 | 6260 | ||
5500 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, | 6261 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, |
5501 | IPR_SET_SUP_DEVICE_TIMEOUT); | 6262 | IPR_SET_SUP_DEVICE_TIMEOUT); |
5502 | 6263 | ||
5503 | ipr_cmd->job_step = ipr_set_supported_devs; | 6264 | if (!ioa_cfg->sis64) |
6265 | ipr_cmd->job_step = ipr_set_supported_devs; | ||
5504 | return IPR_RC_JOB_RETURN; | 6266 | return IPR_RC_JOB_RETURN; |
5505 | } | 6267 | } |
5506 | 6268 | ||
@@ -5508,36 +6270,6 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) | |||
5508 | } | 6270 | } |
5509 | 6271 | ||
5510 | /** | 6272 | /** |
5511 | * ipr_setup_write_cache - Disable write cache if needed | ||
5512 | * @ipr_cmd: ipr command struct | ||
5513 | * | ||
5514 | * This function sets up adapters write cache to desired setting | ||
5515 | * | ||
5516 | * Return value: | ||
5517 | * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN | ||
5518 | **/ | ||
5519 | static int ipr_setup_write_cache(struct ipr_cmnd *ipr_cmd) | ||
5520 | { | ||
5521 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
5522 | |||
5523 | ipr_cmd->job_step = ipr_set_supported_devs; | ||
5524 | ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next, | ||
5525 | struct ipr_resource_entry, queue); | ||
5526 | |||
5527 | if (ioa_cfg->cache_state != CACHE_DISABLED) | ||
5528 | return IPR_RC_JOB_CONTINUE; | ||
5529 | |||
5530 | ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | ||
5531 | ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | ||
5532 | ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN; | ||
5533 | ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL; | ||
5534 | |||
5535 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); | ||
5536 | |||
5537 | return IPR_RC_JOB_RETURN; | ||
5538 | } | ||
5539 | |||
5540 | /** | ||
5541 | * ipr_get_mode_page - Locate specified mode page | 6273 | * ipr_get_mode_page - Locate specified mode page |
5542 | * @mode_pages: mode page buffer | 6274 | * @mode_pages: mode page buffer |
5543 | * @page_code: page code to find | 6275 | * @page_code: page code to find |
@@ -5695,10 +6427,9 @@ static void ipr_modify_ioafp_mode_page_28(struct ipr_ioa_cfg *ioa_cfg, | |||
5695 | * none | 6427 | * none |
5696 | **/ | 6428 | **/ |
5697 | static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd, | 6429 | static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd, |
5698 | __be32 res_handle, u8 parm, u32 dma_addr, | 6430 | __be32 res_handle, u8 parm, |
5699 | u8 xfer_len) | 6431 | dma_addr_t dma_addr, u8 xfer_len) |
5700 | { | 6432 | { |
5701 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | ||
5702 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6433 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
5703 | 6434 | ||
5704 | ioarcb->res_handle = res_handle; | 6435 | ioarcb->res_handle = res_handle; |
@@ -5708,11 +6439,7 @@ static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd, | |||
5708 | ioarcb->cmd_pkt.cdb[1] = parm; | 6439 | ioarcb->cmd_pkt.cdb[1] = parm; |
5709 | ioarcb->cmd_pkt.cdb[4] = xfer_len; | 6440 | ioarcb->cmd_pkt.cdb[4] = xfer_len; |
5710 | 6441 | ||
5711 | ioadl->flags_and_data_len = | 6442 | ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_WRITE_LAST); |
5712 | cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST | xfer_len); | ||
5713 | ioadl->address = cpu_to_be32(dma_addr); | ||
5714 | ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | ||
5715 | ioarcb->write_data_transfer_length = cpu_to_be32(xfer_len); | ||
5716 | } | 6443 | } |
5717 | 6444 | ||
5718 | /** | 6445 | /** |
@@ -5742,7 +6469,9 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd) | |||
5742 | ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), | 6469 | ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), |
5743 | length); | 6470 | length); |
5744 | 6471 | ||
5745 | ipr_cmd->job_step = ipr_setup_write_cache; | 6472 | ipr_cmd->job_step = ipr_set_supported_devs; |
6473 | ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next, | ||
6474 | struct ipr_resource_entry, queue); | ||
5746 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); | 6475 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); |
5747 | 6476 | ||
5748 | LEAVE; | 6477 | LEAVE; |
@@ -5762,9 +6491,8 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd) | |||
5762 | **/ | 6491 | **/ |
5763 | static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, | 6492 | static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, |
5764 | __be32 res_handle, | 6493 | __be32 res_handle, |
5765 | u8 parm, u32 dma_addr, u8 xfer_len) | 6494 | u8 parm, dma_addr_t dma_addr, u8 xfer_len) |
5766 | { | 6495 | { |
5767 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | ||
5768 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6496 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
5769 | 6497 | ||
5770 | ioarcb->res_handle = res_handle; | 6498 | ioarcb->res_handle = res_handle; |
@@ -5773,11 +6501,7 @@ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, | |||
5773 | ioarcb->cmd_pkt.cdb[4] = xfer_len; | 6501 | ioarcb->cmd_pkt.cdb[4] = xfer_len; |
5774 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB; | 6502 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB; |
5775 | 6503 | ||
5776 | ioadl->flags_and_data_len = | 6504 | ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST); |
5777 | cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len); | ||
5778 | ioadl->address = cpu_to_be32(dma_addr); | ||
5779 | ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | ||
5780 | ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len); | ||
5781 | } | 6505 | } |
5782 | 6506 | ||
5783 | /** | 6507 | /** |
@@ -5815,10 +6539,13 @@ static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd) | |||
5815 | **/ | 6539 | **/ |
5816 | static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd) | 6540 | static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd) |
5817 | { | 6541 | { |
6542 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
5818 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); | 6543 | u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); |
5819 | 6544 | ||
5820 | if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { | 6545 | if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { |
5821 | ipr_cmd->job_step = ipr_setup_write_cache; | 6546 | ipr_cmd->job_step = ipr_set_supported_devs; |
6547 | ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next, | ||
6548 | struct ipr_resource_entry, queue); | ||
5822 | return IPR_RC_JOB_CONTINUE; | 6549 | return IPR_RC_JOB_CONTINUE; |
5823 | } | 6550 | } |
5824 | 6551 | ||
@@ -5958,24 +6685,36 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) | |||
5958 | { | 6685 | { |
5959 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6686 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
5960 | struct ipr_resource_entry *res, *temp; | 6687 | struct ipr_resource_entry *res, *temp; |
5961 | struct ipr_config_table_entry *cfgte; | 6688 | struct ipr_config_table_entry_wrapper cfgtew; |
5962 | int found, i; | 6689 | int entries, found, flag, i; |
5963 | LIST_HEAD(old_res); | 6690 | LIST_HEAD(old_res); |
5964 | 6691 | ||
5965 | ENTER; | 6692 | ENTER; |
5966 | if (ioa_cfg->cfg_table->hdr.flags & IPR_UCODE_DOWNLOAD_REQ) | 6693 | if (ioa_cfg->sis64) |
6694 | flag = ioa_cfg->u.cfg_table64->hdr64.flags; | ||
6695 | else | ||
6696 | flag = ioa_cfg->u.cfg_table->hdr.flags; | ||
6697 | |||
6698 | if (flag & IPR_UCODE_DOWNLOAD_REQ) | ||
5967 | dev_err(&ioa_cfg->pdev->dev, "Microcode download required\n"); | 6699 | dev_err(&ioa_cfg->pdev->dev, "Microcode download required\n"); |
5968 | 6700 | ||
5969 | list_for_each_entry_safe(res, temp, &ioa_cfg->used_res_q, queue) | 6701 | list_for_each_entry_safe(res, temp, &ioa_cfg->used_res_q, queue) |
5970 | list_move_tail(&res->queue, &old_res); | 6702 | list_move_tail(&res->queue, &old_res); |
5971 | 6703 | ||
5972 | for (i = 0; i < ioa_cfg->cfg_table->hdr.num_entries; i++) { | 6704 | if (ioa_cfg->sis64) |
5973 | cfgte = &ioa_cfg->cfg_table->dev[i]; | 6705 | entries = ioa_cfg->u.cfg_table64->hdr64.num_entries; |
6706 | else | ||
6707 | entries = ioa_cfg->u.cfg_table->hdr.num_entries; | ||
6708 | |||
6709 | for (i = 0; i < entries; i++) { | ||
6710 | if (ioa_cfg->sis64) | ||
6711 | cfgtew.u.cfgte64 = &ioa_cfg->u.cfg_table64->dev[i]; | ||
6712 | else | ||
6713 | cfgtew.u.cfgte = &ioa_cfg->u.cfg_table->dev[i]; | ||
5974 | found = 0; | 6714 | found = 0; |
5975 | 6715 | ||
5976 | list_for_each_entry_safe(res, temp, &old_res, queue) { | 6716 | list_for_each_entry_safe(res, temp, &old_res, queue) { |
5977 | if (!memcmp(&res->cfgte.res_addr, | 6717 | if (ipr_is_same_device(res, &cfgtew)) { |
5978 | &cfgte->res_addr, sizeof(cfgte->res_addr))) { | ||
5979 | list_move_tail(&res->queue, &ioa_cfg->used_res_q); | 6718 | list_move_tail(&res->queue, &ioa_cfg->used_res_q); |
5980 | found = 1; | 6719 | found = 1; |
5981 | break; | 6720 | break; |
@@ -5992,24 +6731,27 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) | |||
5992 | res = list_entry(ioa_cfg->free_res_q.next, | 6731 | res = list_entry(ioa_cfg->free_res_q.next, |
5993 | struct ipr_resource_entry, queue); | 6732 | struct ipr_resource_entry, queue); |
5994 | list_move_tail(&res->queue, &ioa_cfg->used_res_q); | 6733 | list_move_tail(&res->queue, &ioa_cfg->used_res_q); |
5995 | ipr_init_res_entry(res); | 6734 | ipr_init_res_entry(res, &cfgtew); |
5996 | res->add_to_ml = 1; | 6735 | res->add_to_ml = 1; |
5997 | } | 6736 | } |
5998 | 6737 | ||
5999 | if (found) | 6738 | if (found) |
6000 | memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry)); | 6739 | ipr_update_res_entry(res, &cfgtew); |
6001 | } | 6740 | } |
6002 | 6741 | ||
6003 | list_for_each_entry_safe(res, temp, &old_res, queue) { | 6742 | list_for_each_entry_safe(res, temp, &old_res, queue) { |
6004 | if (res->sdev) { | 6743 | if (res->sdev) { |
6005 | res->del_from_ml = 1; | 6744 | res->del_from_ml = 1; |
6006 | res->cfgte.res_handle = IPR_INVALID_RES_HANDLE; | 6745 | res->res_handle = IPR_INVALID_RES_HANDLE; |
6007 | list_move_tail(&res->queue, &ioa_cfg->used_res_q); | 6746 | list_move_tail(&res->queue, &ioa_cfg->used_res_q); |
6008 | } else { | ||
6009 | list_move_tail(&res->queue, &ioa_cfg->free_res_q); | ||
6010 | } | 6747 | } |
6011 | } | 6748 | } |
6012 | 6749 | ||
6750 | list_for_each_entry_safe(res, temp, &old_res, queue) { | ||
6751 | ipr_clear_res_target(res); | ||
6752 | list_move_tail(&res->queue, &ioa_cfg->free_res_q); | ||
6753 | } | ||
6754 | |||
6013 | if (ioa_cfg->dual_raid && ipr_dual_ioa_raid) | 6755 | if (ioa_cfg->dual_raid && ipr_dual_ioa_raid) |
6014 | ipr_cmd->job_step = ipr_ioafp_mode_sense_page24; | 6756 | ipr_cmd->job_step = ipr_ioafp_mode_sense_page24; |
6015 | else | 6757 | else |
@@ -6033,7 +6775,6 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) | |||
6033 | { | 6775 | { |
6034 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6776 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
6035 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6777 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
6036 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | ||
6037 | struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data; | 6778 | struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data; |
6038 | struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; | 6779 | struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; |
6039 | 6780 | ||
@@ -6047,16 +6788,11 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) | |||
6047 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | 6788 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); |
6048 | 6789 | ||
6049 | ioarcb->cmd_pkt.cdb[0] = IPR_QUERY_IOA_CONFIG; | 6790 | ioarcb->cmd_pkt.cdb[0] = IPR_QUERY_IOA_CONFIG; |
6050 | ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_config_table) >> 8) & 0xff; | 6791 | ioarcb->cmd_pkt.cdb[7] = (ioa_cfg->cfg_table_size >> 8) & 0xff; |
6051 | ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_config_table) & 0xff; | 6792 | ioarcb->cmd_pkt.cdb[8] = ioa_cfg->cfg_table_size & 0xff; |
6052 | 6793 | ||
6053 | ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | 6794 | ipr_init_ioadl(ipr_cmd, ioa_cfg->cfg_table_dma, ioa_cfg->cfg_table_size, |
6054 | ioarcb->read_data_transfer_length = | 6795 | IPR_IOADL_FLAGS_READ_LAST); |
6055 | cpu_to_be32(sizeof(struct ipr_config_table)); | ||
6056 | |||
6057 | ioadl->address = cpu_to_be32(ioa_cfg->cfg_table_dma); | ||
6058 | ioadl->flags_and_data_len = | ||
6059 | cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(struct ipr_config_table)); | ||
6060 | 6796 | ||
6061 | ipr_cmd->job_step = ipr_init_res_table; | 6797 | ipr_cmd->job_step = ipr_init_res_table; |
6062 | 6798 | ||
@@ -6076,10 +6812,9 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) | |||
6076 | * none | 6812 | * none |
6077 | **/ | 6813 | **/ |
6078 | static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page, | 6814 | static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page, |
6079 | u32 dma_addr, u8 xfer_len) | 6815 | dma_addr_t dma_addr, u8 xfer_len) |
6080 | { | 6816 | { |
6081 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6817 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
6082 | struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; | ||
6083 | 6818 | ||
6084 | ENTER; | 6819 | ENTER; |
6085 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB; | 6820 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB; |
@@ -6090,12 +6825,7 @@ static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page, | |||
6090 | ioarcb->cmd_pkt.cdb[2] = page; | 6825 | ioarcb->cmd_pkt.cdb[2] = page; |
6091 | ioarcb->cmd_pkt.cdb[4] = xfer_len; | 6826 | ioarcb->cmd_pkt.cdb[4] = xfer_len; |
6092 | 6827 | ||
6093 | ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); | 6828 | ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST); |
6094 | ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len); | ||
6095 | |||
6096 | ioadl->address = cpu_to_be32(dma_addr); | ||
6097 | ioadl->flags_and_data_len = | ||
6098 | cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len); | ||
6099 | 6829 | ||
6100 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); | 6830 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); |
6101 | LEAVE; | 6831 | LEAVE; |
@@ -6166,13 +6896,9 @@ static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd) | |||
6166 | static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd) | 6896 | static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd) |
6167 | { | 6897 | { |
6168 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6898 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
6169 | struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data; | ||
6170 | 6899 | ||
6171 | ENTER; | 6900 | ENTER; |
6172 | 6901 | ||
6173 | if (!ipr_inquiry_page_supported(page0, 1)) | ||
6174 | ioa_cfg->cache_state = CACHE_NONE; | ||
6175 | |||
6176 | ipr_cmd->job_step = ipr_ioafp_cap_inquiry; | 6902 | ipr_cmd->job_step = ipr_ioafp_cap_inquiry; |
6177 | 6903 | ||
6178 | ipr_ioafp_inquiry(ipr_cmd, 1, 3, | 6904 | ipr_ioafp_inquiry(ipr_cmd, 1, 3, |
@@ -6240,7 +6966,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd) | |||
6240 | } | 6966 | } |
6241 | 6967 | ||
6242 | /** | 6968 | /** |
6243 | * ipr_ioafp_indentify_hrrq - Send Identify Host RRQ. | 6969 | * ipr_ioafp_identify_hrrq - Send Identify Host RRQ. |
6244 | * @ipr_cmd: ipr command struct | 6970 | * @ipr_cmd: ipr command struct |
6245 | * | 6971 | * |
6246 | * This function send an Identify Host Request Response Queue | 6972 | * This function send an Identify Host Request Response Queue |
@@ -6249,7 +6975,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd) | |||
6249 | * Return value: | 6975 | * Return value: |
6250 | * IPR_RC_JOB_RETURN | 6976 | * IPR_RC_JOB_RETURN |
6251 | **/ | 6977 | **/ |
6252 | static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd) | 6978 | static int ipr_ioafp_identify_hrrq(struct ipr_cmnd *ipr_cmd) |
6253 | { | 6979 | { |
6254 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6980 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
6255 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; | 6981 | struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; |
@@ -6261,19 +6987,32 @@ static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd) | |||
6261 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | 6987 | ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); |
6262 | 6988 | ||
6263 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | 6989 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; |
6990 | if (ioa_cfg->sis64) | ||
6991 | ioarcb->cmd_pkt.cdb[1] = 0x1; | ||
6264 | ioarcb->cmd_pkt.cdb[2] = | 6992 | ioarcb->cmd_pkt.cdb[2] = |
6265 | ((u32) ioa_cfg->host_rrq_dma >> 24) & 0xff; | 6993 | ((u64) ioa_cfg->host_rrq_dma >> 24) & 0xff; |
6266 | ioarcb->cmd_pkt.cdb[3] = | 6994 | ioarcb->cmd_pkt.cdb[3] = |
6267 | ((u32) ioa_cfg->host_rrq_dma >> 16) & 0xff; | 6995 | ((u64) ioa_cfg->host_rrq_dma >> 16) & 0xff; |
6268 | ioarcb->cmd_pkt.cdb[4] = | 6996 | ioarcb->cmd_pkt.cdb[4] = |
6269 | ((u32) ioa_cfg->host_rrq_dma >> 8) & 0xff; | 6997 | ((u64) ioa_cfg->host_rrq_dma >> 8) & 0xff; |
6270 | ioarcb->cmd_pkt.cdb[5] = | 6998 | ioarcb->cmd_pkt.cdb[5] = |
6271 | ((u32) ioa_cfg->host_rrq_dma) & 0xff; | 6999 | ((u64) ioa_cfg->host_rrq_dma) & 0xff; |
6272 | ioarcb->cmd_pkt.cdb[7] = | 7000 | ioarcb->cmd_pkt.cdb[7] = |
6273 | ((sizeof(u32) * IPR_NUM_CMD_BLKS) >> 8) & 0xff; | 7001 | ((sizeof(u32) * IPR_NUM_CMD_BLKS) >> 8) & 0xff; |
6274 | ioarcb->cmd_pkt.cdb[8] = | 7002 | ioarcb->cmd_pkt.cdb[8] = |
6275 | (sizeof(u32) * IPR_NUM_CMD_BLKS) & 0xff; | 7003 | (sizeof(u32) * IPR_NUM_CMD_BLKS) & 0xff; |
6276 | 7004 | ||
7005 | if (ioa_cfg->sis64) { | ||
7006 | ioarcb->cmd_pkt.cdb[10] = | ||
7007 | ((u64) ioa_cfg->host_rrq_dma >> 56) & 0xff; | ||
7008 | ioarcb->cmd_pkt.cdb[11] = | ||
7009 | ((u64) ioa_cfg->host_rrq_dma >> 48) & 0xff; | ||
7010 | ioarcb->cmd_pkt.cdb[12] = | ||
7011 | ((u64) ioa_cfg->host_rrq_dma >> 40) & 0xff; | ||
7012 | ioarcb->cmd_pkt.cdb[13] = | ||
7013 | ((u64) ioa_cfg->host_rrq_dma >> 32) & 0xff; | ||
7014 | } | ||
7015 | |||
6277 | ipr_cmd->job_step = ipr_ioafp_std_inquiry; | 7016 | ipr_cmd->job_step = ipr_ioafp_std_inquiry; |
6278 | 7017 | ||
6279 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); | 7018 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); |
@@ -6354,7 +7093,58 @@ static void ipr_init_ioa_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
6354 | ioa_cfg->toggle_bit = 1; | 7093 | ioa_cfg->toggle_bit = 1; |
6355 | 7094 | ||
6356 | /* Zero out config table */ | 7095 | /* Zero out config table */ |
6357 | memset(ioa_cfg->cfg_table, 0, sizeof(struct ipr_config_table)); | 7096 | memset(ioa_cfg->u.cfg_table, 0, ioa_cfg->cfg_table_size); |
7097 | } | ||
7098 | |||
7099 | /** | ||
7100 | * ipr_reset_next_stage - Process IPL stage change based on feedback register. | ||
7101 | * @ipr_cmd: ipr command struct | ||
7102 | * | ||
7103 | * Return value: | ||
7104 | * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN | ||
7105 | **/ | ||
7106 | static int ipr_reset_next_stage(struct ipr_cmnd *ipr_cmd) | ||
7107 | { | ||
7108 | unsigned long stage, stage_time; | ||
7109 | u32 feedback; | ||
7110 | volatile u32 int_reg; | ||
7111 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
7112 | u64 maskval = 0; | ||
7113 | |||
7114 | feedback = readl(ioa_cfg->regs.init_feedback_reg); | ||
7115 | stage = feedback & IPR_IPL_INIT_STAGE_MASK; | ||
7116 | stage_time = feedback & IPR_IPL_INIT_STAGE_TIME_MASK; | ||
7117 | |||
7118 | ipr_dbg("IPL stage = 0x%lx, IPL stage time = %ld\n", stage, stage_time); | ||
7119 | |||
7120 | /* sanity check the stage_time value */ | ||
7121 | if (stage_time < IPR_IPL_INIT_MIN_STAGE_TIME) | ||
7122 | stage_time = IPR_IPL_INIT_MIN_STAGE_TIME; | ||
7123 | else if (stage_time > IPR_LONG_OPERATIONAL_TIMEOUT) | ||
7124 | stage_time = IPR_LONG_OPERATIONAL_TIMEOUT; | ||
7125 | |||
7126 | if (stage == IPR_IPL_INIT_STAGE_UNKNOWN) { | ||
7127 | writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.set_interrupt_mask_reg); | ||
7128 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | ||
7129 | stage_time = ioa_cfg->transop_timeout; | ||
7130 | ipr_cmd->job_step = ipr_ioafp_identify_hrrq; | ||
7131 | } else if (stage == IPR_IPL_INIT_STAGE_TRANSOP) { | ||
7132 | ipr_cmd->job_step = ipr_ioafp_identify_hrrq; | ||
7133 | maskval = IPR_PCII_IPL_STAGE_CHANGE; | ||
7134 | maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER; | ||
7135 | writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg); | ||
7136 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | ||
7137 | return IPR_RC_JOB_CONTINUE; | ||
7138 | } | ||
7139 | |||
7140 | ipr_cmd->timer.data = (unsigned long) ipr_cmd; | ||
7141 | ipr_cmd->timer.expires = jiffies + stage_time * HZ; | ||
7142 | ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; | ||
7143 | ipr_cmd->done = ipr_reset_ioa_job; | ||
7144 | add_timer(&ipr_cmd->timer); | ||
7145 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); | ||
7146 | |||
7147 | return IPR_RC_JOB_RETURN; | ||
6358 | } | 7148 | } |
6359 | 7149 | ||
6360 | /** | 7150 | /** |
@@ -6373,7 +7163,7 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) | |||
6373 | volatile u32 int_reg; | 7163 | volatile u32 int_reg; |
6374 | 7164 | ||
6375 | ENTER; | 7165 | ENTER; |
6376 | ipr_cmd->job_step = ipr_ioafp_indentify_hrrq; | 7166 | ipr_cmd->job_step = ipr_ioafp_identify_hrrq; |
6377 | ipr_init_ioa_mem(ioa_cfg); | 7167 | ipr_init_ioa_mem(ioa_cfg); |
6378 | 7168 | ||
6379 | ioa_cfg->allow_interrupts = 1; | 7169 | ioa_cfg->allow_interrupts = 1; |
@@ -6381,19 +7171,27 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) | |||
6381 | 7171 | ||
6382 | if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { | 7172 | if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { |
6383 | writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED), | 7173 | writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED), |
6384 | ioa_cfg->regs.clr_interrupt_mask_reg); | 7174 | ioa_cfg->regs.clr_interrupt_mask_reg32); |
6385 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 7175 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); |
6386 | return IPR_RC_JOB_CONTINUE; | 7176 | return IPR_RC_JOB_CONTINUE; |
6387 | } | 7177 | } |
6388 | 7178 | ||
6389 | /* Enable destructive diagnostics on IOA */ | 7179 | /* Enable destructive diagnostics on IOA */ |
6390 | writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg); | 7180 | writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg32); |
7181 | |||
7182 | writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg32); | ||
7183 | if (ioa_cfg->sis64) | ||
7184 | writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_mask_reg); | ||
6391 | 7185 | ||
6392 | writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg); | ||
6393 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 7186 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); |
6394 | 7187 | ||
6395 | dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n"); | 7188 | dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n"); |
6396 | 7189 | ||
7190 | if (ioa_cfg->sis64) { | ||
7191 | ipr_cmd->job_step = ipr_reset_next_stage; | ||
7192 | return IPR_RC_JOB_CONTINUE; | ||
7193 | } | ||
7194 | |||
6397 | ipr_cmd->timer.data = (unsigned long) ipr_cmd; | 7195 | ipr_cmd->timer.data = (unsigned long) ipr_cmd; |
6398 | ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ); | 7196 | ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ); |
6399 | ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; | 7197 | ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; |
@@ -6463,7 +7261,7 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) | |||
6463 | 7261 | ||
6464 | mailbox = readl(ioa_cfg->ioa_mailbox); | 7262 | mailbox = readl(ioa_cfg->ioa_mailbox); |
6465 | 7263 | ||
6466 | if (!ipr_sdt_is_fmt2(mailbox)) { | 7264 | if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(mailbox)) { |
6467 | ipr_unit_check_no_data(ioa_cfg); | 7265 | ipr_unit_check_no_data(ioa_cfg); |
6468 | return; | 7266 | return; |
6469 | } | 7267 | } |
@@ -6472,15 +7270,20 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) | |||
6472 | rc = ipr_get_ldump_data_section(ioa_cfg, mailbox, (__be32 *) &sdt, | 7270 | rc = ipr_get_ldump_data_section(ioa_cfg, mailbox, (__be32 *) &sdt, |
6473 | (sizeof(struct ipr_uc_sdt)) / sizeof(__be32)); | 7271 | (sizeof(struct ipr_uc_sdt)) / sizeof(__be32)); |
6474 | 7272 | ||
6475 | if (rc || (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE) || | 7273 | if (rc || !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY) || |
6476 | !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY)) { | 7274 | ((be32_to_cpu(sdt.hdr.state) != IPR_FMT3_SDT_READY_TO_USE) && |
7275 | (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) { | ||
6477 | ipr_unit_check_no_data(ioa_cfg); | 7276 | ipr_unit_check_no_data(ioa_cfg); |
6478 | return; | 7277 | return; |
6479 | } | 7278 | } |
6480 | 7279 | ||
6481 | /* Find length of the first sdt entry (UC buffer) */ | 7280 | /* Find length of the first sdt entry (UC buffer) */ |
6482 | length = (be32_to_cpu(sdt.entry[0].end_offset) - | 7281 | if (be32_to_cpu(sdt.hdr.state) == IPR_FMT3_SDT_READY_TO_USE) |
6483 | be32_to_cpu(sdt.entry[0].bar_str_offset)) & IPR_FMT2_MBX_ADDR_MASK; | 7282 | length = be32_to_cpu(sdt.entry[0].end_token); |
7283 | else | ||
7284 | length = (be32_to_cpu(sdt.entry[0].end_token) - | ||
7285 | be32_to_cpu(sdt.entry[0].start_token)) & | ||
7286 | IPR_FMT2_MBX_ADDR_MASK; | ||
6484 | 7287 | ||
6485 | hostrcb = list_entry(ioa_cfg->hostrcb_free_q.next, | 7288 | hostrcb = list_entry(ioa_cfg->hostrcb_free_q.next, |
6486 | struct ipr_hostrcb, queue); | 7289 | struct ipr_hostrcb, queue); |
@@ -6488,13 +7291,13 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) | |||
6488 | memset(&hostrcb->hcam, 0, sizeof(hostrcb->hcam)); | 7291 | memset(&hostrcb->hcam, 0, sizeof(hostrcb->hcam)); |
6489 | 7292 | ||
6490 | rc = ipr_get_ldump_data_section(ioa_cfg, | 7293 | rc = ipr_get_ldump_data_section(ioa_cfg, |
6491 | be32_to_cpu(sdt.entry[0].bar_str_offset), | 7294 | be32_to_cpu(sdt.entry[0].start_token), |
6492 | (__be32 *)&hostrcb->hcam, | 7295 | (__be32 *)&hostrcb->hcam, |
6493 | min(length, (int)sizeof(hostrcb->hcam)) / sizeof(__be32)); | 7296 | min(length, (int)sizeof(hostrcb->hcam)) / sizeof(__be32)); |
6494 | 7297 | ||
6495 | if (!rc) { | 7298 | if (!rc) { |
6496 | ipr_handle_log_data(ioa_cfg, hostrcb); | 7299 | ipr_handle_log_data(ioa_cfg, hostrcb); |
6497 | ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); | 7300 | ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc); |
6498 | if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED && | 7301 | if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED && |
6499 | ioa_cfg->sdt_state == GET_DUMP) | 7302 | ioa_cfg->sdt_state == GET_DUMP) |
6500 | ioa_cfg->sdt_state = WAIT_FOR_DUMP; | 7303 | ioa_cfg->sdt_state = WAIT_FOR_DUMP; |
@@ -6722,7 +7525,7 @@ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd) | |||
6722 | 7525 | ||
6723 | if ((rc == PCIBIOS_SUCCESSFUL) && (cmd_reg & PCI_COMMAND_MEMORY)) { | 7526 | if ((rc == PCIBIOS_SUCCESSFUL) && (cmd_reg & PCI_COMMAND_MEMORY)) { |
6724 | ipr_mask_and_clear_interrupts(ioa_cfg, ~0); | 7527 | ipr_mask_and_clear_interrupts(ioa_cfg, ~0); |
6725 | writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg); | 7528 | writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg32); |
6726 | ipr_cmd->job_step = ipr_reset_wait_to_start_bist; | 7529 | ipr_cmd->job_step = ipr_reset_wait_to_start_bist; |
6727 | } else { | 7530 | } else { |
6728 | ipr_cmd->job_step = ioa_cfg->reset; | 7531 | ipr_cmd->job_step = ioa_cfg->reset; |
@@ -6785,7 +7588,10 @@ static int ipr_reset_ucode_download(struct ipr_cmnd *ipr_cmd) | |||
6785 | ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8; | 7588 | ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8; |
6786 | ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff; | 7589 | ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff; |
6787 | 7590 | ||
6788 | ipr_build_ucode_ioadl(ipr_cmd, sglist); | 7591 | if (ioa_cfg->sis64) |
7592 | ipr_build_ucode_ioadl64(ipr_cmd, sglist); | ||
7593 | else | ||
7594 | ipr_build_ucode_ioadl(ipr_cmd, sglist); | ||
6789 | ipr_cmd->job_step = ipr_reset_ucode_download_done; | 7595 | ipr_cmd->job_step = ipr_reset_ucode_download_done; |
6790 | 7596 | ||
6791 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, | 7597 | ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, |
@@ -7154,8 +7960,8 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
7154 | ipr_free_cmd_blks(ioa_cfg); | 7960 | ipr_free_cmd_blks(ioa_cfg); |
7155 | pci_free_consistent(ioa_cfg->pdev, sizeof(u32) * IPR_NUM_CMD_BLKS, | 7961 | pci_free_consistent(ioa_cfg->pdev, sizeof(u32) * IPR_NUM_CMD_BLKS, |
7156 | ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma); | 7962 | ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma); |
7157 | pci_free_consistent(ioa_cfg->pdev, sizeof(struct ipr_config_table), | 7963 | pci_free_consistent(ioa_cfg->pdev, ioa_cfg->cfg_table_size, |
7158 | ioa_cfg->cfg_table, | 7964 | ioa_cfg->u.cfg_table, |
7159 | ioa_cfg->cfg_table_dma); | 7965 | ioa_cfg->cfg_table_dma); |
7160 | 7966 | ||
7161 | for (i = 0; i < IPR_NUM_HCAMS; i++) { | 7967 | for (i = 0; i < IPR_NUM_HCAMS; i++) { |
@@ -7209,7 +8015,7 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) | |||
7209 | int i; | 8015 | int i; |
7210 | 8016 | ||
7211 | ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev, | 8017 | ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev, |
7212 | sizeof(struct ipr_cmnd), 8, 0); | 8018 | sizeof(struct ipr_cmnd), 16, 0); |
7213 | 8019 | ||
7214 | if (!ioa_cfg->ipr_cmd_pool) | 8020 | if (!ioa_cfg->ipr_cmd_pool) |
7215 | return -ENOMEM; | 8021 | return -ENOMEM; |
@@ -7227,13 +8033,25 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) | |||
7227 | ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr; | 8033 | ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr; |
7228 | 8034 | ||
7229 | ioarcb = &ipr_cmd->ioarcb; | 8035 | ioarcb = &ipr_cmd->ioarcb; |
7230 | ioarcb->ioarcb_host_pci_addr = cpu_to_be32(dma_addr); | 8036 | ipr_cmd->dma_addr = dma_addr; |
8037 | if (ioa_cfg->sis64) | ||
8038 | ioarcb->a.ioarcb_host_pci_addr64 = cpu_to_be64(dma_addr); | ||
8039 | else | ||
8040 | ioarcb->a.ioarcb_host_pci_addr = cpu_to_be32(dma_addr); | ||
8041 | |||
7231 | ioarcb->host_response_handle = cpu_to_be32(i << 2); | 8042 | ioarcb->host_response_handle = cpu_to_be32(i << 2); |
7232 | ioarcb->write_ioadl_addr = | 8043 | if (ioa_cfg->sis64) { |
7233 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); | 8044 | ioarcb->u.sis64_addr_data.data_ioadl_addr = |
7234 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | 8045 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); |
7235 | ioarcb->ioasa_host_pci_addr = | 8046 | ioarcb->u.sis64_addr_data.ioasa_host_pci_addr = |
7236 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa)); | 8047 | cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, ioasa)); |
8048 | } else { | ||
8049 | ioarcb->write_ioadl_addr = | ||
8050 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); | ||
8051 | ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; | ||
8052 | ioarcb->ioasa_host_pci_addr = | ||
8053 | cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa)); | ||
8054 | } | ||
7237 | ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa)); | 8055 | ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa)); |
7238 | ipr_cmd->cmd_index = i; | 8056 | ipr_cmd->cmd_index = i; |
7239 | ipr_cmd->ioa_cfg = ioa_cfg; | 8057 | ipr_cmd->ioa_cfg = ioa_cfg; |
@@ -7260,13 +8078,24 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
7260 | 8078 | ||
7261 | ENTER; | 8079 | ENTER; |
7262 | ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) * | 8080 | ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) * |
7263 | IPR_MAX_PHYSICAL_DEVS, GFP_KERNEL); | 8081 | ioa_cfg->max_devs_supported, GFP_KERNEL); |
7264 | 8082 | ||
7265 | if (!ioa_cfg->res_entries) | 8083 | if (!ioa_cfg->res_entries) |
7266 | goto out; | 8084 | goto out; |
7267 | 8085 | ||
7268 | for (i = 0; i < IPR_MAX_PHYSICAL_DEVS; i++) | 8086 | if (ioa_cfg->sis64) { |
8087 | ioa_cfg->target_ids = kzalloc(sizeof(unsigned long) * | ||
8088 | BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); | ||
8089 | ioa_cfg->array_ids = kzalloc(sizeof(unsigned long) * | ||
8090 | BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); | ||
8091 | ioa_cfg->vset_ids = kzalloc(sizeof(unsigned long) * | ||
8092 | BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); | ||
8093 | } | ||
8094 | |||
8095 | for (i = 0; i < ioa_cfg->max_devs_supported; i++) { | ||
7269 | list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q); | 8096 | list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q); |
8097 | ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg; | ||
8098 | } | ||
7270 | 8099 | ||
7271 | ioa_cfg->vpd_cbs = pci_alloc_consistent(ioa_cfg->pdev, | 8100 | ioa_cfg->vpd_cbs = pci_alloc_consistent(ioa_cfg->pdev, |
7272 | sizeof(struct ipr_misc_cbs), | 8101 | sizeof(struct ipr_misc_cbs), |
@@ -7285,11 +8114,11 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
7285 | if (!ioa_cfg->host_rrq) | 8114 | if (!ioa_cfg->host_rrq) |
7286 | goto out_ipr_free_cmd_blocks; | 8115 | goto out_ipr_free_cmd_blocks; |
7287 | 8116 | ||
7288 | ioa_cfg->cfg_table = pci_alloc_consistent(ioa_cfg->pdev, | 8117 | ioa_cfg->u.cfg_table = pci_alloc_consistent(ioa_cfg->pdev, |
7289 | sizeof(struct ipr_config_table), | 8118 | ioa_cfg->cfg_table_size, |
7290 | &ioa_cfg->cfg_table_dma); | 8119 | &ioa_cfg->cfg_table_dma); |
7291 | 8120 | ||
7292 | if (!ioa_cfg->cfg_table) | 8121 | if (!ioa_cfg->u.cfg_table) |
7293 | goto out_free_host_rrq; | 8122 | goto out_free_host_rrq; |
7294 | 8123 | ||
7295 | for (i = 0; i < IPR_NUM_HCAMS; i++) { | 8124 | for (i = 0; i < IPR_NUM_HCAMS; i++) { |
@@ -7323,8 +8152,9 @@ out_free_hostrcb_dma: | |||
7323 | ioa_cfg->hostrcb[i], | 8152 | ioa_cfg->hostrcb[i], |
7324 | ioa_cfg->hostrcb_dma[i]); | 8153 | ioa_cfg->hostrcb_dma[i]); |
7325 | } | 8154 | } |
7326 | pci_free_consistent(pdev, sizeof(struct ipr_config_table), | 8155 | pci_free_consistent(pdev, ioa_cfg->cfg_table_size, |
7327 | ioa_cfg->cfg_table, ioa_cfg->cfg_table_dma); | 8156 | ioa_cfg->u.cfg_table, |
8157 | ioa_cfg->cfg_table_dma); | ||
7328 | out_free_host_rrq: | 8158 | out_free_host_rrq: |
7329 | pci_free_consistent(pdev, sizeof(u32) * IPR_NUM_CMD_BLKS, | 8159 | pci_free_consistent(pdev, sizeof(u32) * IPR_NUM_CMD_BLKS, |
7330 | ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma); | 8160 | ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma); |
@@ -7399,15 +8229,21 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, | |||
7399 | init_waitqueue_head(&ioa_cfg->reset_wait_q); | 8229 | init_waitqueue_head(&ioa_cfg->reset_wait_q); |
7400 | init_waitqueue_head(&ioa_cfg->msi_wait_q); | 8230 | init_waitqueue_head(&ioa_cfg->msi_wait_q); |
7401 | ioa_cfg->sdt_state = INACTIVE; | 8231 | ioa_cfg->sdt_state = INACTIVE; |
7402 | if (ipr_enable_cache) | ||
7403 | ioa_cfg->cache_state = CACHE_ENABLED; | ||
7404 | else | ||
7405 | ioa_cfg->cache_state = CACHE_DISABLED; | ||
7406 | 8232 | ||
7407 | ipr_initialize_bus_attr(ioa_cfg); | 8233 | ipr_initialize_bus_attr(ioa_cfg); |
8234 | ioa_cfg->max_devs_supported = ipr_max_devs; | ||
7408 | 8235 | ||
7409 | host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS; | 8236 | if (ioa_cfg->sis64) { |
7410 | host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET; | 8237 | host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS; |
8238 | host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET; | ||
8239 | if (ipr_max_devs > IPR_MAX_SIS64_DEVS) | ||
8240 | ioa_cfg->max_devs_supported = IPR_MAX_SIS64_DEVS; | ||
8241 | } else { | ||
8242 | host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS; | ||
8243 | host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET; | ||
8244 | if (ipr_max_devs > IPR_MAX_PHYSICAL_DEVS) | ||
8245 | ioa_cfg->max_devs_supported = IPR_MAX_PHYSICAL_DEVS; | ||
8246 | } | ||
7411 | host->max_channel = IPR_MAX_BUS_TO_SCAN; | 8247 | host->max_channel = IPR_MAX_BUS_TO_SCAN; |
7412 | host->unique_id = host->host_no; | 8248 | host->unique_id = host->host_no; |
7413 | host->max_cmd_len = IPR_MAX_CDB_LEN; | 8249 | host->max_cmd_len = IPR_MAX_CDB_LEN; |
@@ -7419,13 +8255,26 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, | |||
7419 | 8255 | ||
7420 | t->set_interrupt_mask_reg = base + p->set_interrupt_mask_reg; | 8256 | t->set_interrupt_mask_reg = base + p->set_interrupt_mask_reg; |
7421 | t->clr_interrupt_mask_reg = base + p->clr_interrupt_mask_reg; | 8257 | t->clr_interrupt_mask_reg = base + p->clr_interrupt_mask_reg; |
8258 | t->clr_interrupt_mask_reg32 = base + p->clr_interrupt_mask_reg32; | ||
7422 | t->sense_interrupt_mask_reg = base + p->sense_interrupt_mask_reg; | 8259 | t->sense_interrupt_mask_reg = base + p->sense_interrupt_mask_reg; |
8260 | t->sense_interrupt_mask_reg32 = base + p->sense_interrupt_mask_reg32; | ||
7423 | t->clr_interrupt_reg = base + p->clr_interrupt_reg; | 8261 | t->clr_interrupt_reg = base + p->clr_interrupt_reg; |
8262 | t->clr_interrupt_reg32 = base + p->clr_interrupt_reg32; | ||
7424 | t->sense_interrupt_reg = base + p->sense_interrupt_reg; | 8263 | t->sense_interrupt_reg = base + p->sense_interrupt_reg; |
8264 | t->sense_interrupt_reg32 = base + p->sense_interrupt_reg32; | ||
7425 | t->ioarrin_reg = base + p->ioarrin_reg; | 8265 | t->ioarrin_reg = base + p->ioarrin_reg; |
7426 | t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg; | 8266 | t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg; |
8267 | t->sense_uproc_interrupt_reg32 = base + p->sense_uproc_interrupt_reg32; | ||
7427 | t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg; | 8268 | t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg; |
8269 | t->set_uproc_interrupt_reg32 = base + p->set_uproc_interrupt_reg32; | ||
7428 | t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg; | 8270 | t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg; |
8271 | t->clr_uproc_interrupt_reg32 = base + p->clr_uproc_interrupt_reg32; | ||
8272 | |||
8273 | if (ioa_cfg->sis64) { | ||
8274 | t->init_feedback_reg = base + p->init_feedback_reg; | ||
8275 | t->dump_addr_reg = base + p->dump_addr_reg; | ||
8276 | t->dump_data_reg = base + p->dump_data_reg; | ||
8277 | } | ||
7429 | } | 8278 | } |
7430 | 8279 | ||
7431 | /** | 8280 | /** |
@@ -7497,7 +8346,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, | |||
7497 | init_waitqueue_head(&ioa_cfg->msi_wait_q); | 8346 | init_waitqueue_head(&ioa_cfg->msi_wait_q); |
7498 | ioa_cfg->msi_received = 0; | 8347 | ioa_cfg->msi_received = 0; |
7499 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); | 8348 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); |
7500 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg); | 8349 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg32); |
7501 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 8350 | int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); |
7502 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 8351 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
7503 | 8352 | ||
@@ -7508,7 +8357,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, | |||
7508 | } else if (ipr_debug) | 8357 | } else if (ipr_debug) |
7509 | dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq); | 8358 | dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq); |
7510 | 8359 | ||
7511 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg); | 8360 | writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg32); |
7512 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); | 8361 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); |
7513 | wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ); | 8362 | wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ); |
7514 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); | 8363 | ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); |
@@ -7578,6 +8427,8 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, | |||
7578 | goto out_scsi_host_put; | 8427 | goto out_scsi_host_put; |
7579 | } | 8428 | } |
7580 | 8429 | ||
8430 | /* set SIS 32 or SIS 64 */ | ||
8431 | ioa_cfg->sis64 = ioa_cfg->ipr_chip->sis_type == IPR_SIS64 ? 1 : 0; | ||
7581 | ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg; | 8432 | ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg; |
7582 | 8433 | ||
7583 | if (ipr_transop_timeout) | 8434 | if (ipr_transop_timeout) |
@@ -7615,7 +8466,16 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, | |||
7615 | 8466 | ||
7616 | pci_set_master(pdev); | 8467 | pci_set_master(pdev); |
7617 | 8468 | ||
7618 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 8469 | if (ioa_cfg->sis64) { |
8470 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); | ||
8471 | if (rc < 0) { | ||
8472 | dev_dbg(&pdev->dev, "Failed to set 64 bit PCI DMA mask\n"); | ||
8473 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
8474 | } | ||
8475 | |||
8476 | } else | ||
8477 | rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
8478 | |||
7619 | if (rc < 0) { | 8479 | if (rc < 0) { |
7620 | dev_err(&pdev->dev, "Failed to set PCI DMA mask\n"); | 8480 | dev_err(&pdev->dev, "Failed to set PCI DMA mask\n"); |
7621 | goto cleanup_nomem; | 8481 | goto cleanup_nomem; |
@@ -7657,6 +8517,15 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, | |||
7657 | if ((rc = ipr_set_pcix_cmd_reg(ioa_cfg))) | 8517 | if ((rc = ipr_set_pcix_cmd_reg(ioa_cfg))) |
7658 | goto cleanup_nomem; | 8518 | goto cleanup_nomem; |
7659 | 8519 | ||
8520 | if (ioa_cfg->sis64) | ||
8521 | ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr64) | ||
8522 | + ((sizeof(struct ipr_config_table_entry64) | ||
8523 | * ioa_cfg->max_devs_supported))); | ||
8524 | else | ||
8525 | ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr) | ||
8526 | + ((sizeof(struct ipr_config_table_entry) | ||
8527 | * ioa_cfg->max_devs_supported))); | ||
8528 | |||
7660 | rc = ipr_alloc_mem(ioa_cfg); | 8529 | rc = ipr_alloc_mem(ioa_cfg); |
7661 | if (rc < 0) { | 8530 | if (rc < 0) { |
7662 | dev_err(&pdev->dev, | 8531 | dev_err(&pdev->dev, |
@@ -7668,9 +8537,9 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, | |||
7668 | * If HRRQ updated interrupt is not masked, or reset alert is set, | 8537 | * If HRRQ updated interrupt is not masked, or reset alert is set, |
7669 | * the card is in an unknown state and needs a hard reset | 8538 | * the card is in an unknown state and needs a hard reset |
7670 | */ | 8539 | */ |
7671 | mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg); | 8540 | mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg32); |
7672 | interrupts = readl(ioa_cfg->regs.sense_interrupt_reg); | 8541 | interrupts = readl(ioa_cfg->regs.sense_interrupt_reg32); |
7673 | uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg); | 8542 | uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg32); |
7674 | if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT)) | 8543 | if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT)) |
7675 | ioa_cfg->needs_hard_reset = 1; | 8544 | ioa_cfg->needs_hard_reset = 1; |
7676 | if (interrupts & IPR_PCII_ERROR_INTERRUPTS) | 8545 | if (interrupts & IPR_PCII_ERROR_INTERRUPTS) |
@@ -7958,9 +8827,6 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { | |||
7958 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0, | 8827 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0, |
7959 | IPR_USE_LONG_TRANSOP_TIMEOUT }, | 8828 | IPR_USE_LONG_TRANSOP_TIMEOUT }, |
7960 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, | 8829 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, |
7961 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0, | ||
7962 | IPR_USE_LONG_TRANSOP_TIMEOUT }, | ||
7963 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, | ||
7964 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 }, | 8830 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 }, |
7965 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, | 8831 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, |
7966 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, | 8832 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, |
@@ -7975,9 +8841,22 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { | |||
7975 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, | 8841 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, |
7976 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0, | 8842 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0, |
7977 | IPR_USE_LONG_TRANSOP_TIMEOUT }, | 8843 | IPR_USE_LONG_TRANSOP_TIMEOUT }, |
7978 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SCAMP_E, | 8844 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, |
7979 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, | 8845 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B5, 0, 0, 0 }, |
7980 | IPR_USE_LONG_TRANSOP_TIMEOUT }, | 8846 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, |
8847 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, 0 }, | ||
8848 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, | ||
8849 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B2, 0, 0, 0 }, | ||
8850 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, | ||
8851 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B4, 0, 0, 0 }, | ||
8852 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, | ||
8853 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B1, 0, 0, 0 }, | ||
8854 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, | ||
8855 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C6, 0, 0, 0 }, | ||
8856 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, | ||
8857 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0, 0 }, | ||
8858 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, | ||
8859 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57CE, 0, 0, 0 }, | ||
7981 | { } | 8860 | { } |
7982 | }; | 8861 | }; |
7983 | MODULE_DEVICE_TABLE(pci, ipr_pci_table); | 8862 | MODULE_DEVICE_TABLE(pci, ipr_pci_table); |
@@ -7997,6 +8876,61 @@ static struct pci_driver ipr_driver = { | |||
7997 | }; | 8876 | }; |
7998 | 8877 | ||
7999 | /** | 8878 | /** |
8879 | * ipr_halt_done - Shutdown prepare completion | ||
8880 | * | ||
8881 | * Return value: | ||
8882 | * none | ||
8883 | **/ | ||
8884 | static void ipr_halt_done(struct ipr_cmnd *ipr_cmd) | ||
8885 | { | ||
8886 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | ||
8887 | |||
8888 | list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); | ||
8889 | } | ||
8890 | |||
8891 | /** | ||
8892 | * ipr_halt - Issue shutdown prepare to all adapters | ||
8893 | * | ||
8894 | * Return value: | ||
8895 | * NOTIFY_OK on success / NOTIFY_DONE on failure | ||
8896 | **/ | ||
8897 | static int ipr_halt(struct notifier_block *nb, ulong event, void *buf) | ||
8898 | { | ||
8899 | struct ipr_cmnd *ipr_cmd; | ||
8900 | struct ipr_ioa_cfg *ioa_cfg; | ||
8901 | unsigned long flags = 0; | ||
8902 | |||
8903 | if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) | ||
8904 | return NOTIFY_DONE; | ||
8905 | |||
8906 | spin_lock(&ipr_driver_lock); | ||
8907 | |||
8908 | list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) { | ||
8909 | spin_lock_irqsave(ioa_cfg->host->host_lock, flags); | ||
8910 | if (!ioa_cfg->allow_cmds) { | ||
8911 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); | ||
8912 | continue; | ||
8913 | } | ||
8914 | |||
8915 | ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); | ||
8916 | ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); | ||
8917 | ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | ||
8918 | ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN; | ||
8919 | ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL; | ||
8920 | |||
8921 | ipr_do_req(ipr_cmd, ipr_halt_done, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); | ||
8922 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); | ||
8923 | } | ||
8924 | spin_unlock(&ipr_driver_lock); | ||
8925 | |||
8926 | return NOTIFY_OK; | ||
8927 | } | ||
8928 | |||
8929 | static struct notifier_block ipr_notifier = { | ||
8930 | ipr_halt, NULL, 0 | ||
8931 | }; | ||
8932 | |||
8933 | /** | ||
8000 | * ipr_init - Module entry point | 8934 | * ipr_init - Module entry point |
8001 | * | 8935 | * |
8002 | * Return value: | 8936 | * Return value: |
@@ -8007,6 +8941,7 @@ static int __init ipr_init(void) | |||
8007 | ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n", | 8941 | ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n", |
8008 | IPR_DRIVER_VERSION, IPR_DRIVER_DATE); | 8942 | IPR_DRIVER_VERSION, IPR_DRIVER_DATE); |
8009 | 8943 | ||
8944 | register_reboot_notifier(&ipr_notifier); | ||
8010 | return pci_register_driver(&ipr_driver); | 8945 | return pci_register_driver(&ipr_driver); |
8011 | } | 8946 | } |
8012 | 8947 | ||
@@ -8020,6 +8955,7 @@ static int __init ipr_init(void) | |||
8020 | **/ | 8955 | **/ |
8021 | static void __exit ipr_exit(void) | 8956 | static void __exit ipr_exit(void) |
8022 | { | 8957 | { |
8958 | unregister_reboot_notifier(&ipr_notifier); | ||
8023 | pci_unregister_driver(&ipr_driver); | 8959 | pci_unregister_driver(&ipr_driver); |
8024 | } | 8960 | } |
8025 | 8961 | ||
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 19bbcf39f0c9..4c267b5e0b96 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
@@ -37,8 +37,8 @@ | |||
37 | /* | 37 | /* |
38 | * Literals | 38 | * Literals |
39 | */ | 39 | */ |
40 | #define IPR_DRIVER_VERSION "2.4.3" | 40 | #define IPR_DRIVER_VERSION "2.5.0" |
41 | #define IPR_DRIVER_DATE "(June 10, 2009)" | 41 | #define IPR_DRIVER_DATE "(February 11, 2010)" |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding | 44 | * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding |
@@ -55,7 +55,9 @@ | |||
55 | #define IPR_NUM_BASE_CMD_BLKS 100 | 55 | #define IPR_NUM_BASE_CMD_BLKS 100 |
56 | 56 | ||
57 | #define PCI_DEVICE_ID_IBM_OBSIDIAN_E 0x0339 | 57 | #define PCI_DEVICE_ID_IBM_OBSIDIAN_E 0x0339 |
58 | #define PCI_DEVICE_ID_IBM_SCAMP_E 0x034A | 58 | |
59 | #define PCI_DEVICE_ID_IBM_CROC_FPGA_E2 0x033D | ||
60 | #define PCI_DEVICE_ID_IBM_CROC_ASIC_E2 0x034A | ||
59 | 61 | ||
60 | #define IPR_SUBS_DEV_ID_2780 0x0264 | 62 | #define IPR_SUBS_DEV_ID_2780 0x0264 |
61 | #define IPR_SUBS_DEV_ID_5702 0x0266 | 63 | #define IPR_SUBS_DEV_ID_5702 0x0266 |
@@ -70,15 +72,24 @@ | |||
70 | #define IPR_SUBS_DEV_ID_572A 0x02C1 | 72 | #define IPR_SUBS_DEV_ID_572A 0x02C1 |
71 | #define IPR_SUBS_DEV_ID_572B 0x02C2 | 73 | #define IPR_SUBS_DEV_ID_572B 0x02C2 |
72 | #define IPR_SUBS_DEV_ID_572F 0x02C3 | 74 | #define IPR_SUBS_DEV_ID_572F 0x02C3 |
73 | #define IPR_SUBS_DEV_ID_574D 0x030B | ||
74 | #define IPR_SUBS_DEV_ID_574E 0x030A | 75 | #define IPR_SUBS_DEV_ID_574E 0x030A |
75 | #define IPR_SUBS_DEV_ID_575B 0x030D | 76 | #define IPR_SUBS_DEV_ID_575B 0x030D |
76 | #define IPR_SUBS_DEV_ID_575C 0x0338 | 77 | #define IPR_SUBS_DEV_ID_575C 0x0338 |
77 | #define IPR_SUBS_DEV_ID_575D 0x033E | ||
78 | #define IPR_SUBS_DEV_ID_57B3 0x033A | 78 | #define IPR_SUBS_DEV_ID_57B3 0x033A |
79 | #define IPR_SUBS_DEV_ID_57B7 0x0360 | 79 | #define IPR_SUBS_DEV_ID_57B7 0x0360 |
80 | #define IPR_SUBS_DEV_ID_57B8 0x02C2 | 80 | #define IPR_SUBS_DEV_ID_57B8 0x02C2 |
81 | 81 | ||
82 | #define IPR_SUBS_DEV_ID_57B4 0x033B | ||
83 | #define IPR_SUBS_DEV_ID_57B2 0x035F | ||
84 | #define IPR_SUBS_DEV_ID_57C6 0x0357 | ||
85 | |||
86 | #define IPR_SUBS_DEV_ID_57B5 0x033C | ||
87 | #define IPR_SUBS_DEV_ID_57CE 0x035E | ||
88 | #define IPR_SUBS_DEV_ID_57B1 0x0355 | ||
89 | |||
90 | #define IPR_SUBS_DEV_ID_574D 0x0356 | ||
91 | #define IPR_SUBS_DEV_ID_575D 0x035D | ||
92 | |||
82 | #define IPR_NAME "ipr" | 93 | #define IPR_NAME "ipr" |
83 | 94 | ||
84 | /* | 95 | /* |
@@ -118,6 +129,10 @@ | |||
118 | #define IPR_NUM_LOG_HCAMS 2 | 129 | #define IPR_NUM_LOG_HCAMS 2 |
119 | #define IPR_NUM_CFG_CHG_HCAMS 2 | 130 | #define IPR_NUM_CFG_CHG_HCAMS 2 |
120 | #define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS) | 131 | #define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS) |
132 | |||
133 | #define IPR_MAX_SIS64_TARGETS_PER_BUS 1024 | ||
134 | #define IPR_MAX_SIS64_LUNS_PER_TARGET 0xffffffff | ||
135 | |||
121 | #define IPR_MAX_NUM_TARGETS_PER_BUS 256 | 136 | #define IPR_MAX_NUM_TARGETS_PER_BUS 256 |
122 | #define IPR_MAX_NUM_LUNS_PER_TARGET 256 | 137 | #define IPR_MAX_NUM_LUNS_PER_TARGET 256 |
123 | #define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8 | 138 | #define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8 |
@@ -132,13 +147,15 @@ | |||
132 | 147 | ||
133 | /* We need resources for HCAMS, IOA reset, IOA bringdown, and ERP */ | 148 | /* We need resources for HCAMS, IOA reset, IOA bringdown, and ERP */ |
134 | #define IPR_NUM_INTERNAL_CMD_BLKS (IPR_NUM_HCAMS + \ | 149 | #define IPR_NUM_INTERNAL_CMD_BLKS (IPR_NUM_HCAMS + \ |
135 | ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 3) | 150 | ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 4) |
136 | 151 | ||
137 | #define IPR_MAX_COMMANDS IPR_NUM_BASE_CMD_BLKS | 152 | #define IPR_MAX_COMMANDS IPR_NUM_BASE_CMD_BLKS |
138 | #define IPR_NUM_CMD_BLKS (IPR_NUM_BASE_CMD_BLKS + \ | 153 | #define IPR_NUM_CMD_BLKS (IPR_NUM_BASE_CMD_BLKS + \ |
139 | IPR_NUM_INTERNAL_CMD_BLKS) | 154 | IPR_NUM_INTERNAL_CMD_BLKS) |
140 | 155 | ||
141 | #define IPR_MAX_PHYSICAL_DEVS 192 | 156 | #define IPR_MAX_PHYSICAL_DEVS 192 |
157 | #define IPR_DEFAULT_SIS64_DEVS 1024 | ||
158 | #define IPR_MAX_SIS64_DEVS 4096 | ||
142 | 159 | ||
143 | #define IPR_MAX_SGLIST 64 | 160 | #define IPR_MAX_SGLIST 64 |
144 | #define IPR_IOA_MAX_SECTORS 32767 | 161 | #define IPR_IOA_MAX_SECTORS 32767 |
@@ -173,6 +190,7 @@ | |||
173 | #define IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE 0x01 | 190 | #define IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE 0x01 |
174 | #define IPR_HCAM_CDB_OP_CODE_LOG_DATA 0x02 | 191 | #define IPR_HCAM_CDB_OP_CODE_LOG_DATA 0x02 |
175 | #define IPR_SET_SUPPORTED_DEVICES 0xFB | 192 | #define IPR_SET_SUPPORTED_DEVICES 0xFB |
193 | #define IPR_SET_ALL_SUPPORTED_DEVICES 0x80 | ||
176 | #define IPR_IOA_SHUTDOWN 0xF7 | 194 | #define IPR_IOA_SHUTDOWN 0xF7 |
177 | #define IPR_WR_BUF_DOWNLOAD_AND_SAVE 0x05 | 195 | #define IPR_WR_BUF_DOWNLOAD_AND_SAVE 0x05 |
178 | 196 | ||
@@ -221,9 +239,17 @@ | |||
221 | #define IPR_SDT_FMT2_BAR5_SEL 0x5 | 239 | #define IPR_SDT_FMT2_BAR5_SEL 0x5 |
222 | #define IPR_SDT_FMT2_EXP_ROM_SEL 0x8 | 240 | #define IPR_SDT_FMT2_EXP_ROM_SEL 0x8 |
223 | #define IPR_FMT2_SDT_READY_TO_USE 0xC4D4E3F2 | 241 | #define IPR_FMT2_SDT_READY_TO_USE 0xC4D4E3F2 |
242 | #define IPR_FMT3_SDT_READY_TO_USE 0xC4D4E3F3 | ||
224 | #define IPR_DOORBELL 0x82800000 | 243 | #define IPR_DOORBELL 0x82800000 |
225 | #define IPR_RUNTIME_RESET 0x40000000 | 244 | #define IPR_RUNTIME_RESET 0x40000000 |
226 | 245 | ||
246 | #define IPR_IPL_INIT_MIN_STAGE_TIME 5 | ||
247 | #define IPR_IPL_INIT_STAGE_UNKNOWN 0x0 | ||
248 | #define IPR_IPL_INIT_STAGE_TRANSOP 0xB0000000 | ||
249 | #define IPR_IPL_INIT_STAGE_MASK 0xff000000 | ||
250 | #define IPR_IPL_INIT_STAGE_TIME_MASK 0x0000ffff | ||
251 | #define IPR_PCII_IPL_STAGE_CHANGE (0x80000000 >> 0) | ||
252 | |||
227 | #define IPR_PCII_IOA_TRANS_TO_OPER (0x80000000 >> 0) | 253 | #define IPR_PCII_IOA_TRANS_TO_OPER (0x80000000 >> 0) |
228 | #define IPR_PCII_IOARCB_XFER_FAILED (0x80000000 >> 3) | 254 | #define IPR_PCII_IOARCB_XFER_FAILED (0x80000000 >> 3) |
229 | #define IPR_PCII_IOA_UNIT_CHECKED (0x80000000 >> 4) | 255 | #define IPR_PCII_IOA_UNIT_CHECKED (0x80000000 >> 4) |
@@ -318,27 +344,27 @@ struct ipr_std_inq_data { | |||
318 | u8 serial_num[IPR_SERIAL_NUM_LEN]; | 344 | u8 serial_num[IPR_SERIAL_NUM_LEN]; |
319 | }__attribute__ ((packed)); | 345 | }__attribute__ ((packed)); |
320 | 346 | ||
347 | #define IPR_RES_TYPE_AF_DASD 0x00 | ||
348 | #define IPR_RES_TYPE_GENERIC_SCSI 0x01 | ||
349 | #define IPR_RES_TYPE_VOLUME_SET 0x02 | ||
350 | #define IPR_RES_TYPE_REMOTE_AF_DASD 0x03 | ||
351 | #define IPR_RES_TYPE_GENERIC_ATA 0x04 | ||
352 | #define IPR_RES_TYPE_ARRAY 0x05 | ||
353 | #define IPR_RES_TYPE_IOAFP 0xff | ||
354 | |||
321 | struct ipr_config_table_entry { | 355 | struct ipr_config_table_entry { |
322 | u8 proto; | 356 | u8 proto; |
323 | #define IPR_PROTO_SATA 0x02 | 357 | #define IPR_PROTO_SATA 0x02 |
324 | #define IPR_PROTO_SATA_ATAPI 0x03 | 358 | #define IPR_PROTO_SATA_ATAPI 0x03 |
325 | #define IPR_PROTO_SAS_STP 0x06 | 359 | #define IPR_PROTO_SAS_STP 0x06 |
326 | #define IPR_PROTO_SAS_STP_ATAPI 0x07 | 360 | #define IPR_PROTO_SAS_STP_ATAPI 0x07 |
327 | u8 array_id; | 361 | u8 array_id; |
328 | u8 flags; | 362 | u8 flags; |
329 | #define IPR_IS_IOA_RESOURCE 0x80 | 363 | #define IPR_IS_IOA_RESOURCE 0x80 |
330 | #define IPR_IS_ARRAY_MEMBER 0x20 | ||
331 | #define IPR_IS_HOT_SPARE 0x10 | ||
332 | |||
333 | u8 rsvd_subtype; | 364 | u8 rsvd_subtype; |
334 | #define IPR_RES_SUBTYPE(res) (((res)->cfgte.rsvd_subtype) & 0x0f) | 365 | |
335 | #define IPR_SUBTYPE_AF_DASD 0 | 366 | #define IPR_QUEUEING_MODEL(res) ((((res)->flags) & 0x70) >> 4) |
336 | #define IPR_SUBTYPE_GENERIC_SCSI 1 | 367 | #define IPR_QUEUE_FROZEN_MODEL 0 |
337 | #define IPR_SUBTYPE_VOLUME_SET 2 | ||
338 | #define IPR_SUBTYPE_GENERIC_ATA 4 | ||
339 | |||
340 | #define IPR_QUEUEING_MODEL(res) ((((res)->cfgte.flags) & 0x70) >> 4) | ||
341 | #define IPR_QUEUE_FROZEN_MODEL 0 | ||
342 | #define IPR_QUEUE_NACA_MODEL 1 | 368 | #define IPR_QUEUE_NACA_MODEL 1 |
343 | 369 | ||
344 | struct ipr_res_addr res_addr; | 370 | struct ipr_res_addr res_addr; |
@@ -347,6 +373,28 @@ struct ipr_config_table_entry { | |||
347 | struct ipr_std_inq_data std_inq_data; | 373 | struct ipr_std_inq_data std_inq_data; |
348 | }__attribute__ ((packed, aligned (4))); | 374 | }__attribute__ ((packed, aligned (4))); |
349 | 375 | ||
376 | struct ipr_config_table_entry64 { | ||
377 | u8 res_type; | ||
378 | u8 proto; | ||
379 | u8 vset_num; | ||
380 | u8 array_id; | ||
381 | __be16 flags; | ||
382 | __be16 res_flags; | ||
383 | #define IPR_QUEUEING_MODEL64(res) ((((res)->res_flags) & 0x7000) >> 12) | ||
384 | __be32 res_handle; | ||
385 | u8 dev_id_type; | ||
386 | u8 reserved[3]; | ||
387 | __be64 dev_id; | ||
388 | __be64 lun; | ||
389 | __be64 lun_wwn[2]; | ||
390 | #define IPR_MAX_RES_PATH_LENGTH 24 | ||
391 | __be64 res_path; | ||
392 | struct ipr_std_inq_data std_inq_data; | ||
393 | u8 reserved2[4]; | ||
394 | __be64 reserved3[2]; // description text | ||
395 | u8 reserved4[8]; | ||
396 | }__attribute__ ((packed, aligned (8))); | ||
397 | |||
350 | struct ipr_config_table_hdr { | 398 | struct ipr_config_table_hdr { |
351 | u8 num_entries; | 399 | u8 num_entries; |
352 | u8 flags; | 400 | u8 flags; |
@@ -354,13 +402,35 @@ struct ipr_config_table_hdr { | |||
354 | __be16 reserved; | 402 | __be16 reserved; |
355 | }__attribute__((packed, aligned (4))); | 403 | }__attribute__((packed, aligned (4))); |
356 | 404 | ||
405 | struct ipr_config_table_hdr64 { | ||
406 | __be16 num_entries; | ||
407 | __be16 reserved; | ||
408 | u8 flags; | ||
409 | u8 reserved2[11]; | ||
410 | }__attribute__((packed, aligned (4))); | ||
411 | |||
357 | struct ipr_config_table { | 412 | struct ipr_config_table { |
358 | struct ipr_config_table_hdr hdr; | 413 | struct ipr_config_table_hdr hdr; |
359 | struct ipr_config_table_entry dev[IPR_MAX_PHYSICAL_DEVS]; | 414 | struct ipr_config_table_entry dev[0]; |
360 | }__attribute__((packed, aligned (4))); | 415 | }__attribute__((packed, aligned (4))); |
361 | 416 | ||
417 | struct ipr_config_table64 { | ||
418 | struct ipr_config_table_hdr64 hdr64; | ||
419 | struct ipr_config_table_entry64 dev[0]; | ||
420 | }__attribute__((packed, aligned (8))); | ||
421 | |||
422 | struct ipr_config_table_entry_wrapper { | ||
423 | union { | ||
424 | struct ipr_config_table_entry *cfgte; | ||
425 | struct ipr_config_table_entry64 *cfgte64; | ||
426 | } u; | ||
427 | }; | ||
428 | |||
362 | struct ipr_hostrcb_cfg_ch_not { | 429 | struct ipr_hostrcb_cfg_ch_not { |
363 | struct ipr_config_table_entry cfgte; | 430 | union { |
431 | struct ipr_config_table_entry cfgte; | ||
432 | struct ipr_config_table_entry64 cfgte64; | ||
433 | } u; | ||
364 | u8 reserved[936]; | 434 | u8 reserved[936]; |
365 | }__attribute__((packed, aligned (4))); | 435 | }__attribute__((packed, aligned (4))); |
366 | 436 | ||
@@ -381,7 +451,7 @@ struct ipr_cmd_pkt { | |||
381 | #define IPR_RQTYPE_HCAM 0x02 | 451 | #define IPR_RQTYPE_HCAM 0x02 |
382 | #define IPR_RQTYPE_ATA_PASSTHRU 0x04 | 452 | #define IPR_RQTYPE_ATA_PASSTHRU 0x04 |
383 | 453 | ||
384 | u8 luntar_luntrn; | 454 | u8 reserved2; |
385 | 455 | ||
386 | u8 flags_hi; | 456 | u8 flags_hi; |
387 | #define IPR_FLAGS_HI_WRITE_NOT_READ 0x80 | 457 | #define IPR_FLAGS_HI_WRITE_NOT_READ 0x80 |
@@ -403,7 +473,7 @@ struct ipr_cmd_pkt { | |||
403 | __be16 timeout; | 473 | __be16 timeout; |
404 | }__attribute__ ((packed, aligned(4))); | 474 | }__attribute__ ((packed, aligned(4))); |
405 | 475 | ||
406 | struct ipr_ioarcb_ata_regs { | 476 | struct ipr_ioarcb_ata_regs { /* 22 bytes */ |
407 | u8 flags; | 477 | u8 flags; |
408 | #define IPR_ATA_FLAG_PACKET_CMD 0x80 | 478 | #define IPR_ATA_FLAG_PACKET_CMD 0x80 |
409 | #define IPR_ATA_FLAG_XFER_TYPE_DMA 0x40 | 479 | #define IPR_ATA_FLAG_XFER_TYPE_DMA 0x40 |
@@ -442,28 +512,49 @@ struct ipr_ioadl_desc { | |||
442 | __be32 address; | 512 | __be32 address; |
443 | }__attribute__((packed, aligned (8))); | 513 | }__attribute__((packed, aligned (8))); |
444 | 514 | ||
515 | struct ipr_ioadl64_desc { | ||
516 | __be32 flags; | ||
517 | __be32 data_len; | ||
518 | __be64 address; | ||
519 | }__attribute__((packed, aligned (16))); | ||
520 | |||
521 | struct ipr_ata64_ioadl { | ||
522 | struct ipr_ioarcb_ata_regs regs; | ||
523 | u16 reserved[5]; | ||
524 | struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES]; | ||
525 | }__attribute__((packed, aligned (16))); | ||
526 | |||
445 | struct ipr_ioarcb_add_data { | 527 | struct ipr_ioarcb_add_data { |
446 | union { | 528 | union { |
447 | struct ipr_ioarcb_ata_regs regs; | 529 | struct ipr_ioarcb_ata_regs regs; |
448 | struct ipr_ioadl_desc ioadl[5]; | 530 | struct ipr_ioadl_desc ioadl[5]; |
449 | __be32 add_cmd_parms[10]; | 531 | __be32 add_cmd_parms[10]; |
450 | }u; | 532 | } u; |
451 | }__attribute__ ((packed, aligned(4))); | 533 | }__attribute__ ((packed, aligned (4))); |
534 | |||
535 | struct ipr_ioarcb_sis64_add_addr_ecb { | ||
536 | __be64 ioasa_host_pci_addr; | ||
537 | __be64 data_ioadl_addr; | ||
538 | __be64 reserved; | ||
539 | __be32 ext_control_buf[4]; | ||
540 | }__attribute__((packed, aligned (8))); | ||
452 | 541 | ||
453 | /* IOA Request Control Block 128 bytes */ | 542 | /* IOA Request Control Block 128 bytes */ |
454 | struct ipr_ioarcb { | 543 | struct ipr_ioarcb { |
455 | __be32 ioarcb_host_pci_addr; | 544 | union { |
456 | __be32 reserved; | 545 | __be32 ioarcb_host_pci_addr; |
546 | __be64 ioarcb_host_pci_addr64; | ||
547 | } a; | ||
457 | __be32 res_handle; | 548 | __be32 res_handle; |
458 | __be32 host_response_handle; | 549 | __be32 host_response_handle; |
459 | __be32 reserved1; | 550 | __be32 reserved1; |
460 | __be32 reserved2; | 551 | __be32 reserved2; |
461 | __be32 reserved3; | 552 | __be32 reserved3; |
462 | 553 | ||
463 | __be32 write_data_transfer_length; | 554 | __be32 data_transfer_length; |
464 | __be32 read_data_transfer_length; | 555 | __be32 read_data_transfer_length; |
465 | __be32 write_ioadl_addr; | 556 | __be32 write_ioadl_addr; |
466 | __be32 write_ioadl_len; | 557 | __be32 ioadl_len; |
467 | __be32 read_ioadl_addr; | 558 | __be32 read_ioadl_addr; |
468 | __be32 read_ioadl_len; | 559 | __be32 read_ioadl_len; |
469 | 560 | ||
@@ -473,8 +564,14 @@ struct ipr_ioarcb { | |||
473 | 564 | ||
474 | struct ipr_cmd_pkt cmd_pkt; | 565 | struct ipr_cmd_pkt cmd_pkt; |
475 | 566 | ||
476 | __be32 add_cmd_parms_len; | 567 | __be16 add_cmd_parms_offset; |
477 | struct ipr_ioarcb_add_data add_data; | 568 | __be16 add_cmd_parms_len; |
569 | |||
570 | union { | ||
571 | struct ipr_ioarcb_add_data add_data; | ||
572 | struct ipr_ioarcb_sis64_add_addr_ecb sis64_addr_data; | ||
573 | } u; | ||
574 | |||
478 | }__attribute__((packed, aligned (4))); | 575 | }__attribute__((packed, aligned (4))); |
479 | 576 | ||
480 | struct ipr_ioasa_vset { | 577 | struct ipr_ioasa_vset { |
@@ -676,12 +773,29 @@ struct ipr_hostrcb_device_data_entry_enhanced { | |||
676 | struct ipr_ext_vpd cfc_last_with_dev_vpd; | 773 | struct ipr_ext_vpd cfc_last_with_dev_vpd; |
677 | }__attribute__((packed, aligned (4))); | 774 | }__attribute__((packed, aligned (4))); |
678 | 775 | ||
776 | struct ipr_hostrcb64_device_data_entry_enhanced { | ||
777 | struct ipr_ext_vpd vpd; | ||
778 | u8 ccin[4]; | ||
779 | u8 res_path[8]; | ||
780 | struct ipr_ext_vpd new_vpd; | ||
781 | u8 new_ccin[4]; | ||
782 | struct ipr_ext_vpd ioa_last_with_dev_vpd; | ||
783 | struct ipr_ext_vpd cfc_last_with_dev_vpd; | ||
784 | }__attribute__((packed, aligned (4))); | ||
785 | |||
679 | struct ipr_hostrcb_array_data_entry { | 786 | struct ipr_hostrcb_array_data_entry { |
680 | struct ipr_vpd vpd; | 787 | struct ipr_vpd vpd; |
681 | struct ipr_res_addr expected_dev_res_addr; | 788 | struct ipr_res_addr expected_dev_res_addr; |
682 | struct ipr_res_addr dev_res_addr; | 789 | struct ipr_res_addr dev_res_addr; |
683 | }__attribute__((packed, aligned (4))); | 790 | }__attribute__((packed, aligned (4))); |
684 | 791 | ||
792 | struct ipr_hostrcb64_array_data_entry { | ||
793 | struct ipr_ext_vpd vpd; | ||
794 | u8 ccin[4]; | ||
795 | u8 expected_res_path[8]; | ||
796 | u8 res_path[8]; | ||
797 | }__attribute__((packed, aligned (4))); | ||
798 | |||
685 | struct ipr_hostrcb_array_data_entry_enhanced { | 799 | struct ipr_hostrcb_array_data_entry_enhanced { |
686 | struct ipr_ext_vpd vpd; | 800 | struct ipr_ext_vpd vpd; |
687 | u8 ccin[4]; | 801 | u8 ccin[4]; |
@@ -733,6 +847,14 @@ struct ipr_hostrcb_type_13_error { | |||
733 | struct ipr_hostrcb_device_data_entry_enhanced dev[3]; | 847 | struct ipr_hostrcb_device_data_entry_enhanced dev[3]; |
734 | }__attribute__((packed, aligned (4))); | 848 | }__attribute__((packed, aligned (4))); |
735 | 849 | ||
850 | struct ipr_hostrcb_type_23_error { | ||
851 | struct ipr_ext_vpd ioa_vpd; | ||
852 | struct ipr_ext_vpd cfc_vpd; | ||
853 | __be32 errors_detected; | ||
854 | __be32 errors_logged; | ||
855 | struct ipr_hostrcb64_device_data_entry_enhanced dev[3]; | ||
856 | }__attribute__((packed, aligned (4))); | ||
857 | |||
736 | struct ipr_hostrcb_type_04_error { | 858 | struct ipr_hostrcb_type_04_error { |
737 | struct ipr_vpd ioa_vpd; | 859 | struct ipr_vpd ioa_vpd; |
738 | struct ipr_vpd cfc_vpd; | 860 | struct ipr_vpd cfc_vpd; |
@@ -760,6 +882,22 @@ struct ipr_hostrcb_type_14_error { | |||
760 | struct ipr_hostrcb_array_data_entry_enhanced array_member[18]; | 882 | struct ipr_hostrcb_array_data_entry_enhanced array_member[18]; |
761 | }__attribute__((packed, aligned (4))); | 883 | }__attribute__((packed, aligned (4))); |
762 | 884 | ||
885 | struct ipr_hostrcb_type_24_error { | ||
886 | struct ipr_ext_vpd ioa_vpd; | ||
887 | struct ipr_ext_vpd cfc_vpd; | ||
888 | u8 reserved[2]; | ||
889 | u8 exposed_mode_adn; | ||
890 | #define IPR_INVALID_ARRAY_DEV_NUM 0xff | ||
891 | u8 array_id; | ||
892 | u8 last_res_path[8]; | ||
893 | u8 protection_level[8]; | ||
894 | struct ipr_ext_vpd array_vpd; | ||
895 | u8 description[16]; | ||
896 | u8 reserved2[3]; | ||
897 | u8 num_entries; | ||
898 | struct ipr_hostrcb64_array_data_entry array_member[32]; | ||
899 | }__attribute__((packed, aligned (4))); | ||
900 | |||
763 | struct ipr_hostrcb_type_07_error { | 901 | struct ipr_hostrcb_type_07_error { |
764 | u8 failure_reason[64]; | 902 | u8 failure_reason[64]; |
765 | struct ipr_vpd vpd; | 903 | struct ipr_vpd vpd; |
@@ -797,6 +935,22 @@ struct ipr_hostrcb_config_element { | |||
797 | __be32 wwid[2]; | 935 | __be32 wwid[2]; |
798 | }__attribute__((packed, aligned (4))); | 936 | }__attribute__((packed, aligned (4))); |
799 | 937 | ||
938 | struct ipr_hostrcb64_config_element { | ||
939 | __be16 length; | ||
940 | u8 descriptor_id; | ||
941 | #define IPR_DESCRIPTOR_MASK 0xC0 | ||
942 | #define IPR_DESCRIPTOR_SIS64 0x00 | ||
943 | |||
944 | u8 reserved; | ||
945 | u8 type_status; | ||
946 | |||
947 | u8 reserved2[2]; | ||
948 | u8 link_rate; | ||
949 | |||
950 | u8 res_path[8]; | ||
951 | __be32 wwid[2]; | ||
952 | }__attribute__((packed, aligned (8))); | ||
953 | |||
800 | struct ipr_hostrcb_fabric_desc { | 954 | struct ipr_hostrcb_fabric_desc { |
801 | __be16 length; | 955 | __be16 length; |
802 | u8 ioa_port; | 956 | u8 ioa_port; |
@@ -818,6 +972,20 @@ struct ipr_hostrcb_fabric_desc { | |||
818 | struct ipr_hostrcb_config_element elem[1]; | 972 | struct ipr_hostrcb_config_element elem[1]; |
819 | }__attribute__((packed, aligned (4))); | 973 | }__attribute__((packed, aligned (4))); |
820 | 974 | ||
975 | struct ipr_hostrcb64_fabric_desc { | ||
976 | __be16 length; | ||
977 | u8 descriptor_id; | ||
978 | |||
979 | u8 reserved; | ||
980 | u8 path_state; | ||
981 | |||
982 | u8 reserved2[2]; | ||
983 | u8 res_path[8]; | ||
984 | u8 reserved3[6]; | ||
985 | __be16 num_entries; | ||
986 | struct ipr_hostrcb64_config_element elem[1]; | ||
987 | }__attribute__((packed, aligned (8))); | ||
988 | |||
821 | #define for_each_fabric_cfg(fabric, cfg) \ | 989 | #define for_each_fabric_cfg(fabric, cfg) \ |
822 | for (cfg = (fabric)->elem; \ | 990 | for (cfg = (fabric)->elem; \ |
823 | cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \ | 991 | cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \ |
@@ -830,10 +998,17 @@ struct ipr_hostrcb_type_20_error { | |||
830 | struct ipr_hostrcb_fabric_desc desc[1]; | 998 | struct ipr_hostrcb_fabric_desc desc[1]; |
831 | }__attribute__((packed, aligned (4))); | 999 | }__attribute__((packed, aligned (4))); |
832 | 1000 | ||
1001 | struct ipr_hostrcb_type_30_error { | ||
1002 | u8 failure_reason[64]; | ||
1003 | u8 reserved[3]; | ||
1004 | u8 num_entries; | ||
1005 | struct ipr_hostrcb64_fabric_desc desc[1]; | ||
1006 | }__attribute__((packed, aligned (4))); | ||
1007 | |||
833 | struct ipr_hostrcb_error { | 1008 | struct ipr_hostrcb_error { |
834 | __be32 failing_dev_ioasc; | 1009 | __be32 fd_ioasc; |
835 | struct ipr_res_addr failing_dev_res_addr; | 1010 | struct ipr_res_addr fd_res_addr; |
836 | __be32 failing_dev_res_handle; | 1011 | __be32 fd_res_handle; |
837 | __be32 prc; | 1012 | __be32 prc; |
838 | union { | 1013 | union { |
839 | struct ipr_hostrcb_type_ff_error type_ff_error; | 1014 | struct ipr_hostrcb_type_ff_error type_ff_error; |
@@ -850,6 +1025,26 @@ struct ipr_hostrcb_error { | |||
850 | } u; | 1025 | } u; |
851 | }__attribute__((packed, aligned (4))); | 1026 | }__attribute__((packed, aligned (4))); |
852 | 1027 | ||
1028 | struct ipr_hostrcb64_error { | ||
1029 | __be32 fd_ioasc; | ||
1030 | __be32 ioa_fw_level; | ||
1031 | __be32 fd_res_handle; | ||
1032 | __be32 prc; | ||
1033 | __be64 fd_dev_id; | ||
1034 | __be64 fd_lun; | ||
1035 | u8 fd_res_path[8]; | ||
1036 | __be64 time_stamp; | ||
1037 | u8 reserved[2]; | ||
1038 | union { | ||
1039 | struct ipr_hostrcb_type_ff_error type_ff_error; | ||
1040 | struct ipr_hostrcb_type_12_error type_12_error; | ||
1041 | struct ipr_hostrcb_type_17_error type_17_error; | ||
1042 | struct ipr_hostrcb_type_23_error type_23_error; | ||
1043 | struct ipr_hostrcb_type_24_error type_24_error; | ||
1044 | struct ipr_hostrcb_type_30_error type_30_error; | ||
1045 | } u; | ||
1046 | }__attribute__((packed, aligned (8))); | ||
1047 | |||
853 | struct ipr_hostrcb_raw { | 1048 | struct ipr_hostrcb_raw { |
854 | __be32 data[sizeof(struct ipr_hostrcb_error)/sizeof(__be32)]; | 1049 | __be32 data[sizeof(struct ipr_hostrcb_error)/sizeof(__be32)]; |
855 | }__attribute__((packed, aligned (4))); | 1050 | }__attribute__((packed, aligned (4))); |
@@ -887,7 +1082,11 @@ struct ipr_hcam { | |||
887 | #define IPR_HOST_RCB_OVERLAY_ID_16 0x16 | 1082 | #define IPR_HOST_RCB_OVERLAY_ID_16 0x16 |
888 | #define IPR_HOST_RCB_OVERLAY_ID_17 0x17 | 1083 | #define IPR_HOST_RCB_OVERLAY_ID_17 0x17 |
889 | #define IPR_HOST_RCB_OVERLAY_ID_20 0x20 | 1084 | #define IPR_HOST_RCB_OVERLAY_ID_20 0x20 |
890 | #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF | 1085 | #define IPR_HOST_RCB_OVERLAY_ID_23 0x23 |
1086 | #define IPR_HOST_RCB_OVERLAY_ID_24 0x24 | ||
1087 | #define IPR_HOST_RCB_OVERLAY_ID_26 0x26 | ||
1088 | #define IPR_HOST_RCB_OVERLAY_ID_30 0x30 | ||
1089 | #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF | ||
891 | 1090 | ||
892 | u8 reserved1[3]; | 1091 | u8 reserved1[3]; |
893 | __be32 ilid; | 1092 | __be32 ilid; |
@@ -897,6 +1096,7 @@ struct ipr_hcam { | |||
897 | 1096 | ||
898 | union { | 1097 | union { |
899 | struct ipr_hostrcb_error error; | 1098 | struct ipr_hostrcb_error error; |
1099 | struct ipr_hostrcb64_error error64; | ||
900 | struct ipr_hostrcb_cfg_ch_not ccn; | 1100 | struct ipr_hostrcb_cfg_ch_not ccn; |
901 | struct ipr_hostrcb_raw raw; | 1101 | struct ipr_hostrcb_raw raw; |
902 | } u; | 1102 | } u; |
@@ -907,14 +1107,14 @@ struct ipr_hostrcb { | |||
907 | dma_addr_t hostrcb_dma; | 1107 | dma_addr_t hostrcb_dma; |
908 | struct list_head queue; | 1108 | struct list_head queue; |
909 | struct ipr_ioa_cfg *ioa_cfg; | 1109 | struct ipr_ioa_cfg *ioa_cfg; |
1110 | char rp_buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
910 | }; | 1111 | }; |
911 | 1112 | ||
912 | /* IPR smart dump table structures */ | 1113 | /* IPR smart dump table structures */ |
913 | struct ipr_sdt_entry { | 1114 | struct ipr_sdt_entry { |
914 | __be32 bar_str_offset; | 1115 | __be32 start_token; |
915 | __be32 end_offset; | 1116 | __be32 end_token; |
916 | u8 entry_byte; | 1117 | u8 reserved[4]; |
917 | u8 reserved[3]; | ||
918 | 1118 | ||
919 | u8 flags; | 1119 | u8 flags; |
920 | #define IPR_SDT_ENDIAN 0x80 | 1120 | #define IPR_SDT_ENDIAN 0x80 |
@@ -960,28 +1160,48 @@ struct ipr_sata_port { | |||
960 | }; | 1160 | }; |
961 | 1161 | ||
962 | struct ipr_resource_entry { | 1162 | struct ipr_resource_entry { |
963 | struct ipr_config_table_entry cfgte; | ||
964 | u8 needs_sync_complete:1; | 1163 | u8 needs_sync_complete:1; |
965 | u8 in_erp:1; | 1164 | u8 in_erp:1; |
966 | u8 add_to_ml:1; | 1165 | u8 add_to_ml:1; |
967 | u8 del_from_ml:1; | 1166 | u8 del_from_ml:1; |
968 | u8 resetting_device:1; | 1167 | u8 resetting_device:1; |
969 | 1168 | ||
1169 | u32 bus; /* AKA channel */ | ||
1170 | u32 target; /* AKA id */ | ||
1171 | u32 lun; | ||
1172 | #define IPR_ARRAY_VIRTUAL_BUS 0x1 | ||
1173 | #define IPR_VSET_VIRTUAL_BUS 0x2 | ||
1174 | #define IPR_IOAFP_VIRTUAL_BUS 0x3 | ||
1175 | |||
1176 | #define IPR_GET_RES_PHYS_LOC(res) \ | ||
1177 | (((res)->bus << 24) | ((res)->target << 8) | (res)->lun) | ||
1178 | |||
1179 | u8 ata_class; | ||
1180 | |||
1181 | u8 flags; | ||
1182 | __be16 res_flags; | ||
1183 | |||
1184 | __be32 type; | ||
1185 | |||
1186 | u8 qmodel; | ||
1187 | struct ipr_std_inq_data std_inq_data; | ||
1188 | |||
1189 | __be32 res_handle; | ||
1190 | __be64 dev_id; | ||
1191 | struct scsi_lun dev_lun; | ||
1192 | u8 res_path[8]; | ||
1193 | |||
1194 | struct ipr_ioa_cfg *ioa_cfg; | ||
970 | struct scsi_device *sdev; | 1195 | struct scsi_device *sdev; |
971 | struct ipr_sata_port *sata_port; | 1196 | struct ipr_sata_port *sata_port; |
972 | struct list_head queue; | 1197 | struct list_head queue; |
973 | }; | 1198 | }; /* struct ipr_resource_entry */ |
974 | 1199 | ||
975 | struct ipr_resource_hdr { | 1200 | struct ipr_resource_hdr { |
976 | u16 num_entries; | 1201 | u16 num_entries; |
977 | u16 reserved; | 1202 | u16 reserved; |
978 | }; | 1203 | }; |
979 | 1204 | ||
980 | struct ipr_resource_table { | ||
981 | struct ipr_resource_hdr hdr; | ||
982 | struct ipr_resource_entry dev[IPR_MAX_PHYSICAL_DEVS]; | ||
983 | }; | ||
984 | |||
985 | struct ipr_misc_cbs { | 1205 | struct ipr_misc_cbs { |
986 | struct ipr_ioa_vpd ioa_vpd; | 1206 | struct ipr_ioa_vpd ioa_vpd; |
987 | struct ipr_inquiry_page0 page0_data; | 1207 | struct ipr_inquiry_page0 page0_data; |
@@ -994,27 +1214,51 @@ struct ipr_misc_cbs { | |||
994 | struct ipr_interrupt_offsets { | 1214 | struct ipr_interrupt_offsets { |
995 | unsigned long set_interrupt_mask_reg; | 1215 | unsigned long set_interrupt_mask_reg; |
996 | unsigned long clr_interrupt_mask_reg; | 1216 | unsigned long clr_interrupt_mask_reg; |
1217 | unsigned long clr_interrupt_mask_reg32; | ||
997 | unsigned long sense_interrupt_mask_reg; | 1218 | unsigned long sense_interrupt_mask_reg; |
1219 | unsigned long sense_interrupt_mask_reg32; | ||
998 | unsigned long clr_interrupt_reg; | 1220 | unsigned long clr_interrupt_reg; |
1221 | unsigned long clr_interrupt_reg32; | ||
999 | 1222 | ||
1000 | unsigned long sense_interrupt_reg; | 1223 | unsigned long sense_interrupt_reg; |
1224 | unsigned long sense_interrupt_reg32; | ||
1001 | unsigned long ioarrin_reg; | 1225 | unsigned long ioarrin_reg; |
1002 | unsigned long sense_uproc_interrupt_reg; | 1226 | unsigned long sense_uproc_interrupt_reg; |
1227 | unsigned long sense_uproc_interrupt_reg32; | ||
1003 | unsigned long set_uproc_interrupt_reg; | 1228 | unsigned long set_uproc_interrupt_reg; |
1229 | unsigned long set_uproc_interrupt_reg32; | ||
1004 | unsigned long clr_uproc_interrupt_reg; | 1230 | unsigned long clr_uproc_interrupt_reg; |
1231 | unsigned long clr_uproc_interrupt_reg32; | ||
1232 | |||
1233 | unsigned long init_feedback_reg; | ||
1234 | |||
1235 | unsigned long dump_addr_reg; | ||
1236 | unsigned long dump_data_reg; | ||
1005 | }; | 1237 | }; |
1006 | 1238 | ||
1007 | struct ipr_interrupts { | 1239 | struct ipr_interrupts { |
1008 | void __iomem *set_interrupt_mask_reg; | 1240 | void __iomem *set_interrupt_mask_reg; |
1009 | void __iomem *clr_interrupt_mask_reg; | 1241 | void __iomem *clr_interrupt_mask_reg; |
1242 | void __iomem *clr_interrupt_mask_reg32; | ||
1010 | void __iomem *sense_interrupt_mask_reg; | 1243 | void __iomem *sense_interrupt_mask_reg; |
1244 | void __iomem *sense_interrupt_mask_reg32; | ||
1011 | void __iomem *clr_interrupt_reg; | 1245 | void __iomem *clr_interrupt_reg; |
1246 | void __iomem *clr_interrupt_reg32; | ||
1012 | 1247 | ||
1013 | void __iomem *sense_interrupt_reg; | 1248 | void __iomem *sense_interrupt_reg; |
1249 | void __iomem *sense_interrupt_reg32; | ||
1014 | void __iomem *ioarrin_reg; | 1250 | void __iomem *ioarrin_reg; |
1015 | void __iomem *sense_uproc_interrupt_reg; | 1251 | void __iomem *sense_uproc_interrupt_reg; |
1252 | void __iomem *sense_uproc_interrupt_reg32; | ||
1016 | void __iomem *set_uproc_interrupt_reg; | 1253 | void __iomem *set_uproc_interrupt_reg; |
1254 | void __iomem *set_uproc_interrupt_reg32; | ||
1017 | void __iomem *clr_uproc_interrupt_reg; | 1255 | void __iomem *clr_uproc_interrupt_reg; |
1256 | void __iomem *clr_uproc_interrupt_reg32; | ||
1257 | |||
1258 | void __iomem *init_feedback_reg; | ||
1259 | |||
1260 | void __iomem *dump_addr_reg; | ||
1261 | void __iomem *dump_data_reg; | ||
1018 | }; | 1262 | }; |
1019 | 1263 | ||
1020 | struct ipr_chip_cfg_t { | 1264 | struct ipr_chip_cfg_t { |
@@ -1029,6 +1273,9 @@ struct ipr_chip_t { | |||
1029 | u16 intr_type; | 1273 | u16 intr_type; |
1030 | #define IPR_USE_LSI 0x00 | 1274 | #define IPR_USE_LSI 0x00 |
1031 | #define IPR_USE_MSI 0x01 | 1275 | #define IPR_USE_MSI 0x01 |
1276 | u16 sis_type; | ||
1277 | #define IPR_SIS32 0x00 | ||
1278 | #define IPR_SIS64 0x01 | ||
1032 | const struct ipr_chip_cfg_t *cfg; | 1279 | const struct ipr_chip_cfg_t *cfg; |
1033 | }; | 1280 | }; |
1034 | 1281 | ||
@@ -1073,13 +1320,6 @@ enum ipr_sdt_state { | |||
1073 | DUMP_OBTAINED | 1320 | DUMP_OBTAINED |
1074 | }; | 1321 | }; |
1075 | 1322 | ||
1076 | enum ipr_cache_state { | ||
1077 | CACHE_NONE, | ||
1078 | CACHE_DISABLED, | ||
1079 | CACHE_ENABLED, | ||
1080 | CACHE_INVALID | ||
1081 | }; | ||
1082 | |||
1083 | /* Per-controller data */ | 1323 | /* Per-controller data */ |
1084 | struct ipr_ioa_cfg { | 1324 | struct ipr_ioa_cfg { |
1085 | char eye_catcher[8]; | 1325 | char eye_catcher[8]; |
@@ -1099,10 +1339,17 @@ struct ipr_ioa_cfg { | |||
1099 | u8 dual_raid:1; | 1339 | u8 dual_raid:1; |
1100 | u8 needs_warm_reset:1; | 1340 | u8 needs_warm_reset:1; |
1101 | u8 msi_received:1; | 1341 | u8 msi_received:1; |
1342 | u8 sis64:1; | ||
1102 | 1343 | ||
1103 | u8 revid; | 1344 | u8 revid; |
1104 | 1345 | ||
1105 | enum ipr_cache_state cache_state; | 1346 | /* |
1347 | * Bitmaps for SIS64 generated target values | ||
1348 | */ | ||
1349 | unsigned long *target_ids; | ||
1350 | unsigned long *array_ids; | ||
1351 | unsigned long *vset_ids; | ||
1352 | |||
1106 | u16 type; /* CCIN of the card */ | 1353 | u16 type; /* CCIN of the card */ |
1107 | 1354 | ||
1108 | u8 log_level; | 1355 | u8 log_level; |
@@ -1133,8 +1380,13 @@ struct ipr_ioa_cfg { | |||
1133 | 1380 | ||
1134 | char cfg_table_start[8]; | 1381 | char cfg_table_start[8]; |
1135 | #define IPR_CFG_TBL_START "cfg" | 1382 | #define IPR_CFG_TBL_START "cfg" |
1136 | struct ipr_config_table *cfg_table; | 1383 | union { |
1384 | struct ipr_config_table *cfg_table; | ||
1385 | struct ipr_config_table64 *cfg_table64; | ||
1386 | } u; | ||
1137 | dma_addr_t cfg_table_dma; | 1387 | dma_addr_t cfg_table_dma; |
1388 | u32 cfg_table_size; | ||
1389 | u32 max_devs_supported; | ||
1138 | 1390 | ||
1139 | char resource_table_label[8]; | 1391 | char resource_table_label[8]; |
1140 | #define IPR_RES_TABLE_LABEL "res_tbl" | 1392 | #define IPR_RES_TABLE_LABEL "res_tbl" |
@@ -1202,13 +1454,17 @@ struct ipr_ioa_cfg { | |||
1202 | char ipr_cmd_label[8]; | 1454 | char ipr_cmd_label[8]; |
1203 | #define IPR_CMD_LABEL "ipr_cmd" | 1455 | #define IPR_CMD_LABEL "ipr_cmd" |
1204 | struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS]; | 1456 | struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS]; |
1205 | u32 ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS]; | 1457 | dma_addr_t ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS]; |
1206 | }; | 1458 | }; /* struct ipr_ioa_cfg */ |
1207 | 1459 | ||
1208 | struct ipr_cmnd { | 1460 | struct ipr_cmnd { |
1209 | struct ipr_ioarcb ioarcb; | 1461 | struct ipr_ioarcb ioarcb; |
1462 | union { | ||
1463 | struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES]; | ||
1464 | struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES]; | ||
1465 | struct ipr_ata64_ioadl ata_ioadl; | ||
1466 | } i; | ||
1210 | struct ipr_ioasa ioasa; | 1467 | struct ipr_ioasa ioasa; |
1211 | struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES]; | ||
1212 | struct list_head queue; | 1468 | struct list_head queue; |
1213 | struct scsi_cmnd *scsi_cmd; | 1469 | struct scsi_cmnd *scsi_cmd; |
1214 | struct ata_queued_cmd *qc; | 1470 | struct ata_queued_cmd *qc; |
@@ -1221,7 +1477,7 @@ struct ipr_cmnd { | |||
1221 | u8 sense_buffer[SCSI_SENSE_BUFFERSIZE]; | 1477 | u8 sense_buffer[SCSI_SENSE_BUFFERSIZE]; |
1222 | dma_addr_t sense_buffer_dma; | 1478 | dma_addr_t sense_buffer_dma; |
1223 | unsigned short dma_use_sg; | 1479 | unsigned short dma_use_sg; |
1224 | dma_addr_t dma_handle; | 1480 | dma_addr_t dma_addr; |
1225 | struct ipr_cmnd *sibling; | 1481 | struct ipr_cmnd *sibling; |
1226 | union { | 1482 | union { |
1227 | enum ipr_shutdown_type shutdown_type; | 1483 | enum ipr_shutdown_type shutdown_type; |
@@ -1314,8 +1570,6 @@ struct ipr_ioa_dump { | |||
1314 | u32 next_page_index; | 1570 | u32 next_page_index; |
1315 | u32 page_offset; | 1571 | u32 page_offset; |
1316 | u32 format; | 1572 | u32 format; |
1317 | #define IPR_SDT_FMT2 2 | ||
1318 | #define IPR_SDT_UNKNOWN 3 | ||
1319 | }__attribute__((packed, aligned (4))); | 1573 | }__attribute__((packed, aligned (4))); |
1320 | 1574 | ||
1321 | struct ipr_dump { | 1575 | struct ipr_dump { |
@@ -1377,6 +1631,13 @@ struct ipr_ucode_image_header { | |||
1377 | #define ipr_info(...) printk(KERN_INFO IPR_NAME ": "__VA_ARGS__) | 1631 | #define ipr_info(...) printk(KERN_INFO IPR_NAME ": "__VA_ARGS__) |
1378 | #define ipr_dbg(...) IPR_DBG_CMD(printk(KERN_INFO IPR_NAME ": "__VA_ARGS__)) | 1632 | #define ipr_dbg(...) IPR_DBG_CMD(printk(KERN_INFO IPR_NAME ": "__VA_ARGS__)) |
1379 | 1633 | ||
1634 | #define ipr_res_printk(level, ioa_cfg, bus, target, lun, fmt, ...) \ | ||
1635 | printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \ | ||
1636 | bus, target, lun, ##__VA_ARGS__) | ||
1637 | |||
1638 | #define ipr_res_err(ioa_cfg, res, fmt, ...) \ | ||
1639 | ipr_res_printk(KERN_ERR, ioa_cfg, (res)->bus, (res)->target, (res)->lun, fmt, ##__VA_ARGS__) | ||
1640 | |||
1380 | #define ipr_ra_printk(level, ioa_cfg, ra, fmt, ...) \ | 1641 | #define ipr_ra_printk(level, ioa_cfg, ra, fmt, ...) \ |
1381 | printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \ | 1642 | printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \ |
1382 | (ra).bus, (ra).target, (ra).lun, ##__VA_ARGS__) | 1643 | (ra).bus, (ra).target, (ra).lun, ##__VA_ARGS__) |
@@ -1384,9 +1645,6 @@ struct ipr_ucode_image_header { | |||
1384 | #define ipr_ra_err(ioa_cfg, ra, fmt, ...) \ | 1645 | #define ipr_ra_err(ioa_cfg, ra, fmt, ...) \ |
1385 | ipr_ra_printk(KERN_ERR, ioa_cfg, ra, fmt, ##__VA_ARGS__) | 1646 | ipr_ra_printk(KERN_ERR, ioa_cfg, ra, fmt, ##__VA_ARGS__) |
1386 | 1647 | ||
1387 | #define ipr_res_err(ioa_cfg, res, fmt, ...) \ | ||
1388 | ipr_ra_err(ioa_cfg, (res)->cfgte.res_addr, fmt, ##__VA_ARGS__) | ||
1389 | |||
1390 | #define ipr_phys_res_err(ioa_cfg, res, fmt, ...) \ | 1648 | #define ipr_phys_res_err(ioa_cfg, res, fmt, ...) \ |
1391 | { \ | 1649 | { \ |
1392 | if ((res).bus >= IPR_MAX_NUM_BUSES) { \ | 1650 | if ((res).bus >= IPR_MAX_NUM_BUSES) { \ |
@@ -1399,14 +1657,21 @@ struct ipr_ucode_image_header { | |||
1399 | } | 1657 | } |
1400 | 1658 | ||
1401 | #define ipr_hcam_err(hostrcb, fmt, ...) \ | 1659 | #define ipr_hcam_err(hostrcb, fmt, ...) \ |
1402 | { \ | 1660 | { \ |
1403 | if (ipr_is_device(&(hostrcb)->hcam.u.error.failing_dev_res_addr)) { \ | 1661 | if (ipr_is_device(hostrcb)) { \ |
1404 | ipr_ra_err((hostrcb)->ioa_cfg, \ | 1662 | if ((hostrcb)->ioa_cfg->sis64) { \ |
1405 | (hostrcb)->hcam.u.error.failing_dev_res_addr, \ | 1663 | printk(KERN_ERR IPR_NAME ": %s: " fmt, \ |
1406 | fmt, ##__VA_ARGS__); \ | 1664 | ipr_format_resource_path(&hostrcb->hcam.u.error64.fd_res_path[0], \ |
1407 | } else { \ | 1665 | &hostrcb->rp_buffer[0]), \ |
1408 | dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, ##__VA_ARGS__); \ | 1666 | __VA_ARGS__); \ |
1409 | } \ | 1667 | } else { \ |
1668 | ipr_ra_err((hostrcb)->ioa_cfg, \ | ||
1669 | (hostrcb)->hcam.u.error.fd_res_addr, \ | ||
1670 | fmt, __VA_ARGS__); \ | ||
1671 | } \ | ||
1672 | } else { \ | ||
1673 | dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, __VA_ARGS__); \ | ||
1674 | } \ | ||
1410 | } | 1675 | } |
1411 | 1676 | ||
1412 | #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ | 1677 | #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ |
@@ -1432,7 +1697,7 @@ ipr_err("----------------------------------------------------------\n") | |||
1432 | **/ | 1697 | **/ |
1433 | static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res) | 1698 | static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res) |
1434 | { | 1699 | { |
1435 | return (res->cfgte.flags & IPR_IS_IOA_RESOURCE) ? 1 : 0; | 1700 | return res->type == IPR_RES_TYPE_IOAFP; |
1436 | } | 1701 | } |
1437 | 1702 | ||
1438 | /** | 1703 | /** |
@@ -1444,12 +1709,8 @@ static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res) | |||
1444 | **/ | 1709 | **/ |
1445 | static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res) | 1710 | static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res) |
1446 | { | 1711 | { |
1447 | if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data) && | 1712 | return res->type == IPR_RES_TYPE_AF_DASD || |
1448 | !ipr_is_ioa_resource(res) && | 1713 | res->type == IPR_RES_TYPE_REMOTE_AF_DASD; |
1449 | IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_AF_DASD) | ||
1450 | return 1; | ||
1451 | else | ||
1452 | return 0; | ||
1453 | } | 1714 | } |
1454 | 1715 | ||
1455 | /** | 1716 | /** |
@@ -1461,12 +1722,7 @@ static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res) | |||
1461 | **/ | 1722 | **/ |
1462 | static inline int ipr_is_vset_device(struct ipr_resource_entry *res) | 1723 | static inline int ipr_is_vset_device(struct ipr_resource_entry *res) |
1463 | { | 1724 | { |
1464 | if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data) && | 1725 | return res->type == IPR_RES_TYPE_VOLUME_SET; |
1465 | !ipr_is_ioa_resource(res) && | ||
1466 | IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_VOLUME_SET) | ||
1467 | return 1; | ||
1468 | else | ||
1469 | return 0; | ||
1470 | } | 1726 | } |
1471 | 1727 | ||
1472 | /** | 1728 | /** |
@@ -1478,11 +1734,7 @@ static inline int ipr_is_vset_device(struct ipr_resource_entry *res) | |||
1478 | **/ | 1734 | **/ |
1479 | static inline int ipr_is_gscsi(struct ipr_resource_entry *res) | 1735 | static inline int ipr_is_gscsi(struct ipr_resource_entry *res) |
1480 | { | 1736 | { |
1481 | if (!ipr_is_ioa_resource(res) && | 1737 | return res->type == IPR_RES_TYPE_GENERIC_SCSI; |
1482 | IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_GENERIC_SCSI) | ||
1483 | return 1; | ||
1484 | else | ||
1485 | return 0; | ||
1486 | } | 1738 | } |
1487 | 1739 | ||
1488 | /** | 1740 | /** |
@@ -1495,7 +1747,7 @@ static inline int ipr_is_gscsi(struct ipr_resource_entry *res) | |||
1495 | static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res) | 1747 | static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res) |
1496 | { | 1748 | { |
1497 | if (ipr_is_af_dasd_device(res) || | 1749 | if (ipr_is_af_dasd_device(res) || |
1498 | (ipr_is_gscsi(res) && IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data))) | 1750 | (ipr_is_gscsi(res) && IPR_IS_DASD_DEVICE(res->std_inq_data))) |
1499 | return 1; | 1751 | return 1; |
1500 | else | 1752 | else |
1501 | return 0; | 1753 | return 0; |
@@ -1510,11 +1762,7 @@ static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res) | |||
1510 | **/ | 1762 | **/ |
1511 | static inline int ipr_is_gata(struct ipr_resource_entry *res) | 1763 | static inline int ipr_is_gata(struct ipr_resource_entry *res) |
1512 | { | 1764 | { |
1513 | if (!ipr_is_ioa_resource(res) && | 1765 | return res->type == IPR_RES_TYPE_GENERIC_ATA; |
1514 | IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_GENERIC_ATA) | ||
1515 | return 1; | ||
1516 | else | ||
1517 | return 0; | ||
1518 | } | 1766 | } |
1519 | 1767 | ||
1520 | /** | 1768 | /** |
@@ -1526,24 +1774,35 @@ static inline int ipr_is_gata(struct ipr_resource_entry *res) | |||
1526 | **/ | 1774 | **/ |
1527 | static inline int ipr_is_naca_model(struct ipr_resource_entry *res) | 1775 | static inline int ipr_is_naca_model(struct ipr_resource_entry *res) |
1528 | { | 1776 | { |
1529 | if (ipr_is_gscsi(res) && IPR_QUEUEING_MODEL(res) == IPR_QUEUE_NACA_MODEL) | 1777 | if (ipr_is_gscsi(res) && res->qmodel == IPR_QUEUE_NACA_MODEL) |
1530 | return 1; | 1778 | return 1; |
1531 | return 0; | 1779 | return 0; |
1532 | } | 1780 | } |
1533 | 1781 | ||
1534 | /** | 1782 | /** |
1535 | * ipr_is_device - Determine if resource address is that of a device | 1783 | * ipr_is_device - Determine if the hostrcb structure is related to a device |
1536 | * @res_addr: resource address struct | 1784 | * @hostrcb: host resource control blocks struct |
1537 | * | 1785 | * |
1538 | * Return value: | 1786 | * Return value: |
1539 | * 1 if AF / 0 if not AF | 1787 | * 1 if AF / 0 if not AF |
1540 | **/ | 1788 | **/ |
1541 | static inline int ipr_is_device(struct ipr_res_addr *res_addr) | 1789 | static inline int ipr_is_device(struct ipr_hostrcb *hostrcb) |
1542 | { | 1790 | { |
1543 | if ((res_addr->bus < IPR_MAX_NUM_BUSES) && | 1791 | struct ipr_res_addr *res_addr; |
1544 | (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1))) | 1792 | u8 *res_path; |
1545 | return 1; | 1793 | |
1546 | 1794 | if (hostrcb->ioa_cfg->sis64) { | |
1795 | res_path = &hostrcb->hcam.u.error64.fd_res_path[0]; | ||
1796 | if ((res_path[0] == 0x00 || res_path[0] == 0x80 || | ||
1797 | res_path[0] == 0x81) && res_path[2] != 0xFF) | ||
1798 | return 1; | ||
1799 | } else { | ||
1800 | res_addr = &hostrcb->hcam.u.error.fd_res_addr; | ||
1801 | |||
1802 | if ((res_addr->bus < IPR_MAX_NUM_BUSES) && | ||
1803 | (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1))) | ||
1804 | return 1; | ||
1805 | } | ||
1547 | return 0; | 1806 | return 0; |
1548 | } | 1807 | } |
1549 | 1808 | ||
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 8a89ba900588..249053a9d4fa 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -874,7 +874,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = { | |||
874 | .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, | 874 | .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, |
875 | .eh_abort_handler = iscsi_eh_abort, | 875 | .eh_abort_handler = iscsi_eh_abort, |
876 | .eh_device_reset_handler= iscsi_eh_device_reset, | 876 | .eh_device_reset_handler= iscsi_eh_device_reset, |
877 | .eh_target_reset_handler= iscsi_eh_target_reset, | 877 | .eh_target_reset_handler = iscsi_eh_recover_target, |
878 | .use_clustering = DISABLE_CLUSTERING, | 878 | .use_clustering = DISABLE_CLUSTERING, |
879 | .slave_alloc = iscsi_sw_tcp_slave_alloc, | 879 | .slave_alloc = iscsi_sw_tcp_slave_alloc, |
880 | .slave_configure = iscsi_sw_tcp_slave_configure, | 880 | .slave_configure = iscsi_sw_tcp_slave_configure, |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 703eb6a88790..685eaec53218 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -2338,7 +2338,7 @@ EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout); | |||
2338 | * This function will wait for a relogin, session termination from | 2338 | * This function will wait for a relogin, session termination from |
2339 | * userspace, or a recovery/replacement timeout. | 2339 | * userspace, or a recovery/replacement timeout. |
2340 | */ | 2340 | */ |
2341 | static int iscsi_eh_session_reset(struct scsi_cmnd *sc) | 2341 | int iscsi_eh_session_reset(struct scsi_cmnd *sc) |
2342 | { | 2342 | { |
2343 | struct iscsi_cls_session *cls_session; | 2343 | struct iscsi_cls_session *cls_session; |
2344 | struct iscsi_session *session; | 2344 | struct iscsi_session *session; |
@@ -2389,6 +2389,7 @@ failed: | |||
2389 | mutex_unlock(&session->eh_mutex); | 2389 | mutex_unlock(&session->eh_mutex); |
2390 | return SUCCESS; | 2390 | return SUCCESS; |
2391 | } | 2391 | } |
2392 | EXPORT_SYMBOL_GPL(iscsi_eh_session_reset); | ||
2392 | 2393 | ||
2393 | static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr) | 2394 | static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr) |
2394 | { | 2395 | { |
@@ -2403,8 +2404,7 @@ static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr) | |||
2403 | * iscsi_eh_target_reset - reset target | 2404 | * iscsi_eh_target_reset - reset target |
2404 | * @sc: scsi command | 2405 | * @sc: scsi command |
2405 | * | 2406 | * |
2406 | * This will attempt to send a warm target reset. If that fails | 2407 | * This will attempt to send a warm target reset. |
2407 | * then we will drop the session and attempt ERL0 recovery. | ||
2408 | */ | 2408 | */ |
2409 | int iscsi_eh_target_reset(struct scsi_cmnd *sc) | 2409 | int iscsi_eh_target_reset(struct scsi_cmnd *sc) |
2410 | { | 2410 | { |
@@ -2476,12 +2476,27 @@ done: | |||
2476 | ISCSI_DBG_EH(session, "tgt %s reset result = %s\n", session->targetname, | 2476 | ISCSI_DBG_EH(session, "tgt %s reset result = %s\n", session->targetname, |
2477 | rc == SUCCESS ? "SUCCESS" : "FAILED"); | 2477 | rc == SUCCESS ? "SUCCESS" : "FAILED"); |
2478 | mutex_unlock(&session->eh_mutex); | 2478 | mutex_unlock(&session->eh_mutex); |
2479 | return rc; | ||
2480 | } | ||
2481 | EXPORT_SYMBOL_GPL(iscsi_eh_target_reset); | ||
2479 | 2482 | ||
2483 | /** | ||
2484 | * iscsi_eh_recover_target - reset target and possibly the session | ||
2485 | * @sc: scsi command | ||
2486 | * | ||
2487 | * This will attempt to send a warm target reset. If that fails, | ||
2488 | * we will escalate to ERL0 session recovery. | ||
2489 | */ | ||
2490 | int iscsi_eh_recover_target(struct scsi_cmnd *sc) | ||
2491 | { | ||
2492 | int rc; | ||
2493 | |||
2494 | rc = iscsi_eh_target_reset(sc); | ||
2480 | if (rc == FAILED) | 2495 | if (rc == FAILED) |
2481 | rc = iscsi_eh_session_reset(sc); | 2496 | rc = iscsi_eh_session_reset(sc); |
2482 | return rc; | 2497 | return rc; |
2483 | } | 2498 | } |
2484 | EXPORT_SYMBOL_GPL(iscsi_eh_target_reset); | 2499 | EXPORT_SYMBOL_GPL(iscsi_eh_recover_target); |
2485 | 2500 | ||
2486 | /* | 2501 | /* |
2487 | * Pre-allocate a pool of @max items of @item_size. By default, the pool | 2502 | * Pre-allocate a pool of @max items of @item_size. By default, the pool |
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 84b696463a58..565e16dd74fc 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -37,6 +37,9 @@ struct lpfc_sli2_slim; | |||
37 | the NameServer before giving up. */ | 37 | the NameServer before giving up. */ |
38 | #define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */ | 38 | #define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */ |
39 | #define LPFC_DEFAULT_SG_SEG_CNT 64 /* sg element count per scsi cmnd */ | 39 | #define LPFC_DEFAULT_SG_SEG_CNT 64 /* sg element count per scsi cmnd */ |
40 | #define LPFC_DEFAULT_MENLO_SG_SEG_CNT 128 /* sg element count per scsi | ||
41 | cmnd for menlo needs nearly twice as for firmware | ||
42 | downloads using bsg */ | ||
40 | #define LPFC_DEFAULT_PROT_SG_SEG_CNT 4096 /* sg protection elements count */ | 43 | #define LPFC_DEFAULT_PROT_SG_SEG_CNT 4096 /* sg protection elements count */ |
41 | #define LPFC_MAX_SG_SEG_CNT 4096 /* sg element count per scsi cmnd */ | 44 | #define LPFC_MAX_SG_SEG_CNT 4096 /* sg element count per scsi cmnd */ |
42 | #define LPFC_MAX_PROT_SG_SEG_CNT 4096 /* prot sg element count per scsi cmd*/ | 45 | #define LPFC_MAX_PROT_SG_SEG_CNT 4096 /* prot sg element count per scsi cmd*/ |
@@ -509,7 +512,6 @@ struct lpfc_hba { | |||
509 | int (*lpfc_hba_down_link) | 512 | int (*lpfc_hba_down_link) |
510 | (struct lpfc_hba *); | 513 | (struct lpfc_hba *); |
511 | 514 | ||
512 | |||
513 | /* SLI4 specific HBA data structure */ | 515 | /* SLI4 specific HBA data structure */ |
514 | struct lpfc_sli4_hba sli4_hba; | 516 | struct lpfc_sli4_hba sli4_hba; |
515 | 517 | ||
@@ -623,6 +625,9 @@ struct lpfc_hba { | |||
623 | uint32_t cfg_log_verbose; | 625 | uint32_t cfg_log_verbose; |
624 | uint32_t cfg_aer_support; | 626 | uint32_t cfg_aer_support; |
625 | uint32_t cfg_suppress_link_up; | 627 | uint32_t cfg_suppress_link_up; |
628 | #define LPFC_INITIALIZE_LINK 0 /* do normal init_link mbox */ | ||
629 | #define LPFC_DELAY_INIT_LINK 1 /* layered driver hold off */ | ||
630 | #define LPFC_DELAY_INIT_LINK_INDEFINITELY 2 /* wait, manual intervention */ | ||
626 | 631 | ||
627 | lpfc_vpd_t vpd; /* vital product data */ | 632 | lpfc_vpd_t vpd; /* vital product data */ |
628 | 633 | ||
@@ -804,6 +809,9 @@ struct lpfc_hba { | |||
804 | struct list_head ct_ev_waiters; | 809 | struct list_head ct_ev_waiters; |
805 | struct unsol_rcv_ct_ctx ct_ctx[64]; | 810 | struct unsol_rcv_ct_ctx ct_ctx[64]; |
806 | uint32_t ctx_idx; | 811 | uint32_t ctx_idx; |
812 | |||
813 | uint8_t menlo_flag; /* menlo generic flags */ | ||
814 | #define HBA_MENLO_SUPPORT 0x1 /* HBA supports menlo commands */ | ||
807 | }; | 815 | }; |
808 | 816 | ||
809 | static inline struct Scsi_Host * | 817 | static inline struct Scsi_Host * |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index c992e8328f9e..64cd17eedb64 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -1939,7 +1939,9 @@ static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, | |||
1939 | # 0x2 = never bring up link | 1939 | # 0x2 = never bring up link |
1940 | # Default value is 0. | 1940 | # Default value is 0. |
1941 | */ | 1941 | */ |
1942 | LPFC_ATTR_R(suppress_link_up, 0, 0, 2, "Suppress Link Up at initialization"); | 1942 | LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK, |
1943 | LPFC_DELAY_INIT_LINK_INDEFINITELY, | ||
1944 | "Suppress Link Up at initialization"); | ||
1943 | 1945 | ||
1944 | /* | 1946 | /* |
1945 | # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear | 1947 | # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear |
@@ -1966,8 +1968,7 @@ lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr, | |||
1966 | { | 1968 | { |
1967 | struct Scsi_Host *shost = class_to_shost(dev); | 1969 | struct Scsi_Host *shost = class_to_shost(dev); |
1968 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 1970 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1969 | int val = 0; | 1971 | |
1970 | val = vport->cfg_devloss_tmo; | ||
1971 | return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo); | 1972 | return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo); |
1972 | } | 1973 | } |
1973 | 1974 | ||
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index f3f1bf1a0a71..692c29f6048e 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c | |||
@@ -83,15 +83,28 @@ struct lpfc_bsg_mbox { | |||
83 | struct fc_bsg_job *set_job; | 83 | struct fc_bsg_job *set_job; |
84 | }; | 84 | }; |
85 | 85 | ||
86 | #define MENLO_DID 0x0000FC0E | ||
87 | |||
88 | struct lpfc_bsg_menlo { | ||
89 | struct lpfc_iocbq *cmdiocbq; | ||
90 | struct lpfc_iocbq *rspiocbq; | ||
91 | struct lpfc_dmabuf *bmp; | ||
92 | |||
93 | /* job waiting for this iocb to finish */ | ||
94 | struct fc_bsg_job *set_job; | ||
95 | }; | ||
96 | |||
86 | #define TYPE_EVT 1 | 97 | #define TYPE_EVT 1 |
87 | #define TYPE_IOCB 2 | 98 | #define TYPE_IOCB 2 |
88 | #define TYPE_MBOX 3 | 99 | #define TYPE_MBOX 3 |
100 | #define TYPE_MENLO 4 | ||
89 | struct bsg_job_data { | 101 | struct bsg_job_data { |
90 | uint32_t type; | 102 | uint32_t type; |
91 | union { | 103 | union { |
92 | struct lpfc_bsg_event *evt; | 104 | struct lpfc_bsg_event *evt; |
93 | struct lpfc_bsg_iocb iocb; | 105 | struct lpfc_bsg_iocb iocb; |
94 | struct lpfc_bsg_mbox mbox; | 106 | struct lpfc_bsg_mbox mbox; |
107 | struct lpfc_bsg_menlo menlo; | ||
95 | } context_un; | 108 | } context_un; |
96 | }; | 109 | }; |
97 | 110 | ||
@@ -2456,6 +2469,18 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba, | |||
2456 | case MBX_PORT_IOV_CONTROL: | 2469 | case MBX_PORT_IOV_CONTROL: |
2457 | break; | 2470 | break; |
2458 | case MBX_SET_VARIABLE: | 2471 | case MBX_SET_VARIABLE: |
2472 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
2473 | "1226 mbox: set_variable 0x%x, 0x%x\n", | ||
2474 | mb->un.varWords[0], | ||
2475 | mb->un.varWords[1]); | ||
2476 | if ((mb->un.varWords[0] == SETVAR_MLOMNT) | ||
2477 | && (mb->un.varWords[1] == 1)) { | ||
2478 | phba->wait_4_mlo_maint_flg = 1; | ||
2479 | } else if (mb->un.varWords[0] == SETVAR_MLORST) { | ||
2480 | phba->link_flag &= ~LS_LOOPBACK_MODE; | ||
2481 | phba->fc_topology = TOPOLOGY_PT_PT; | ||
2482 | } | ||
2483 | break; | ||
2459 | case MBX_RUN_BIU_DIAG64: | 2484 | case MBX_RUN_BIU_DIAG64: |
2460 | case MBX_READ_EVENT_LOG: | 2485 | case MBX_READ_EVENT_LOG: |
2461 | case MBX_READ_SPARM64: | 2486 | case MBX_READ_SPARM64: |
@@ -2638,6 +2663,297 @@ job_error: | |||
2638 | } | 2663 | } |
2639 | 2664 | ||
2640 | /** | 2665 | /** |
2666 | * lpfc_bsg_menlo_cmd_cmp - lpfc_menlo_cmd completion handler | ||
2667 | * @phba: Pointer to HBA context object. | ||
2668 | * @cmdiocbq: Pointer to command iocb. | ||
2669 | * @rspiocbq: Pointer to response iocb. | ||
2670 | * | ||
2671 | * This function is the completion handler for iocbs issued using | ||
2672 | * lpfc_menlo_cmd function. This function is called by the | ||
2673 | * ring event handler function without any lock held. This function | ||
2674 | * can be called from both worker thread context and interrupt | ||
2675 | * context. This function also can be called from another thread which | ||
2676 | * cleans up the SLI layer objects. | ||
2677 | * This function copies the contents of the response iocb to the | ||
2678 | * response iocb memory object provided by the caller of | ||
2679 | * lpfc_sli_issue_iocb_wait and then wakes up the thread which | ||
2680 | * sleeps for the iocb completion. | ||
2681 | **/ | ||
2682 | static void | ||
2683 | lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba, | ||
2684 | struct lpfc_iocbq *cmdiocbq, | ||
2685 | struct lpfc_iocbq *rspiocbq) | ||
2686 | { | ||
2687 | struct bsg_job_data *dd_data; | ||
2688 | struct fc_bsg_job *job; | ||
2689 | IOCB_t *rsp; | ||
2690 | struct lpfc_dmabuf *bmp; | ||
2691 | struct lpfc_bsg_menlo *menlo; | ||
2692 | unsigned long flags; | ||
2693 | struct menlo_response *menlo_resp; | ||
2694 | int rc = 0; | ||
2695 | |||
2696 | spin_lock_irqsave(&phba->ct_ev_lock, flags); | ||
2697 | dd_data = cmdiocbq->context1; | ||
2698 | if (!dd_data) { | ||
2699 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); | ||
2700 | return; | ||
2701 | } | ||
2702 | |||
2703 | menlo = &dd_data->context_un.menlo; | ||
2704 | job = menlo->set_job; | ||
2705 | job->dd_data = NULL; /* so timeout handler does not reply */ | ||
2706 | |||
2707 | spin_lock_irqsave(&phba->hbalock, flags); | ||
2708 | cmdiocbq->iocb_flag |= LPFC_IO_WAKE; | ||
2709 | if (cmdiocbq->context2 && rspiocbq) | ||
2710 | memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, | ||
2711 | &rspiocbq->iocb, sizeof(IOCB_t)); | ||
2712 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
2713 | |||
2714 | bmp = menlo->bmp; | ||
2715 | rspiocbq = menlo->rspiocbq; | ||
2716 | rsp = &rspiocbq->iocb; | ||
2717 | |||
2718 | pci_unmap_sg(phba->pcidev, job->request_payload.sg_list, | ||
2719 | job->request_payload.sg_cnt, DMA_TO_DEVICE); | ||
2720 | pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list, | ||
2721 | job->reply_payload.sg_cnt, DMA_FROM_DEVICE); | ||
2722 | |||
2723 | /* always return the xri, this would be used in the case | ||
2724 | * of a menlo download to allow the data to be sent as a continuation | ||
2725 | * of the exchange. | ||
2726 | */ | ||
2727 | menlo_resp = (struct menlo_response *) | ||
2728 | job->reply->reply_data.vendor_reply.vendor_rsp; | ||
2729 | menlo_resp->xri = rsp->ulpContext; | ||
2730 | if (rsp->ulpStatus) { | ||
2731 | if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) { | ||
2732 | switch (rsp->un.ulpWord[4] & 0xff) { | ||
2733 | case IOERR_SEQUENCE_TIMEOUT: | ||
2734 | rc = -ETIMEDOUT; | ||
2735 | break; | ||
2736 | case IOERR_INVALID_RPI: | ||
2737 | rc = -EFAULT; | ||
2738 | break; | ||
2739 | default: | ||
2740 | rc = -EACCES; | ||
2741 | break; | ||
2742 | } | ||
2743 | } else | ||
2744 | rc = -EACCES; | ||
2745 | } else | ||
2746 | job->reply->reply_payload_rcv_len = | ||
2747 | rsp->un.genreq64.bdl.bdeSize; | ||
2748 | |||
2749 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | ||
2750 | lpfc_sli_release_iocbq(phba, rspiocbq); | ||
2751 | lpfc_sli_release_iocbq(phba, cmdiocbq); | ||
2752 | kfree(bmp); | ||
2753 | kfree(dd_data); | ||
2754 | /* make error code available to userspace */ | ||
2755 | job->reply->result = rc; | ||
2756 | /* complete the job back to userspace */ | ||
2757 | job->job_done(job); | ||
2758 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); | ||
2759 | return; | ||
2760 | } | ||
2761 | |||
2762 | /** | ||
2763 | * lpfc_menlo_cmd - send an ioctl for menlo hardware | ||
2764 | * @job: fc_bsg_job to handle | ||
2765 | * | ||
2766 | * This function issues a gen request 64 CR ioctl for all menlo cmd requests, | ||
2767 | * all the command completions will return the xri for the command. | ||
2768 | * For menlo data requests a gen request 64 CX is used to continue the exchange | ||
2769 | * supplied in the menlo request header xri field. | ||
2770 | **/ | ||
2771 | static int | ||
2772 | lpfc_menlo_cmd(struct fc_bsg_job *job) | ||
2773 | { | ||
2774 | struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata; | ||
2775 | struct lpfc_hba *phba = vport->phba; | ||
2776 | struct lpfc_iocbq *cmdiocbq, *rspiocbq; | ||
2777 | IOCB_t *cmd, *rsp; | ||
2778 | int rc = 0; | ||
2779 | struct menlo_command *menlo_cmd; | ||
2780 | struct menlo_response *menlo_resp; | ||
2781 | struct lpfc_dmabuf *bmp = NULL; | ||
2782 | int request_nseg; | ||
2783 | int reply_nseg; | ||
2784 | struct scatterlist *sgel = NULL; | ||
2785 | int numbde; | ||
2786 | dma_addr_t busaddr; | ||
2787 | struct bsg_job_data *dd_data; | ||
2788 | struct ulp_bde64 *bpl = NULL; | ||
2789 | |||
2790 | /* in case no data is returned return just the return code */ | ||
2791 | job->reply->reply_payload_rcv_len = 0; | ||
2792 | |||
2793 | if (job->request_len < | ||
2794 | sizeof(struct fc_bsg_request) + | ||
2795 | sizeof(struct menlo_command)) { | ||
2796 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, | ||
2797 | "2784 Received MENLO_CMD request below " | ||
2798 | "minimum size\n"); | ||
2799 | rc = -ERANGE; | ||
2800 | goto no_dd_data; | ||
2801 | } | ||
2802 | |||
2803 | if (job->reply_len < | ||
2804 | sizeof(struct fc_bsg_request) + sizeof(struct menlo_response)) { | ||
2805 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, | ||
2806 | "2785 Received MENLO_CMD reply below " | ||
2807 | "minimum size\n"); | ||
2808 | rc = -ERANGE; | ||
2809 | goto no_dd_data; | ||
2810 | } | ||
2811 | |||
2812 | if (!(phba->menlo_flag & HBA_MENLO_SUPPORT)) { | ||
2813 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, | ||
2814 | "2786 Adapter does not support menlo " | ||
2815 | "commands\n"); | ||
2816 | rc = -EPERM; | ||
2817 | goto no_dd_data; | ||
2818 | } | ||
2819 | |||
2820 | menlo_cmd = (struct menlo_command *) | ||
2821 | job->request->rqst_data.h_vendor.vendor_cmd; | ||
2822 | |||
2823 | menlo_resp = (struct menlo_response *) | ||
2824 | job->reply->reply_data.vendor_reply.vendor_rsp; | ||
2825 | |||
2826 | /* allocate our bsg tracking structure */ | ||
2827 | dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); | ||
2828 | if (!dd_data) { | ||
2829 | lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, | ||
2830 | "2787 Failed allocation of dd_data\n"); | ||
2831 | rc = -ENOMEM; | ||
2832 | goto no_dd_data; | ||
2833 | } | ||
2834 | |||
2835 | bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | ||
2836 | if (!bmp) { | ||
2837 | rc = -ENOMEM; | ||
2838 | goto free_dd; | ||
2839 | } | ||
2840 | |||
2841 | cmdiocbq = lpfc_sli_get_iocbq(phba); | ||
2842 | if (!cmdiocbq) { | ||
2843 | rc = -ENOMEM; | ||
2844 | goto free_bmp; | ||
2845 | } | ||
2846 | |||
2847 | rspiocbq = lpfc_sli_get_iocbq(phba); | ||
2848 | if (!rspiocbq) { | ||
2849 | rc = -ENOMEM; | ||
2850 | goto free_cmdiocbq; | ||
2851 | } | ||
2852 | |||
2853 | rsp = &rspiocbq->iocb; | ||
2854 | |||
2855 | bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys); | ||
2856 | if (!bmp->virt) { | ||
2857 | rc = -ENOMEM; | ||
2858 | goto free_rspiocbq; | ||
2859 | } | ||
2860 | |||
2861 | INIT_LIST_HEAD(&bmp->list); | ||
2862 | bpl = (struct ulp_bde64 *) bmp->virt; | ||
2863 | request_nseg = pci_map_sg(phba->pcidev, job->request_payload.sg_list, | ||
2864 | job->request_payload.sg_cnt, DMA_TO_DEVICE); | ||
2865 | for_each_sg(job->request_payload.sg_list, sgel, request_nseg, numbde) { | ||
2866 | busaddr = sg_dma_address(sgel); | ||
2867 | bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64; | ||
2868 | bpl->tus.f.bdeSize = sg_dma_len(sgel); | ||
2869 | bpl->tus.w = cpu_to_le32(bpl->tus.w); | ||
2870 | bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr)); | ||
2871 | bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr)); | ||
2872 | bpl++; | ||
2873 | } | ||
2874 | |||
2875 | reply_nseg = pci_map_sg(phba->pcidev, job->reply_payload.sg_list, | ||
2876 | job->reply_payload.sg_cnt, DMA_FROM_DEVICE); | ||
2877 | for_each_sg(job->reply_payload.sg_list, sgel, reply_nseg, numbde) { | ||
2878 | busaddr = sg_dma_address(sgel); | ||
2879 | bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I; | ||
2880 | bpl->tus.f.bdeSize = sg_dma_len(sgel); | ||
2881 | bpl->tus.w = cpu_to_le32(bpl->tus.w); | ||
2882 | bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr)); | ||
2883 | bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr)); | ||
2884 | bpl++; | ||
2885 | } | ||
2886 | |||
2887 | cmd = &cmdiocbq->iocb; | ||
2888 | cmd->un.genreq64.bdl.ulpIoTag32 = 0; | ||
2889 | cmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys); | ||
2890 | cmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys); | ||
2891 | cmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; | ||
2892 | cmd->un.genreq64.bdl.bdeSize = | ||
2893 | (request_nseg + reply_nseg) * sizeof(struct ulp_bde64); | ||
2894 | cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA); | ||
2895 | cmd->un.genreq64.w5.hcsw.Dfctl = 0; | ||
2896 | cmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CMD; | ||
2897 | cmd->un.genreq64.w5.hcsw.Type = MENLO_TRANSPORT_TYPE; /* 0xfe */ | ||
2898 | cmd->ulpBdeCount = 1; | ||
2899 | cmd->ulpClass = CLASS3; | ||
2900 | cmd->ulpOwner = OWN_CHIP; | ||
2901 | cmd->ulpLe = 1; /* Limited Edition */ | ||
2902 | cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC; | ||
2903 | cmdiocbq->vport = phba->pport; | ||
2904 | /* We want the firmware to timeout before we do */ | ||
2905 | cmd->ulpTimeout = MENLO_TIMEOUT - 5; | ||
2906 | cmdiocbq->context3 = bmp; | ||
2907 | cmdiocbq->context2 = rspiocbq; | ||
2908 | cmdiocbq->iocb_cmpl = lpfc_bsg_menlo_cmd_cmp; | ||
2909 | cmdiocbq->context1 = dd_data; | ||
2910 | cmdiocbq->context2 = rspiocbq; | ||
2911 | if (menlo_cmd->cmd == LPFC_BSG_VENDOR_MENLO_CMD) { | ||
2912 | cmd->ulpCommand = CMD_GEN_REQUEST64_CR; | ||
2913 | cmd->ulpPU = MENLO_PU; /* 3 */ | ||
2914 | cmd->un.ulpWord[4] = MENLO_DID; /* 0x0000FC0E */ | ||
2915 | cmd->ulpContext = MENLO_CONTEXT; /* 0 */ | ||
2916 | } else { | ||
2917 | cmd->ulpCommand = CMD_GEN_REQUEST64_CX; | ||
2918 | cmd->ulpPU = 1; | ||
2919 | cmd->un.ulpWord[4] = 0; | ||
2920 | cmd->ulpContext = menlo_cmd->xri; | ||
2921 | } | ||
2922 | |||
2923 | dd_data->type = TYPE_MENLO; | ||
2924 | dd_data->context_un.menlo.cmdiocbq = cmdiocbq; | ||
2925 | dd_data->context_un.menlo.rspiocbq = rspiocbq; | ||
2926 | dd_data->context_un.menlo.set_job = job; | ||
2927 | dd_data->context_un.menlo.bmp = bmp; | ||
2928 | |||
2929 | rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, | ||
2930 | MENLO_TIMEOUT - 5); | ||
2931 | if (rc == IOCB_SUCCESS) | ||
2932 | return 0; /* done for now */ | ||
2933 | |||
2934 | /* iocb failed so cleanup */ | ||
2935 | pci_unmap_sg(phba->pcidev, job->request_payload.sg_list, | ||
2936 | job->request_payload.sg_cnt, DMA_TO_DEVICE); | ||
2937 | pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list, | ||
2938 | job->reply_payload.sg_cnt, DMA_FROM_DEVICE); | ||
2939 | |||
2940 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | ||
2941 | |||
2942 | free_rspiocbq: | ||
2943 | lpfc_sli_release_iocbq(phba, rspiocbq); | ||
2944 | free_cmdiocbq: | ||
2945 | lpfc_sli_release_iocbq(phba, cmdiocbq); | ||
2946 | free_bmp: | ||
2947 | kfree(bmp); | ||
2948 | free_dd: | ||
2949 | kfree(dd_data); | ||
2950 | no_dd_data: | ||
2951 | /* make error code available to userspace */ | ||
2952 | job->reply->result = rc; | ||
2953 | job->dd_data = NULL; | ||
2954 | return rc; | ||
2955 | } | ||
2956 | /** | ||
2641 | * lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job | 2957 | * lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job |
2642 | * @job: fc_bsg_job to handle | 2958 | * @job: fc_bsg_job to handle |
2643 | **/ | 2959 | **/ |
@@ -2669,6 +2985,10 @@ lpfc_bsg_hst_vendor(struct fc_bsg_job *job) | |||
2669 | case LPFC_BSG_VENDOR_MBOX: | 2985 | case LPFC_BSG_VENDOR_MBOX: |
2670 | rc = lpfc_bsg_mbox_cmd(job); | 2986 | rc = lpfc_bsg_mbox_cmd(job); |
2671 | break; | 2987 | break; |
2988 | case LPFC_BSG_VENDOR_MENLO_CMD: | ||
2989 | case LPFC_BSG_VENDOR_MENLO_DATA: | ||
2990 | rc = lpfc_menlo_cmd(job); | ||
2991 | break; | ||
2672 | default: | 2992 | default: |
2673 | rc = -EINVAL; | 2993 | rc = -EINVAL; |
2674 | job->reply->reply_payload_rcv_len = 0; | 2994 | job->reply->reply_payload_rcv_len = 0; |
@@ -2728,6 +3048,7 @@ lpfc_bsg_timeout(struct fc_bsg_job *job) | |||
2728 | struct lpfc_bsg_event *evt; | 3048 | struct lpfc_bsg_event *evt; |
2729 | struct lpfc_bsg_iocb *iocb; | 3049 | struct lpfc_bsg_iocb *iocb; |
2730 | struct lpfc_bsg_mbox *mbox; | 3050 | struct lpfc_bsg_mbox *mbox; |
3051 | struct lpfc_bsg_menlo *menlo; | ||
2731 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; | 3052 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; |
2732 | struct bsg_job_data *dd_data; | 3053 | struct bsg_job_data *dd_data; |
2733 | unsigned long flags; | 3054 | unsigned long flags; |
@@ -2775,6 +3096,17 @@ lpfc_bsg_timeout(struct fc_bsg_job *job) | |||
2775 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); | 3096 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); |
2776 | job->job_done(job); | 3097 | job->job_done(job); |
2777 | break; | 3098 | break; |
3099 | case TYPE_MENLO: | ||
3100 | menlo = &dd_data->context_un.menlo; | ||
3101 | cmdiocb = menlo->cmdiocbq; | ||
3102 | /* hint to completion handler that the job timed out */ | ||
3103 | job->reply->result = -EAGAIN; | ||
3104 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); | ||
3105 | /* this will call our completion handler */ | ||
3106 | spin_lock_irq(&phba->hbalock); | ||
3107 | lpfc_sli_issue_abort_iotag(phba, pring, cmdiocb); | ||
3108 | spin_unlock_irq(&phba->hbalock); | ||
3109 | break; | ||
2778 | default: | 3110 | default: |
2779 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); | 3111 | spin_unlock_irqrestore(&phba->ct_ev_lock, flags); |
2780 | break; | 3112 | break; |
diff --git a/drivers/scsi/lpfc/lpfc_bsg.h b/drivers/scsi/lpfc/lpfc_bsg.h index 6c8f87e39b98..5bc630819b9e 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.h +++ b/drivers/scsi/lpfc/lpfc_bsg.h | |||
@@ -31,6 +31,8 @@ | |||
31 | #define LPFC_BSG_VENDOR_DIAG_TEST 5 | 31 | #define LPFC_BSG_VENDOR_DIAG_TEST 5 |
32 | #define LPFC_BSG_VENDOR_GET_MGMT_REV 6 | 32 | #define LPFC_BSG_VENDOR_GET_MGMT_REV 6 |
33 | #define LPFC_BSG_VENDOR_MBOX 7 | 33 | #define LPFC_BSG_VENDOR_MBOX 7 |
34 | #define LPFC_BSG_VENDOR_MENLO_CMD 8 | ||
35 | #define LPFC_BSG_VENDOR_MENLO_DATA 9 | ||
34 | 36 | ||
35 | struct set_ct_event { | 37 | struct set_ct_event { |
36 | uint32_t command; | 38 | uint32_t command; |
@@ -96,3 +98,13 @@ struct dfc_mbox_req { | |||
96 | uint8_t mbOffset; | 98 | uint8_t mbOffset; |
97 | }; | 99 | }; |
98 | 100 | ||
101 | /* Used for menlo command or menlo data. The xri is only used for menlo data */ | ||
102 | struct menlo_command { | ||
103 | uint32_t cmd; | ||
104 | uint32_t xri; | ||
105 | }; | ||
106 | |||
107 | struct menlo_response { | ||
108 | uint32_t xri; /* return the xri of the iocb exchange */ | ||
109 | }; | ||
110 | |||
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 6f0fb51eb461..5087c4211b43 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -63,6 +63,7 @@ void lpfc_linkdown_port(struct lpfc_vport *); | |||
63 | void lpfc_port_link_failure(struct lpfc_vport *); | 63 | void lpfc_port_link_failure(struct lpfc_vport *); |
64 | void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); | 64 | void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); |
65 | void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); | 65 | void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); |
66 | void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *); | ||
66 | void lpfc_retry_pport_discovery(struct lpfc_hba *); | 67 | void lpfc_retry_pport_discovery(struct lpfc_hba *); |
67 | 68 | ||
68 | void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | 69 | void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); |
@@ -221,6 +222,10 @@ void lpfc_unregister_fcf_rescan(struct lpfc_hba *); | |||
221 | void lpfc_unregister_unused_fcf(struct lpfc_hba *); | 222 | void lpfc_unregister_unused_fcf(struct lpfc_hba *); |
222 | int lpfc_sli4_redisc_fcf_table(struct lpfc_hba *); | 223 | int lpfc_sli4_redisc_fcf_table(struct lpfc_hba *); |
223 | void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *); | 224 | void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *); |
225 | void lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *); | ||
226 | uint16_t lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *); | ||
227 | int lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *, uint16_t); | ||
228 | void lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *, uint16_t); | ||
224 | 229 | ||
225 | int lpfc_mem_alloc(struct lpfc_hba *, int align); | 230 | int lpfc_mem_alloc(struct lpfc_hba *, int align); |
226 | void lpfc_mem_free(struct lpfc_hba *); | 231 | void lpfc_mem_free(struct lpfc_hba *); |
@@ -385,7 +390,7 @@ void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t); | |||
385 | int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); | 390 | int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); |
386 | void lpfc_start_fdiscs(struct lpfc_hba *phba); | 391 | void lpfc_start_fdiscs(struct lpfc_hba *phba); |
387 | struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t); | 392 | struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t); |
388 | 393 | struct lpfc_sglq *__lpfc_get_active_sglq(struct lpfc_hba *, uint16_t); | |
389 | #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) | 394 | #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) |
390 | #define HBA_EVENT_RSCN 5 | 395 | #define HBA_EVENT_RSCN 5 |
391 | #define HBA_EVENT_LINK_UP 2 | 396 | #define HBA_EVENT_LINK_UP 2 |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 2a40a6eabf4d..ee980bd66869 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -771,6 +771,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
771 | struct lpfc_nodelist *ndlp = cmdiocb->context1; | 771 | struct lpfc_nodelist *ndlp = cmdiocb->context1; |
772 | struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp; | 772 | struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp; |
773 | struct serv_parm *sp; | 773 | struct serv_parm *sp; |
774 | uint16_t fcf_index; | ||
774 | int rc; | 775 | int rc; |
775 | 776 | ||
776 | /* Check to see if link went down during discovery */ | 777 | /* Check to see if link went down during discovery */ |
@@ -788,6 +789,54 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
788 | vport->port_state); | 789 | vport->port_state); |
789 | 790 | ||
790 | if (irsp->ulpStatus) { | 791 | if (irsp->ulpStatus) { |
792 | /* | ||
793 | * In case of FIP mode, perform round robin FCF failover | ||
794 | * due to new FCF discovery | ||
795 | */ | ||
796 | if ((phba->hba_flag & HBA_FIP_SUPPORT) && | ||
797 | (phba->fcf.fcf_flag & FCF_DISCOVERY)) { | ||
798 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS, | ||
799 | "2611 FLOGI failed on registered " | ||
800 | "FCF record fcf_index:%d, trying " | ||
801 | "to perform round robin failover\n", | ||
802 | phba->fcf.current_rec.fcf_indx); | ||
803 | fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba); | ||
804 | if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) { | ||
805 | /* | ||
806 | * Exhausted the eligible FCF record list, | ||
807 | * fail through to retry FLOGI on current | ||
808 | * FCF record. | ||
809 | */ | ||
810 | lpfc_printf_log(phba, KERN_WARNING, | ||
811 | LOG_FIP | LOG_ELS, | ||
812 | "2760 FLOGI exhausted FCF " | ||
813 | "round robin failover list, " | ||
814 | "retry FLOGI on the current " | ||
815 | "registered FCF index:%d\n", | ||
816 | phba->fcf.current_rec.fcf_indx); | ||
817 | spin_lock_irq(&phba->hbalock); | ||
818 | phba->fcf.fcf_flag &= ~FCF_DISCOVERY; | ||
819 | spin_unlock_irq(&phba->hbalock); | ||
820 | } else { | ||
821 | rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba, | ||
822 | fcf_index); | ||
823 | if (rc) { | ||
824 | lpfc_printf_log(phba, KERN_WARNING, | ||
825 | LOG_FIP | LOG_ELS, | ||
826 | "2761 FLOGI round " | ||
827 | "robin FCF failover " | ||
828 | "read FCF failed " | ||
829 | "rc:x%x, fcf_index:" | ||
830 | "%d\n", rc, | ||
831 | phba->fcf.current_rec.fcf_indx); | ||
832 | spin_lock_irq(&phba->hbalock); | ||
833 | phba->fcf.fcf_flag &= ~FCF_DISCOVERY; | ||
834 | spin_unlock_irq(&phba->hbalock); | ||
835 | } else | ||
836 | goto out; | ||
837 | } | ||
838 | } | ||
839 | |||
791 | /* Check for retry */ | 840 | /* Check for retry */ |
792 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) | 841 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) |
793 | goto out; | 842 | goto out; |
@@ -806,9 +855,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
806 | } | 855 | } |
807 | 856 | ||
808 | /* FLOGI failure */ | 857 | /* FLOGI failure */ |
809 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, | 858 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
810 | "0100 FLOGI failure Data: x%x x%x " | 859 | "0100 FLOGI failure Status:x%x/x%x TMO:x%x\n", |
811 | "x%x\n", | ||
812 | irsp->ulpStatus, irsp->un.ulpWord[4], | 860 | irsp->ulpStatus, irsp->un.ulpWord[4], |
813 | irsp->ulpTimeout); | 861 | irsp->ulpTimeout); |
814 | goto flogifail; | 862 | goto flogifail; |
@@ -842,8 +890,18 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
842 | else | 890 | else |
843 | rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp); | 891 | rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp); |
844 | 892 | ||
845 | if (!rc) | 893 | if (!rc) { |
894 | /* Mark the FCF discovery process done */ | ||
895 | lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | LOG_ELS, | ||
896 | "2769 FLOGI successful on FCF record: " | ||
897 | "current_fcf_index:x%x, terminate FCF " | ||
898 | "round robin failover process\n", | ||
899 | phba->fcf.current_rec.fcf_indx); | ||
900 | spin_lock_irq(&phba->hbalock); | ||
901 | phba->fcf.fcf_flag &= ~FCF_DISCOVERY; | ||
902 | spin_unlock_irq(&phba->hbalock); | ||
846 | goto out; | 903 | goto out; |
904 | } | ||
847 | } | 905 | } |
848 | 906 | ||
849 | flogifail: | 907 | flogifail: |
@@ -1409,6 +1467,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1409 | goto out; | 1467 | goto out; |
1410 | } | 1468 | } |
1411 | /* PLOGI failed */ | 1469 | /* PLOGI failed */ |
1470 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
1471 | "2753 PLOGI failure DID:%06X Status:x%x/x%x\n", | ||
1472 | ndlp->nlp_DID, irsp->ulpStatus, | ||
1473 | irsp->un.ulpWord[4]); | ||
1412 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1474 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1413 | if (lpfc_error_lost_link(irsp)) | 1475 | if (lpfc_error_lost_link(irsp)) |
1414 | rc = NLP_STE_FREED_NODE; | 1476 | rc = NLP_STE_FREED_NODE; |
@@ -1577,6 +1639,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1577 | goto out; | 1639 | goto out; |
1578 | } | 1640 | } |
1579 | /* PRLI failed */ | 1641 | /* PRLI failed */ |
1642 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
1643 | "2754 PRLI failure DID:%06X Status:x%x/x%x\n", | ||
1644 | ndlp->nlp_DID, irsp->ulpStatus, | ||
1645 | irsp->un.ulpWord[4]); | ||
1580 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1646 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1581 | if (lpfc_error_lost_link(irsp)) | 1647 | if (lpfc_error_lost_link(irsp)) |
1582 | goto out; | 1648 | goto out; |
@@ -1860,6 +1926,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1860 | goto out; | 1926 | goto out; |
1861 | } | 1927 | } |
1862 | /* ADISC failed */ | 1928 | /* ADISC failed */ |
1929 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
1930 | "2755 ADISC failure DID:%06X Status:x%x/x%x\n", | ||
1931 | ndlp->nlp_DID, irsp->ulpStatus, | ||
1932 | irsp->un.ulpWord[4]); | ||
1863 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1933 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1864 | if (!lpfc_error_lost_link(irsp)) | 1934 | if (!lpfc_error_lost_link(irsp)) |
1865 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 1935 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
@@ -2009,6 +2079,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2009 | /* ELS command is being retried */ | 2079 | /* ELS command is being retried */ |
2010 | goto out; | 2080 | goto out; |
2011 | /* LOGO failed */ | 2081 | /* LOGO failed */ |
2082 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
2083 | "2756 LOGO failure DID:%06X Status:x%x/x%x\n", | ||
2084 | ndlp->nlp_DID, irsp->ulpStatus, | ||
2085 | irsp->un.ulpWord[4]); | ||
2012 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 2086 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
2013 | if (lpfc_error_lost_link(irsp)) | 2087 | if (lpfc_error_lost_link(irsp)) |
2014 | goto out; | 2088 | goto out; |
@@ -5989,7 +6063,12 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
5989 | if (phba->sli_rev < LPFC_SLI_REV4) | 6063 | if (phba->sli_rev < LPFC_SLI_REV4) |
5990 | lpfc_issue_fabric_reglogin(vport); | 6064 | lpfc_issue_fabric_reglogin(vport); |
5991 | else { | 6065 | else { |
5992 | lpfc_start_fdiscs(phba); | 6066 | /* |
6067 | * If the physical port is instantiated using | ||
6068 | * FDISC, do not start vport discovery. | ||
6069 | */ | ||
6070 | if (vport->port_state != LPFC_FDISC) | ||
6071 | lpfc_start_fdiscs(phba); | ||
5993 | lpfc_do_scr_ns_plogi(phba, vport); | 6072 | lpfc_do_scr_ns_plogi(phba, vport); |
5994 | } | 6073 | } |
5995 | } else | 6074 | } else |
@@ -6055,21 +6134,18 @@ mbox_err_exit: | |||
6055 | } | 6134 | } |
6056 | 6135 | ||
6057 | /** | 6136 | /** |
6058 | * lpfc_retry_pport_discovery - Start timer to retry FLOGI. | 6137 | * lpfc_cancel_all_vport_retry_delay_timer - Cancel all vport retry delay timer |
6059 | * @phba: pointer to lpfc hba data structure. | 6138 | * @phba: pointer to lpfc hba data structure. |
6060 | * | 6139 | * |
6061 | * This routine abort all pending discovery commands and | 6140 | * This routine cancels the retry delay timers to all the vports. |
6062 | * start a timer to retry FLOGI for the physical port | ||
6063 | * discovery. | ||
6064 | **/ | 6141 | **/ |
6065 | void | 6142 | void |
6066 | lpfc_retry_pport_discovery(struct lpfc_hba *phba) | 6143 | lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba) |
6067 | { | 6144 | { |
6068 | struct lpfc_vport **vports; | 6145 | struct lpfc_vport **vports; |
6069 | struct lpfc_nodelist *ndlp; | 6146 | struct lpfc_nodelist *ndlp; |
6070 | struct Scsi_Host *shost; | ||
6071 | int i; | ||
6072 | uint32_t link_state; | 6147 | uint32_t link_state; |
6148 | int i; | ||
6073 | 6149 | ||
6074 | /* Treat this failure as linkdown for all vports */ | 6150 | /* Treat this failure as linkdown for all vports */ |
6075 | link_state = phba->link_state; | 6151 | link_state = phba->link_state; |
@@ -6087,13 +6163,30 @@ lpfc_retry_pport_discovery(struct lpfc_hba *phba) | |||
6087 | } | 6163 | } |
6088 | lpfc_destroy_vport_work_array(phba, vports); | 6164 | lpfc_destroy_vport_work_array(phba, vports); |
6089 | } | 6165 | } |
6166 | } | ||
6167 | |||
6168 | /** | ||
6169 | * lpfc_retry_pport_discovery - Start timer to retry FLOGI. | ||
6170 | * @phba: pointer to lpfc hba data structure. | ||
6171 | * | ||
6172 | * This routine abort all pending discovery commands and | ||
6173 | * start a timer to retry FLOGI for the physical port | ||
6174 | * discovery. | ||
6175 | **/ | ||
6176 | void | ||
6177 | lpfc_retry_pport_discovery(struct lpfc_hba *phba) | ||
6178 | { | ||
6179 | struct lpfc_nodelist *ndlp; | ||
6180 | struct Scsi_Host *shost; | ||
6181 | |||
6182 | /* Cancel the all vports retry delay retry timers */ | ||
6183 | lpfc_cancel_all_vport_retry_delay_timer(phba); | ||
6090 | 6184 | ||
6091 | /* If fabric require FLOGI, then re-instantiate physical login */ | 6185 | /* If fabric require FLOGI, then re-instantiate physical login */ |
6092 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); | 6186 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); |
6093 | if (!ndlp) | 6187 | if (!ndlp) |
6094 | return; | 6188 | return; |
6095 | 6189 | ||
6096 | |||
6097 | shost = lpfc_shost_from_vport(phba->pport); | 6190 | shost = lpfc_shost_from_vport(phba->pport); |
6098 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 6191 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
6099 | spin_lock_irq(shost->host_lock); | 6192 | spin_lock_irq(shost->host_lock); |
@@ -6219,7 +6312,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
6219 | lpfc_mbx_unreg_vpi(vport); | 6312 | lpfc_mbx_unreg_vpi(vport); |
6220 | spin_lock_irq(shost->host_lock); | 6313 | spin_lock_irq(shost->host_lock); |
6221 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 6314 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
6222 | vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | 6315 | if (phba->sli_rev == LPFC_SLI_REV4) |
6316 | vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | ||
6223 | spin_unlock_irq(shost->host_lock); | 6317 | spin_unlock_irq(shost->host_lock); |
6224 | } | 6318 | } |
6225 | 6319 | ||
@@ -6797,21 +6891,27 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, | |||
6797 | struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; | 6891 | struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; |
6798 | unsigned long iflag = 0; | 6892 | unsigned long iflag = 0; |
6799 | 6893 | ||
6800 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag); | 6894 | spin_lock_irqsave(&phba->hbalock, iflag); |
6895 | spin_lock(&phba->sli4_hba.abts_sgl_list_lock); | ||
6801 | list_for_each_entry_safe(sglq_entry, sglq_next, | 6896 | list_for_each_entry_safe(sglq_entry, sglq_next, |
6802 | &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { | 6897 | &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { |
6803 | if (sglq_entry->sli4_xritag == xri) { | 6898 | if (sglq_entry->sli4_xritag == xri) { |
6804 | list_del(&sglq_entry->list); | 6899 | list_del(&sglq_entry->list); |
6805 | spin_unlock_irqrestore( | ||
6806 | &phba->sli4_hba.abts_sgl_list_lock, | ||
6807 | iflag); | ||
6808 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
6809 | |||
6810 | list_add_tail(&sglq_entry->list, | 6900 | list_add_tail(&sglq_entry->list, |
6811 | &phba->sli4_hba.lpfc_sgl_list); | 6901 | &phba->sli4_hba.lpfc_sgl_list); |
6902 | sglq_entry->state = SGL_FREED; | ||
6903 | spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); | ||
6812 | spin_unlock_irqrestore(&phba->hbalock, iflag); | 6904 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
6813 | return; | 6905 | return; |
6814 | } | 6906 | } |
6815 | } | 6907 | } |
6816 | spin_unlock_irqrestore(&phba->sli4_hba.abts_sgl_list_lock, iflag); | 6908 | spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); |
6909 | sglq_entry = __lpfc_get_active_sglq(phba, xri); | ||
6910 | if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) { | ||
6911 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
6912 | return; | ||
6913 | } | ||
6914 | sglq_entry->state = SGL_XRI_ABORTED; | ||
6915 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
6916 | return; | ||
6817 | } | 6917 | } |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 2359d0bfb734..c555e3b7f202 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1481,8 +1481,6 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba, | |||
1481 | int | 1481 | int |
1482 | lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) | 1482 | lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) |
1483 | { | 1483 | { |
1484 | LPFC_MBOXQ_t *mbox; | ||
1485 | int rc; | ||
1486 | /* | 1484 | /* |
1487 | * If the Link is up and no FCoE events while in the | 1485 | * If the Link is up and no FCoE events while in the |
1488 | * FCF discovery, no need to restart FCF discovery. | 1486 | * FCF discovery, no need to restart FCF discovery. |
@@ -1491,86 +1489,70 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) | |||
1491 | (phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan)) | 1489 | (phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan)) |
1492 | return 0; | 1490 | return 0; |
1493 | 1491 | ||
1492 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
1493 | "2768 Pending link or FCF event during current " | ||
1494 | "handling of the previous event: link_state:x%x, " | ||
1495 | "evt_tag_at_scan:x%x, evt_tag_current:x%x\n", | ||
1496 | phba->link_state, phba->fcoe_eventtag_at_fcf_scan, | ||
1497 | phba->fcoe_eventtag); | ||
1498 | |||
1494 | spin_lock_irq(&phba->hbalock); | 1499 | spin_lock_irq(&phba->hbalock); |
1495 | phba->fcf.fcf_flag &= ~FCF_AVAILABLE; | 1500 | phba->fcf.fcf_flag &= ~FCF_AVAILABLE; |
1496 | spin_unlock_irq(&phba->hbalock); | 1501 | spin_unlock_irq(&phba->hbalock); |
1497 | 1502 | ||
1498 | if (phba->link_state >= LPFC_LINK_UP) | 1503 | if (phba->link_state >= LPFC_LINK_UP) { |
1499 | lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | 1504 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, |
1500 | else { | 1505 | "2780 Restart FCF table scan due to " |
1506 | "pending FCF event:evt_tag_at_scan:x%x, " | ||
1507 | "evt_tag_current:x%x\n", | ||
1508 | phba->fcoe_eventtag_at_fcf_scan, | ||
1509 | phba->fcoe_eventtag); | ||
1510 | lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); | ||
1511 | } else { | ||
1501 | /* | 1512 | /* |
1502 | * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS | 1513 | * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS |
1503 | * flag | 1514 | * flag |
1504 | */ | 1515 | */ |
1505 | spin_lock_irq(&phba->hbalock); | 1516 | spin_lock_irq(&phba->hbalock); |
1506 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1517 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
1507 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; | 1518 | phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | FCF_DISCOVERY); |
1508 | spin_unlock_irq(&phba->hbalock); | 1519 | spin_unlock_irq(&phba->hbalock); |
1509 | } | 1520 | } |
1510 | 1521 | ||
1522 | /* Unregister the currently registered FCF if required */ | ||
1511 | if (unreg_fcf) { | 1523 | if (unreg_fcf) { |
1512 | spin_lock_irq(&phba->hbalock); | 1524 | spin_lock_irq(&phba->hbalock); |
1513 | phba->fcf.fcf_flag &= ~FCF_REGISTERED; | 1525 | phba->fcf.fcf_flag &= ~FCF_REGISTERED; |
1514 | spin_unlock_irq(&phba->hbalock); | 1526 | spin_unlock_irq(&phba->hbalock); |
1515 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 1527 | lpfc_sli4_unregister_fcf(phba); |
1516 | if (!mbox) { | ||
1517 | lpfc_printf_log(phba, KERN_ERR, | ||
1518 | LOG_DISCOVERY|LOG_MBOX, | ||
1519 | "2610 UNREG_FCFI mbox allocation failed\n"); | ||
1520 | return 1; | ||
1521 | } | ||
1522 | lpfc_unreg_fcfi(mbox, phba->fcf.fcfi); | ||
1523 | mbox->vport = phba->pport; | ||
1524 | mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl; | ||
1525 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
1526 | if (rc == MBX_NOT_FINISHED) { | ||
1527 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
1528 | "2611 UNREG_FCFI issue mbox failed\n"); | ||
1529 | mempool_free(mbox, phba->mbox_mem_pool); | ||
1530 | } | ||
1531 | } | 1528 | } |
1532 | |||
1533 | return 1; | 1529 | return 1; |
1534 | } | 1530 | } |
1535 | 1531 | ||
1536 | /** | 1532 | /** |
1537 | * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox. | 1533 | * lpfc_sli4_fcf_rec_mbox_parse - parse non-embedded fcf record mailbox command |
1538 | * @phba: pointer to lpfc hba data structure. | 1534 | * @phba: pointer to lpfc hba data structure. |
1539 | * @mboxq: pointer to mailbox object. | 1535 | * @mboxq: pointer to mailbox object. |
1536 | * @next_fcf_index: pointer to holder of next fcf index. | ||
1540 | * | 1537 | * |
1541 | * This function iterate through all the fcf records available in | 1538 | * This routine parses the non-embedded fcf mailbox command by performing the |
1542 | * HBA and choose the optimal FCF record for discovery. After finding | 1539 | * necessarily error checking, non-embedded read FCF record mailbox command |
1543 | * the FCF for discovery it register the FCF record and kick start | 1540 | * SGE parsing, and endianness swapping. |
1544 | * discovery. | 1541 | * |
1545 | * If FCF_IN_USE flag is set in currently used FCF, the routine try to | 1542 | * Returns the pointer to the new FCF record in the non-embedded mailbox |
1546 | * use a FCF record which match fabric name and mac address of the | 1543 | * command DMA memory if successfully, other NULL. |
1547 | * currently used FCF record. | ||
1548 | * If the driver support only one FCF, it will try to use the FCF record | ||
1549 | * used by BOOT_BIOS. | ||
1550 | */ | 1544 | */ |
1551 | void | 1545 | static struct fcf_record * |
1552 | lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | 1546 | lpfc_sli4_fcf_rec_mbox_parse(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, |
1547 | uint16_t *next_fcf_index) | ||
1553 | { | 1548 | { |
1554 | void *virt_addr; | 1549 | void *virt_addr; |
1555 | dma_addr_t phys_addr; | 1550 | dma_addr_t phys_addr; |
1556 | uint8_t *bytep; | ||
1557 | struct lpfc_mbx_sge sge; | 1551 | struct lpfc_mbx_sge sge; |
1558 | struct lpfc_mbx_read_fcf_tbl *read_fcf; | 1552 | struct lpfc_mbx_read_fcf_tbl *read_fcf; |
1559 | uint32_t shdr_status, shdr_add_status; | 1553 | uint32_t shdr_status, shdr_add_status; |
1560 | union lpfc_sli4_cfg_shdr *shdr; | 1554 | union lpfc_sli4_cfg_shdr *shdr; |
1561 | struct fcf_record *new_fcf_record; | 1555 | struct fcf_record *new_fcf_record; |
1562 | uint32_t boot_flag, addr_mode; | ||
1563 | uint32_t next_fcf_index; | ||
1564 | struct lpfc_fcf_rec *fcf_rec = NULL; | ||
1565 | unsigned long iflags; | ||
1566 | uint16_t vlan_id; | ||
1567 | int rc; | ||
1568 | |||
1569 | /* If there is pending FCoE event restart FCF table scan */ | ||
1570 | if (lpfc_check_pending_fcoe_event(phba, 0)) { | ||
1571 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1572 | return; | ||
1573 | } | ||
1574 | 1556 | ||
1575 | /* Get the first SGE entry from the non-embedded DMA memory. This | 1557 | /* Get the first SGE entry from the non-embedded DMA memory. This |
1576 | * routine only uses a single SGE. | 1558 | * routine only uses a single SGE. |
@@ -1581,59 +1563,183 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1581 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | 1563 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, |
1582 | "2524 Failed to get the non-embedded SGE " | 1564 | "2524 Failed to get the non-embedded SGE " |
1583 | "virtual address\n"); | 1565 | "virtual address\n"); |
1584 | goto out; | 1566 | return NULL; |
1585 | } | 1567 | } |
1586 | virt_addr = mboxq->sge_array->addr[0]; | 1568 | virt_addr = mboxq->sge_array->addr[0]; |
1587 | 1569 | ||
1588 | shdr = (union lpfc_sli4_cfg_shdr *)virt_addr; | 1570 | shdr = (union lpfc_sli4_cfg_shdr *)virt_addr; |
1589 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | 1571 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); |
1590 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | 1572 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); |
1591 | &shdr->response); | ||
1592 | /* | ||
1593 | * The FCF Record was read and there is no reason for the driver | ||
1594 | * to maintain the FCF record data or memory. Instead, just need | ||
1595 | * to book keeping the FCFIs can be used. | ||
1596 | */ | ||
1597 | if (shdr_status || shdr_add_status) { | 1573 | if (shdr_status || shdr_add_status) { |
1598 | if (shdr_status == STATUS_FCF_TABLE_EMPTY) { | 1574 | if (shdr_status == STATUS_FCF_TABLE_EMPTY) |
1599 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1575 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP, |
1600 | "2726 READ_FCF_RECORD Indicates empty " | 1576 | "2726 READ_FCF_RECORD Indicates empty " |
1601 | "FCF table.\n"); | 1577 | "FCF table.\n"); |
1602 | } else { | 1578 | else |
1603 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1579 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP, |
1604 | "2521 READ_FCF_RECORD mailbox failed " | 1580 | "2521 READ_FCF_RECORD mailbox failed " |
1605 | "with status x%x add_status x%x, mbx\n", | 1581 | "with status x%x add_status x%x, " |
1606 | shdr_status, shdr_add_status); | 1582 | "mbx\n", shdr_status, shdr_add_status); |
1607 | } | 1583 | return NULL; |
1608 | goto out; | ||
1609 | } | 1584 | } |
1610 | /* Interpreting the returned information of FCF records */ | 1585 | |
1586 | /* Interpreting the returned information of the FCF record */ | ||
1611 | read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; | 1587 | read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; |
1612 | lpfc_sli_pcimem_bcopy(read_fcf, read_fcf, | 1588 | lpfc_sli_pcimem_bcopy(read_fcf, read_fcf, |
1613 | sizeof(struct lpfc_mbx_read_fcf_tbl)); | 1589 | sizeof(struct lpfc_mbx_read_fcf_tbl)); |
1614 | next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf); | 1590 | *next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf); |
1615 | |||
1616 | new_fcf_record = (struct fcf_record *)(virt_addr + | 1591 | new_fcf_record = (struct fcf_record *)(virt_addr + |
1617 | sizeof(struct lpfc_mbx_read_fcf_tbl)); | 1592 | sizeof(struct lpfc_mbx_read_fcf_tbl)); |
1618 | lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record, | 1593 | lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record, |
1619 | sizeof(struct fcf_record)); | 1594 | sizeof(struct fcf_record)); |
1620 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | ||
1621 | 1595 | ||
1596 | return new_fcf_record; | ||
1597 | } | ||
1598 | |||
1599 | /** | ||
1600 | * lpfc_sli4_log_fcf_record_info - Log the information of a fcf record | ||
1601 | * @phba: pointer to lpfc hba data structure. | ||
1602 | * @fcf_record: pointer to the fcf record. | ||
1603 | * @vlan_id: the lowest vlan identifier associated to this fcf record. | ||
1604 | * @next_fcf_index: the index to the next fcf record in hba's fcf table. | ||
1605 | * | ||
1606 | * This routine logs the detailed FCF record if the LOG_FIP loggin is | ||
1607 | * enabled. | ||
1608 | **/ | ||
1609 | static void | ||
1610 | lpfc_sli4_log_fcf_record_info(struct lpfc_hba *phba, | ||
1611 | struct fcf_record *fcf_record, | ||
1612 | uint16_t vlan_id, | ||
1613 | uint16_t next_fcf_index) | ||
1614 | { | ||
1615 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
1616 | "2764 READ_FCF_RECORD:\n" | ||
1617 | "\tFCF_Index : x%x\n" | ||
1618 | "\tFCF_Avail : x%x\n" | ||
1619 | "\tFCF_Valid : x%x\n" | ||
1620 | "\tFIP_Priority : x%x\n" | ||
1621 | "\tMAC_Provider : x%x\n" | ||
1622 | "\tLowest VLANID : x%x\n" | ||
1623 | "\tFCF_MAC Addr : x%x:%x:%x:%x:%x:%x\n" | ||
1624 | "\tFabric_Name : x%x:%x:%x:%x:%x:%x:%x:%x\n" | ||
1625 | "\tSwitch_Name : x%x:%x:%x:%x:%x:%x:%x:%x\n" | ||
1626 | "\tNext_FCF_Index: x%x\n", | ||
1627 | bf_get(lpfc_fcf_record_fcf_index, fcf_record), | ||
1628 | bf_get(lpfc_fcf_record_fcf_avail, fcf_record), | ||
1629 | bf_get(lpfc_fcf_record_fcf_valid, fcf_record), | ||
1630 | fcf_record->fip_priority, | ||
1631 | bf_get(lpfc_fcf_record_mac_addr_prov, fcf_record), | ||
1632 | vlan_id, | ||
1633 | bf_get(lpfc_fcf_record_mac_0, fcf_record), | ||
1634 | bf_get(lpfc_fcf_record_mac_1, fcf_record), | ||
1635 | bf_get(lpfc_fcf_record_mac_2, fcf_record), | ||
1636 | bf_get(lpfc_fcf_record_mac_3, fcf_record), | ||
1637 | bf_get(lpfc_fcf_record_mac_4, fcf_record), | ||
1638 | bf_get(lpfc_fcf_record_mac_5, fcf_record), | ||
1639 | bf_get(lpfc_fcf_record_fab_name_0, fcf_record), | ||
1640 | bf_get(lpfc_fcf_record_fab_name_1, fcf_record), | ||
1641 | bf_get(lpfc_fcf_record_fab_name_2, fcf_record), | ||
1642 | bf_get(lpfc_fcf_record_fab_name_3, fcf_record), | ||
1643 | bf_get(lpfc_fcf_record_fab_name_4, fcf_record), | ||
1644 | bf_get(lpfc_fcf_record_fab_name_5, fcf_record), | ||
1645 | bf_get(lpfc_fcf_record_fab_name_6, fcf_record), | ||
1646 | bf_get(lpfc_fcf_record_fab_name_7, fcf_record), | ||
1647 | bf_get(lpfc_fcf_record_switch_name_0, fcf_record), | ||
1648 | bf_get(lpfc_fcf_record_switch_name_1, fcf_record), | ||
1649 | bf_get(lpfc_fcf_record_switch_name_2, fcf_record), | ||
1650 | bf_get(lpfc_fcf_record_switch_name_3, fcf_record), | ||
1651 | bf_get(lpfc_fcf_record_switch_name_4, fcf_record), | ||
1652 | bf_get(lpfc_fcf_record_switch_name_5, fcf_record), | ||
1653 | bf_get(lpfc_fcf_record_switch_name_6, fcf_record), | ||
1654 | bf_get(lpfc_fcf_record_switch_name_7, fcf_record), | ||
1655 | next_fcf_index); | ||
1656 | } | ||
1657 | |||
1658 | /** | ||
1659 | * lpfc_mbx_cmpl_fcf_scan_read_fcf_rec - fcf scan read_fcf mbox cmpl handler. | ||
1660 | * @phba: pointer to lpfc hba data structure. | ||
1661 | * @mboxq: pointer to mailbox object. | ||
1662 | * | ||
1663 | * This function iterates through all the fcf records available in | ||
1664 | * HBA and chooses the optimal FCF record for discovery. After finding | ||
1665 | * the FCF for discovery it registers the FCF record and kicks start | ||
1666 | * discovery. | ||
1667 | * If FCF_IN_USE flag is set in currently used FCF, the routine tries to | ||
1668 | * use an FCF record which matches fabric name and mac address of the | ||
1669 | * currently used FCF record. | ||
1670 | * If the driver supports only one FCF, it will try to use the FCF record | ||
1671 | * used by BOOT_BIOS. | ||
1672 | */ | ||
1673 | void | ||
1674 | lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
1675 | { | ||
1676 | struct fcf_record *new_fcf_record; | ||
1677 | uint32_t boot_flag, addr_mode; | ||
1678 | uint16_t fcf_index, next_fcf_index; | ||
1679 | struct lpfc_fcf_rec *fcf_rec = NULL; | ||
1680 | uint16_t vlan_id; | ||
1681 | int rc; | ||
1682 | |||
1683 | /* If there is pending FCoE event restart FCF table scan */ | ||
1684 | if (lpfc_check_pending_fcoe_event(phba, 0)) { | ||
1685 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1686 | return; | ||
1687 | } | ||
1688 | |||
1689 | /* Parse the FCF record from the non-embedded mailbox command */ | ||
1690 | new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq, | ||
1691 | &next_fcf_index); | ||
1692 | if (!new_fcf_record) { | ||
1693 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, | ||
1694 | "2765 Mailbox command READ_FCF_RECORD " | ||
1695 | "failed to retrieve a FCF record.\n"); | ||
1696 | /* Let next new FCF event trigger fast failover */ | ||
1697 | spin_lock_irq(&phba->hbalock); | ||
1698 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | ||
1699 | spin_unlock_irq(&phba->hbalock); | ||
1700 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1701 | return; | ||
1702 | } | ||
1703 | |||
1704 | /* Check the FCF record against the connection list */ | ||
1622 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, | 1705 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, |
1623 | &addr_mode, &vlan_id); | 1706 | &addr_mode, &vlan_id); |
1707 | |||
1708 | /* Log the FCF record information if turned on */ | ||
1709 | lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id, | ||
1710 | next_fcf_index); | ||
1711 | |||
1624 | /* | 1712 | /* |
1625 | * If the fcf record does not match with connect list entries | 1713 | * If the fcf record does not match with connect list entries |
1626 | * read the next entry. | 1714 | * read the next entry; otherwise, this is an eligible FCF |
1715 | * record for round robin FCF failover. | ||
1627 | */ | 1716 | */ |
1628 | if (!rc) | 1717 | if (!rc) { |
1718 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, | ||
1719 | "2781 FCF record fcf_index:x%x failed FCF " | ||
1720 | "connection list check, fcf_avail:x%x, " | ||
1721 | "fcf_valid:x%x\n", | ||
1722 | bf_get(lpfc_fcf_record_fcf_index, | ||
1723 | new_fcf_record), | ||
1724 | bf_get(lpfc_fcf_record_fcf_avail, | ||
1725 | new_fcf_record), | ||
1726 | bf_get(lpfc_fcf_record_fcf_valid, | ||
1727 | new_fcf_record)); | ||
1629 | goto read_next_fcf; | 1728 | goto read_next_fcf; |
1729 | } else { | ||
1730 | fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); | ||
1731 | rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index); | ||
1732 | if (rc) | ||
1733 | goto read_next_fcf; | ||
1734 | } | ||
1735 | |||
1630 | /* | 1736 | /* |
1631 | * If this is not the first FCF discovery of the HBA, use last | 1737 | * If this is not the first FCF discovery of the HBA, use last |
1632 | * FCF record for the discovery. The condition that a rescan | 1738 | * FCF record for the discovery. The condition that a rescan |
1633 | * matches the in-use FCF record: fabric name, switch name, mac | 1739 | * matches the in-use FCF record: fabric name, switch name, mac |
1634 | * address, and vlan_id. | 1740 | * address, and vlan_id. |
1635 | */ | 1741 | */ |
1636 | spin_lock_irqsave(&phba->hbalock, iflags); | 1742 | spin_lock_irq(&phba->hbalock); |
1637 | if (phba->fcf.fcf_flag & FCF_IN_USE) { | 1743 | if (phba->fcf.fcf_flag & FCF_IN_USE) { |
1638 | if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, | 1744 | if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, |
1639 | new_fcf_record) && | 1745 | new_fcf_record) && |
@@ -1649,8 +1755,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1649 | __lpfc_sli4_stop_fcf_redisc_wait_timer(phba); | 1755 | __lpfc_sli4_stop_fcf_redisc_wait_timer(phba); |
1650 | else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) | 1756 | else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) |
1651 | /* If in fast failover, mark it's completed */ | 1757 | /* If in fast failover, mark it's completed */ |
1652 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; | 1758 | phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | |
1653 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1759 | FCF_DISCOVERY); |
1760 | spin_unlock_irq(&phba->hbalock); | ||
1654 | goto out; | 1761 | goto out; |
1655 | } | 1762 | } |
1656 | /* | 1763 | /* |
@@ -1661,7 +1768,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1661 | * next candidate. | 1768 | * next candidate. |
1662 | */ | 1769 | */ |
1663 | if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) { | 1770 | if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) { |
1664 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1771 | spin_unlock_irq(&phba->hbalock); |
1665 | goto read_next_fcf; | 1772 | goto read_next_fcf; |
1666 | } | 1773 | } |
1667 | } | 1774 | } |
@@ -1669,14 +1776,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1669 | * Update on failover FCF record only if it's in FCF fast-failover | 1776 | * Update on failover FCF record only if it's in FCF fast-failover |
1670 | * period; otherwise, update on current FCF record. | 1777 | * period; otherwise, update on current FCF record. |
1671 | */ | 1778 | */ |
1672 | if (phba->fcf.fcf_flag & FCF_REDISC_FOV) { | 1779 | if (phba->fcf.fcf_flag & FCF_REDISC_FOV) |
1673 | /* Fast FCF failover only to the same fabric name */ | 1780 | fcf_rec = &phba->fcf.failover_rec; |
1674 | if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, | 1781 | else |
1675 | new_fcf_record)) | ||
1676 | fcf_rec = &phba->fcf.failover_rec; | ||
1677 | else | ||
1678 | goto read_next_fcf; | ||
1679 | } else | ||
1680 | fcf_rec = &phba->fcf.current_rec; | 1782 | fcf_rec = &phba->fcf.current_rec; |
1681 | 1783 | ||
1682 | if (phba->fcf.fcf_flag & FCF_AVAILABLE) { | 1784 | if (phba->fcf.fcf_flag & FCF_AVAILABLE) { |
@@ -1689,7 +1791,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1689 | /* Choose this FCF record */ | 1791 | /* Choose this FCF record */ |
1690 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, | 1792 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
1691 | addr_mode, vlan_id, BOOT_ENABLE); | 1793 | addr_mode, vlan_id, BOOT_ENABLE); |
1692 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1794 | spin_unlock_irq(&phba->hbalock); |
1693 | goto read_next_fcf; | 1795 | goto read_next_fcf; |
1694 | } | 1796 | } |
1695 | /* | 1797 | /* |
@@ -1698,20 +1800,19 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1698 | * the next FCF record. | 1800 | * the next FCF record. |
1699 | */ | 1801 | */ |
1700 | if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) { | 1802 | if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) { |
1701 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1803 | spin_unlock_irq(&phba->hbalock); |
1702 | goto read_next_fcf; | 1804 | goto read_next_fcf; |
1703 | } | 1805 | } |
1704 | /* | 1806 | /* |
1705 | * If the new hba FCF record has lower priority value | 1807 | * If the new hba FCF record has lower priority value |
1706 | * than the driver FCF record, use the new record. | 1808 | * than the driver FCF record, use the new record. |
1707 | */ | 1809 | */ |
1708 | if (lpfc_fab_name_match(fcf_rec->fabric_name, new_fcf_record) && | 1810 | if (new_fcf_record->fip_priority < fcf_rec->priority) { |
1709 | (new_fcf_record->fip_priority < fcf_rec->priority)) { | ||
1710 | /* Choose this FCF record */ | 1811 | /* Choose this FCF record */ |
1711 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, | 1812 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
1712 | addr_mode, vlan_id, 0); | 1813 | addr_mode, vlan_id, 0); |
1713 | } | 1814 | } |
1714 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1815 | spin_unlock_irq(&phba->hbalock); |
1715 | goto read_next_fcf; | 1816 | goto read_next_fcf; |
1716 | } | 1817 | } |
1717 | /* | 1818 | /* |
@@ -1724,7 +1825,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1724 | BOOT_ENABLE : 0)); | 1825 | BOOT_ENABLE : 0)); |
1725 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | 1826 | phba->fcf.fcf_flag |= FCF_AVAILABLE; |
1726 | } | 1827 | } |
1727 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1828 | spin_unlock_irq(&phba->hbalock); |
1728 | goto read_next_fcf; | 1829 | goto read_next_fcf; |
1729 | 1830 | ||
1730 | read_next_fcf: | 1831 | read_next_fcf: |
@@ -1740,9 +1841,22 @@ read_next_fcf: | |||
1740 | * FCF scan inprogress, and do nothing | 1841 | * FCF scan inprogress, and do nothing |
1741 | */ | 1842 | */ |
1742 | if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) { | 1843 | if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) { |
1743 | spin_lock_irqsave(&phba->hbalock, iflags); | 1844 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, |
1845 | "2782 No suitable FCF record " | ||
1846 | "found during this round of " | ||
1847 | "post FCF rediscovery scan: " | ||
1848 | "fcf_evt_tag:x%x, fcf_index: " | ||
1849 | "x%x\n", | ||
1850 | phba->fcoe_eventtag_at_fcf_scan, | ||
1851 | bf_get(lpfc_fcf_record_fcf_index, | ||
1852 | new_fcf_record)); | ||
1853 | /* | ||
1854 | * Let next new FCF event trigger fast | ||
1855 | * failover | ||
1856 | */ | ||
1857 | spin_lock_irq(&phba->hbalock); | ||
1744 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1858 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
1745 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1859 | spin_unlock_irq(&phba->hbalock); |
1746 | return; | 1860 | return; |
1747 | } | 1861 | } |
1748 | /* | 1862 | /* |
@@ -1754,16 +1868,23 @@ read_next_fcf: | |||
1754 | * record. | 1868 | * record. |
1755 | */ | 1869 | */ |
1756 | 1870 | ||
1757 | /* unregister the current in-use FCF record */ | 1871 | /* Unregister the current in-use FCF record */ |
1758 | lpfc_unregister_fcf(phba); | 1872 | lpfc_unregister_fcf(phba); |
1759 | /* replace in-use record with the new record */ | 1873 | |
1874 | /* Replace in-use record with the new record */ | ||
1760 | memcpy(&phba->fcf.current_rec, | 1875 | memcpy(&phba->fcf.current_rec, |
1761 | &phba->fcf.failover_rec, | 1876 | &phba->fcf.failover_rec, |
1762 | sizeof(struct lpfc_fcf_rec)); | 1877 | sizeof(struct lpfc_fcf_rec)); |
1763 | /* mark the FCF fast failover completed */ | 1878 | /* mark the FCF fast failover completed */ |
1764 | spin_lock_irqsave(&phba->hbalock, iflags); | 1879 | spin_lock_irq(&phba->hbalock); |
1765 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; | 1880 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; |
1766 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 1881 | spin_unlock_irq(&phba->hbalock); |
1882 | /* | ||
1883 | * Set up the initial registered FCF index for FLOGI | ||
1884 | * round robin FCF failover. | ||
1885 | */ | ||
1886 | phba->fcf.fcf_rr_init_indx = | ||
1887 | phba->fcf.failover_rec.fcf_indx; | ||
1767 | /* Register to the new FCF record */ | 1888 | /* Register to the new FCF record */ |
1768 | lpfc_register_fcf(phba); | 1889 | lpfc_register_fcf(phba); |
1769 | } else { | 1890 | } else { |
@@ -1776,13 +1897,25 @@ read_next_fcf: | |||
1776 | return; | 1897 | return; |
1777 | /* | 1898 | /* |
1778 | * Otherwise, initial scan or post linkdown rescan, | 1899 | * Otherwise, initial scan or post linkdown rescan, |
1779 | * register with the best fit FCF record found so | 1900 | * register with the best FCF record found so far |
1780 | * far through the scanning process. | 1901 | * through the FCF scanning process. |
1902 | */ | ||
1903 | |||
1904 | /* mark the initial FCF discovery completed */ | ||
1905 | spin_lock_irq(&phba->hbalock); | ||
1906 | phba->fcf.fcf_flag &= ~FCF_INIT_DISC; | ||
1907 | spin_unlock_irq(&phba->hbalock); | ||
1908 | /* | ||
1909 | * Set up the initial registered FCF index for FLOGI | ||
1910 | * round robin FCF failover | ||
1781 | */ | 1911 | */ |
1912 | phba->fcf.fcf_rr_init_indx = | ||
1913 | phba->fcf.current_rec.fcf_indx; | ||
1914 | /* Register to the new FCF record */ | ||
1782 | lpfc_register_fcf(phba); | 1915 | lpfc_register_fcf(phba); |
1783 | } | 1916 | } |
1784 | } else | 1917 | } else |
1785 | lpfc_sli4_read_fcf_record(phba, next_fcf_index); | 1918 | lpfc_sli4_fcf_scan_read_fcf_rec(phba, next_fcf_index); |
1786 | return; | 1919 | return; |
1787 | 1920 | ||
1788 | out: | 1921 | out: |
@@ -1793,6 +1926,141 @@ out: | |||
1793 | } | 1926 | } |
1794 | 1927 | ||
1795 | /** | 1928 | /** |
1929 | * lpfc_mbx_cmpl_fcf_rr_read_fcf_rec - fcf round robin read_fcf mbox cmpl hdler | ||
1930 | * @phba: pointer to lpfc hba data structure. | ||
1931 | * @mboxq: pointer to mailbox object. | ||
1932 | * | ||
1933 | * This is the callback function for FLOGI failure round robin FCF failover | ||
1934 | * read FCF record mailbox command from the eligible FCF record bmask for | ||
1935 | * performing the failover. If the FCF read back is not valid/available, it | ||
1936 | * fails through to retrying FLOGI to the currently registered FCF again. | ||
1937 | * Otherwise, if the FCF read back is valid and available, it will set the | ||
1938 | * newly read FCF record to the failover FCF record, unregister currently | ||
1939 | * registered FCF record, copy the failover FCF record to the current | ||
1940 | * FCF record, and then register the current FCF record before proceeding | ||
1941 | * to trying FLOGI on the new failover FCF. | ||
1942 | */ | ||
1943 | void | ||
1944 | lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
1945 | { | ||
1946 | struct fcf_record *new_fcf_record; | ||
1947 | uint32_t boot_flag, addr_mode; | ||
1948 | uint16_t next_fcf_index; | ||
1949 | uint16_t current_fcf_index; | ||
1950 | uint16_t vlan_id; | ||
1951 | |||
1952 | /* If link state is not up, stop the round robin failover process */ | ||
1953 | if (phba->link_state < LPFC_LINK_UP) { | ||
1954 | spin_lock_irq(&phba->hbalock); | ||
1955 | phba->fcf.fcf_flag &= ~FCF_DISCOVERY; | ||
1956 | spin_unlock_irq(&phba->hbalock); | ||
1957 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1958 | return; | ||
1959 | } | ||
1960 | |||
1961 | /* Parse the FCF record from the non-embedded mailbox command */ | ||
1962 | new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq, | ||
1963 | &next_fcf_index); | ||
1964 | if (!new_fcf_record) { | ||
1965 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, | ||
1966 | "2766 Mailbox command READ_FCF_RECORD " | ||
1967 | "failed to retrieve a FCF record.\n"); | ||
1968 | goto out; | ||
1969 | } | ||
1970 | |||
1971 | /* Get the needed parameters from FCF record */ | ||
1972 | lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, | ||
1973 | &addr_mode, &vlan_id); | ||
1974 | |||
1975 | /* Log the FCF record information if turned on */ | ||
1976 | lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id, | ||
1977 | next_fcf_index); | ||
1978 | |||
1979 | /* Upload new FCF record to the failover FCF record */ | ||
1980 | spin_lock_irq(&phba->hbalock); | ||
1981 | __lpfc_update_fcf_record(phba, &phba->fcf.failover_rec, | ||
1982 | new_fcf_record, addr_mode, vlan_id, | ||
1983 | (boot_flag ? BOOT_ENABLE : 0)); | ||
1984 | spin_unlock_irq(&phba->hbalock); | ||
1985 | |||
1986 | current_fcf_index = phba->fcf.current_rec.fcf_indx; | ||
1987 | |||
1988 | /* Unregister the current in-use FCF record */ | ||
1989 | lpfc_unregister_fcf(phba); | ||
1990 | |||
1991 | /* Replace in-use record with the new record */ | ||
1992 | memcpy(&phba->fcf.current_rec, &phba->fcf.failover_rec, | ||
1993 | sizeof(struct lpfc_fcf_rec)); | ||
1994 | |||
1995 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
1996 | "2783 FLOGI round robin FCF failover from FCF " | ||
1997 | "(index:x%x) to FCF (index:x%x).\n", | ||
1998 | current_fcf_index, | ||
1999 | bf_get(lpfc_fcf_record_fcf_index, new_fcf_record)); | ||
2000 | |||
2001 | out: | ||
2002 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
2003 | lpfc_register_fcf(phba); | ||
2004 | } | ||
2005 | |||
2006 | /** | ||
2007 | * lpfc_mbx_cmpl_read_fcf_rec - read fcf completion handler. | ||
2008 | * @phba: pointer to lpfc hba data structure. | ||
2009 | * @mboxq: pointer to mailbox object. | ||
2010 | * | ||
2011 | * This is the callback function of read FCF record mailbox command for | ||
2012 | * updating the eligible FCF bmask for FLOGI failure round robin FCF | ||
2013 | * failover when a new FCF event happened. If the FCF read back is | ||
2014 | * valid/available and it passes the connection list check, it updates | ||
2015 | * the bmask for the eligible FCF record for round robin failover. | ||
2016 | */ | ||
2017 | void | ||
2018 | lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
2019 | { | ||
2020 | struct fcf_record *new_fcf_record; | ||
2021 | uint32_t boot_flag, addr_mode; | ||
2022 | uint16_t fcf_index, next_fcf_index; | ||
2023 | uint16_t vlan_id; | ||
2024 | int rc; | ||
2025 | |||
2026 | /* If link state is not up, no need to proceed */ | ||
2027 | if (phba->link_state < LPFC_LINK_UP) | ||
2028 | goto out; | ||
2029 | |||
2030 | /* If FCF discovery period is over, no need to proceed */ | ||
2031 | if (phba->fcf.fcf_flag & FCF_DISCOVERY) | ||
2032 | goto out; | ||
2033 | |||
2034 | /* Parse the FCF record from the non-embedded mailbox command */ | ||
2035 | new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq, | ||
2036 | &next_fcf_index); | ||
2037 | if (!new_fcf_record) { | ||
2038 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
2039 | "2767 Mailbox command READ_FCF_RECORD " | ||
2040 | "failed to retrieve a FCF record.\n"); | ||
2041 | goto out; | ||
2042 | } | ||
2043 | |||
2044 | /* Check the connection list for eligibility */ | ||
2045 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, | ||
2046 | &addr_mode, &vlan_id); | ||
2047 | |||
2048 | /* Log the FCF record information if turned on */ | ||
2049 | lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id, | ||
2050 | next_fcf_index); | ||
2051 | |||
2052 | if (!rc) | ||
2053 | goto out; | ||
2054 | |||
2055 | /* Update the eligible FCF record index bmask */ | ||
2056 | fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); | ||
2057 | rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index); | ||
2058 | |||
2059 | out: | ||
2060 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
2061 | } | ||
2062 | |||
2063 | /** | ||
1796 | * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command. | 2064 | * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command. |
1797 | * @phba: pointer to lpfc hba data structure. | 2065 | * @phba: pointer to lpfc hba data structure. |
1798 | * @mboxq: pointer to mailbox data structure. | 2066 | * @mboxq: pointer to mailbox data structure. |
@@ -2024,8 +2292,6 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
2024 | int rc; | 2292 | int rc; |
2025 | struct fcf_record *fcf_record; | 2293 | struct fcf_record *fcf_record; |
2026 | 2294 | ||
2027 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
2028 | |||
2029 | spin_lock_irq(&phba->hbalock); | 2295 | spin_lock_irq(&phba->hbalock); |
2030 | switch (la->UlnkSpeed) { | 2296 | switch (la->UlnkSpeed) { |
2031 | case LA_1GHZ_LINK: | 2297 | case LA_1GHZ_LINK: |
@@ -2117,18 +2383,24 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
2117 | spin_unlock_irq(&phba->hbalock); | 2383 | spin_unlock_irq(&phba->hbalock); |
2118 | 2384 | ||
2119 | lpfc_linkup(phba); | 2385 | lpfc_linkup(phba); |
2120 | if (sparam_mbox) { | 2386 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
2121 | lpfc_read_sparam(phba, sparam_mbox, 0); | 2387 | if (!sparam_mbox) |
2122 | sparam_mbox->vport = vport; | 2388 | goto out; |
2123 | sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; | 2389 | |
2124 | rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT); | 2390 | rc = lpfc_read_sparam(phba, sparam_mbox, 0); |
2125 | if (rc == MBX_NOT_FINISHED) { | 2391 | if (rc) { |
2126 | mp = (struct lpfc_dmabuf *) sparam_mbox->context1; | 2392 | mempool_free(sparam_mbox, phba->mbox_mem_pool); |
2127 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 2393 | goto out; |
2128 | kfree(mp); | 2394 | } |
2129 | mempool_free(sparam_mbox, phba->mbox_mem_pool); | 2395 | sparam_mbox->vport = vport; |
2130 | goto out; | 2396 | sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; |
2131 | } | 2397 | rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT); |
2398 | if (rc == MBX_NOT_FINISHED) { | ||
2399 | mp = (struct lpfc_dmabuf *) sparam_mbox->context1; | ||
2400 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
2401 | kfree(mp); | ||
2402 | mempool_free(sparam_mbox, phba->mbox_mem_pool); | ||
2403 | goto out; | ||
2132 | } | 2404 | } |
2133 | 2405 | ||
2134 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) { | 2406 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) { |
@@ -2186,10 +2458,20 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
2186 | spin_unlock_irq(&phba->hbalock); | 2458 | spin_unlock_irq(&phba->hbalock); |
2187 | return; | 2459 | return; |
2188 | } | 2460 | } |
2461 | /* This is the initial FCF discovery scan */ | ||
2462 | phba->fcf.fcf_flag |= FCF_INIT_DISC; | ||
2189 | spin_unlock_irq(&phba->hbalock); | 2463 | spin_unlock_irq(&phba->hbalock); |
2190 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | 2464 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, |
2191 | if (rc) | 2465 | "2778 Start FCF table scan at linkup\n"); |
2466 | |||
2467 | rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, | ||
2468 | LPFC_FCOE_FCF_GET_FIRST); | ||
2469 | if (rc) { | ||
2470 | spin_lock_irq(&phba->hbalock); | ||
2471 | phba->fcf.fcf_flag &= ~FCF_INIT_DISC; | ||
2472 | spin_unlock_irq(&phba->hbalock); | ||
2192 | goto out; | 2473 | goto out; |
2474 | } | ||
2193 | } | 2475 | } |
2194 | 2476 | ||
2195 | return; | 2477 | return; |
@@ -3379,8 +3661,12 @@ lpfc_unreg_hba_rpis(struct lpfc_hba *phba) | |||
3379 | shost = lpfc_shost_from_vport(vports[i]); | 3661 | shost = lpfc_shost_from_vport(vports[i]); |
3380 | spin_lock_irq(shost->host_lock); | 3662 | spin_lock_irq(shost->host_lock); |
3381 | list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { | 3663 | list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { |
3382 | if (ndlp->nlp_flag & NLP_RPI_VALID) | 3664 | if (ndlp->nlp_flag & NLP_RPI_VALID) { |
3665 | /* The mempool_alloc might sleep */ | ||
3666 | spin_unlock_irq(shost->host_lock); | ||
3383 | lpfc_unreg_rpi(vports[i], ndlp); | 3667 | lpfc_unreg_rpi(vports[i], ndlp); |
3668 | spin_lock_irq(shost->host_lock); | ||
3669 | } | ||
3384 | } | 3670 | } |
3385 | spin_unlock_irq(shost->host_lock); | 3671 | spin_unlock_irq(shost->host_lock); |
3386 | } | 3672 | } |
@@ -4756,6 +5042,7 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba) | |||
4756 | return; | 5042 | return; |
4757 | /* Reset HBA FCF states after successful unregister FCF */ | 5043 | /* Reset HBA FCF states after successful unregister FCF */ |
4758 | phba->fcf.fcf_flag = 0; | 5044 | phba->fcf.fcf_flag = 0; |
5045 | phba->fcf.current_rec.flag = 0; | ||
4759 | 5046 | ||
4760 | /* | 5047 | /* |
4761 | * If driver is not unloading, check if there is any other | 5048 | * If driver is not unloading, check if there is any other |
@@ -4765,13 +5052,21 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba) | |||
4765 | (phba->link_state < LPFC_LINK_UP)) | 5052 | (phba->link_state < LPFC_LINK_UP)) |
4766 | return; | 5053 | return; |
4767 | 5054 | ||
4768 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | 5055 | /* This is considered as the initial FCF discovery scan */ |
5056 | spin_lock_irq(&phba->hbalock); | ||
5057 | phba->fcf.fcf_flag |= FCF_INIT_DISC; | ||
5058 | spin_unlock_irq(&phba->hbalock); | ||
5059 | rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); | ||
4769 | 5060 | ||
4770 | if (rc) | 5061 | if (rc) { |
5062 | spin_lock_irq(&phba->hbalock); | ||
5063 | phba->fcf.fcf_flag &= ~FCF_INIT_DISC; | ||
5064 | spin_unlock_irq(&phba->hbalock); | ||
4771 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 5065 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
4772 | "2553 lpfc_unregister_unused_fcf failed " | 5066 | "2553 lpfc_unregister_unused_fcf failed " |
4773 | "to read FCF record HBA state x%x\n", | 5067 | "to read FCF record HBA state x%x\n", |
4774 | phba->pport->port_state); | 5068 | phba->pport->port_state); |
5069 | } | ||
4775 | } | 5070 | } |
4776 | 5071 | ||
4777 | /** | 5072 | /** |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d29ac7c317d9..ea44239eeb33 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -350,7 +350,12 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
350 | mb = &pmb->u.mb; | 350 | mb = &pmb->u.mb; |
351 | 351 | ||
352 | /* Get login parameters for NID. */ | 352 | /* Get login parameters for NID. */ |
353 | lpfc_read_sparam(phba, pmb, 0); | 353 | rc = lpfc_read_sparam(phba, pmb, 0); |
354 | if (rc) { | ||
355 | mempool_free(pmb, phba->mbox_mem_pool); | ||
356 | return -ENOMEM; | ||
357 | } | ||
358 | |||
354 | pmb->vport = vport; | 359 | pmb->vport = vport; |
355 | if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { | 360 | if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { |
356 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 361 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
@@ -359,7 +364,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
359 | mb->mbxCommand, mb->mbxStatus); | 364 | mb->mbxCommand, mb->mbxStatus); |
360 | phba->link_state = LPFC_HBA_ERROR; | 365 | phba->link_state = LPFC_HBA_ERROR; |
361 | mp = (struct lpfc_dmabuf *) pmb->context1; | 366 | mp = (struct lpfc_dmabuf *) pmb->context1; |
362 | mempool_free( pmb, phba->mbox_mem_pool); | 367 | mempool_free(pmb, phba->mbox_mem_pool); |
363 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 368 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
364 | kfree(mp); | 369 | kfree(mp); |
365 | return -EIO; | 370 | return -EIO; |
@@ -544,7 +549,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
544 | mempool_free(pmb, phba->mbox_mem_pool); | 549 | mempool_free(pmb, phba->mbox_mem_pool); |
545 | return -EIO; | 550 | return -EIO; |
546 | } | 551 | } |
547 | } else if (phba->cfg_suppress_link_up == 0) { | 552 | } else if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) { |
548 | lpfc_init_link(phba, pmb, phba->cfg_topology, | 553 | lpfc_init_link(phba, pmb, phba->cfg_topology, |
549 | phba->cfg_link_speed); | 554 | phba->cfg_link_speed); |
550 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 555 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
@@ -571,6 +576,11 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
571 | } | 576 | } |
572 | /* MBOX buffer will be freed in mbox compl */ | 577 | /* MBOX buffer will be freed in mbox compl */ |
573 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 578 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
579 | if (!pmb) { | ||
580 | phba->link_state = LPFC_HBA_ERROR; | ||
581 | return -ENOMEM; | ||
582 | } | ||
583 | |||
574 | lpfc_config_async(phba, pmb, LPFC_ELS_RING); | 584 | lpfc_config_async(phba, pmb, LPFC_ELS_RING); |
575 | pmb->mbox_cmpl = lpfc_config_async_cmpl; | 585 | pmb->mbox_cmpl = lpfc_config_async_cmpl; |
576 | pmb->vport = phba->pport; | 586 | pmb->vport = phba->pport; |
@@ -588,6 +598,11 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
588 | 598 | ||
589 | /* Get Option rom version */ | 599 | /* Get Option rom version */ |
590 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 600 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
601 | if (!pmb) { | ||
602 | phba->link_state = LPFC_HBA_ERROR; | ||
603 | return -ENOMEM; | ||
604 | } | ||
605 | |||
591 | lpfc_dump_wakeup_param(phba, pmb); | 606 | lpfc_dump_wakeup_param(phba, pmb); |
592 | pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl; | 607 | pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl; |
593 | pmb->vport = phba->pport; | 608 | pmb->vport = phba->pport; |
@@ -652,7 +667,7 @@ lpfc_hba_init_link(struct lpfc_hba *phba) | |||
652 | mempool_free(pmb, phba->mbox_mem_pool); | 667 | mempool_free(pmb, phba->mbox_mem_pool); |
653 | return -EIO; | 668 | return -EIO; |
654 | } | 669 | } |
655 | phba->cfg_suppress_link_up = 0; | 670 | phba->cfg_suppress_link_up = LPFC_INITIALIZE_LINK; |
656 | 671 | ||
657 | return 0; | 672 | return 0; |
658 | } | 673 | } |
@@ -807,6 +822,8 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) | |||
807 | LIST_HEAD(aborts); | 822 | LIST_HEAD(aborts); |
808 | int ret; | 823 | int ret; |
809 | unsigned long iflag = 0; | 824 | unsigned long iflag = 0; |
825 | struct lpfc_sglq *sglq_entry = NULL; | ||
826 | |||
810 | ret = lpfc_hba_down_post_s3(phba); | 827 | ret = lpfc_hba_down_post_s3(phba); |
811 | if (ret) | 828 | if (ret) |
812 | return ret; | 829 | return ret; |
@@ -822,6 +839,10 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) | |||
822 | * list. | 839 | * list. |
823 | */ | 840 | */ |
824 | spin_lock(&phba->sli4_hba.abts_sgl_list_lock); | 841 | spin_lock(&phba->sli4_hba.abts_sgl_list_lock); |
842 | list_for_each_entry(sglq_entry, | ||
843 | &phba->sli4_hba.lpfc_abts_els_sgl_list, list) | ||
844 | sglq_entry->state = SGL_FREED; | ||
845 | |||
825 | list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list, | 846 | list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list, |
826 | &phba->sli4_hba.lpfc_sgl_list); | 847 | &phba->sli4_hba.lpfc_sgl_list); |
827 | spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); | 848 | spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); |
@@ -2178,8 +2199,10 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport) | |||
2178 | void | 2199 | void |
2179 | __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba) | 2200 | __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba) |
2180 | { | 2201 | { |
2181 | /* Clear pending FCF rediscovery wait timer */ | 2202 | /* Clear pending FCF rediscovery wait and failover in progress flags */ |
2182 | phba->fcf.fcf_flag &= ~FCF_REDISC_PEND; | 2203 | phba->fcf.fcf_flag &= ~(FCF_REDISC_PEND | |
2204 | FCF_DEAD_DISC | | ||
2205 | FCF_ACVL_DISC); | ||
2183 | /* Now, try to stop the timer */ | 2206 | /* Now, try to stop the timer */ |
2184 | del_timer(&phba->fcf.redisc_wait); | 2207 | del_timer(&phba->fcf.redisc_wait); |
2185 | } | 2208 | } |
@@ -2576,6 +2599,14 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) | |||
2576 | init_timer(&vport->els_tmofunc); | 2599 | init_timer(&vport->els_tmofunc); |
2577 | vport->els_tmofunc.function = lpfc_els_timeout; | 2600 | vport->els_tmofunc.function = lpfc_els_timeout; |
2578 | vport->els_tmofunc.data = (unsigned long)vport; | 2601 | vport->els_tmofunc.data = (unsigned long)vport; |
2602 | if (phba->pcidev->device == PCI_DEVICE_ID_HORNET) { | ||
2603 | phba->menlo_flag |= HBA_MENLO_SUPPORT; | ||
2604 | /* check for menlo minimum sg count */ | ||
2605 | if (phba->cfg_sg_seg_cnt < LPFC_DEFAULT_MENLO_SG_SEG_CNT) { | ||
2606 | phba->cfg_sg_seg_cnt = LPFC_DEFAULT_MENLO_SG_SEG_CNT; | ||
2607 | shost->sg_tablesize = phba->cfg_sg_seg_cnt; | ||
2608 | } | ||
2609 | } | ||
2579 | 2610 | ||
2580 | error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev); | 2611 | error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev); |
2581 | if (error) | 2612 | if (error) |
@@ -2912,6 +2943,9 @@ lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr) | |||
2912 | /* FCF rediscovery event to worker thread */ | 2943 | /* FCF rediscovery event to worker thread */ |
2913 | phba->fcf.fcf_flag |= FCF_REDISC_EVT; | 2944 | phba->fcf.fcf_flag |= FCF_REDISC_EVT; |
2914 | spin_unlock_irq(&phba->hbalock); | 2945 | spin_unlock_irq(&phba->hbalock); |
2946 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
2947 | "2776 FCF rediscover wait timer expired, post " | ||
2948 | "a worker thread event for FCF table scan\n"); | ||
2915 | /* wake up worker thread */ | 2949 | /* wake up worker thread */ |
2916 | lpfc_worker_wake_up(phba); | 2950 | lpfc_worker_wake_up(phba); |
2917 | } | 2951 | } |
@@ -3183,6 +3217,68 @@ out_free_pmb: | |||
3183 | } | 3217 | } |
3184 | 3218 | ||
3185 | /** | 3219 | /** |
3220 | * lpfc_sli4_perform_vport_cvl - Perform clear virtual link on a vport | ||
3221 | * @vport: pointer to vport data structure. | ||
3222 | * | ||
3223 | * This routine is to perform Clear Virtual Link (CVL) on a vport in | ||
3224 | * response to a CVL event. | ||
3225 | * | ||
3226 | * Return the pointer to the ndlp with the vport if successful, otherwise | ||
3227 | * return NULL. | ||
3228 | **/ | ||
3229 | static struct lpfc_nodelist * | ||
3230 | lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport) | ||
3231 | { | ||
3232 | struct lpfc_nodelist *ndlp; | ||
3233 | struct Scsi_Host *shost; | ||
3234 | struct lpfc_hba *phba; | ||
3235 | |||
3236 | if (!vport) | ||
3237 | return NULL; | ||
3238 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | ||
3239 | if (!ndlp) | ||
3240 | return NULL; | ||
3241 | phba = vport->phba; | ||
3242 | if (!phba) | ||
3243 | return NULL; | ||
3244 | if (phba->pport->port_state <= LPFC_FLOGI) | ||
3245 | return NULL; | ||
3246 | /* If virtual link is not yet instantiated ignore CVL */ | ||
3247 | if (vport->port_state <= LPFC_FDISC) | ||
3248 | return NULL; | ||
3249 | shost = lpfc_shost_from_vport(vport); | ||
3250 | if (!shost) | ||
3251 | return NULL; | ||
3252 | lpfc_linkdown_port(vport); | ||
3253 | lpfc_cleanup_pending_mbox(vport); | ||
3254 | spin_lock_irq(shost->host_lock); | ||
3255 | vport->fc_flag |= FC_VPORT_CVL_RCVD; | ||
3256 | spin_unlock_irq(shost->host_lock); | ||
3257 | |||
3258 | return ndlp; | ||
3259 | } | ||
3260 | |||
3261 | /** | ||
3262 | * lpfc_sli4_perform_all_vport_cvl - Perform clear virtual link on all vports | ||
3263 | * @vport: pointer to lpfc hba data structure. | ||
3264 | * | ||
3265 | * This routine is to perform Clear Virtual Link (CVL) on all vports in | ||
3266 | * response to a FCF dead event. | ||
3267 | **/ | ||
3268 | static void | ||
3269 | lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba) | ||
3270 | { | ||
3271 | struct lpfc_vport **vports; | ||
3272 | int i; | ||
3273 | |||
3274 | vports = lpfc_create_vport_work_array(phba); | ||
3275 | if (vports) | ||
3276 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) | ||
3277 | lpfc_sli4_perform_vport_cvl(vports[i]); | ||
3278 | lpfc_destroy_vport_work_array(phba, vports); | ||
3279 | } | ||
3280 | |||
3281 | /** | ||
3186 | * lpfc_sli4_async_fcoe_evt - Process the asynchronous fcoe event | 3282 | * lpfc_sli4_async_fcoe_evt - Process the asynchronous fcoe event |
3187 | * @phba: pointer to lpfc hba data structure. | 3283 | * @phba: pointer to lpfc hba data structure. |
3188 | * @acqe_link: pointer to the async fcoe completion queue entry. | 3284 | * @acqe_link: pointer to the async fcoe completion queue entry. |
@@ -3198,7 +3294,6 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3198 | struct lpfc_vport *vport; | 3294 | struct lpfc_vport *vport; |
3199 | struct lpfc_nodelist *ndlp; | 3295 | struct lpfc_nodelist *ndlp; |
3200 | struct Scsi_Host *shost; | 3296 | struct Scsi_Host *shost; |
3201 | uint32_t link_state; | ||
3202 | int active_vlink_present; | 3297 | int active_vlink_present; |
3203 | struct lpfc_vport **vports; | 3298 | struct lpfc_vport **vports; |
3204 | int i; | 3299 | int i; |
@@ -3208,10 +3303,11 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3208 | switch (event_type) { | 3303 | switch (event_type) { |
3209 | case LPFC_FCOE_EVENT_TYPE_NEW_FCF: | 3304 | case LPFC_FCOE_EVENT_TYPE_NEW_FCF: |
3210 | case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD: | 3305 | case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD: |
3211 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 3306 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, |
3212 | "2546 New FCF found index 0x%x tag 0x%x\n", | 3307 | "2546 New FCF found/FCF parameter modified event: " |
3213 | acqe_fcoe->index, | 3308 | "evt_tag:x%x, fcf_index:x%x\n", |
3214 | acqe_fcoe->event_tag); | 3309 | acqe_fcoe->event_tag, acqe_fcoe->index); |
3310 | |||
3215 | spin_lock_irq(&phba->hbalock); | 3311 | spin_lock_irq(&phba->hbalock); |
3216 | if ((phba->fcf.fcf_flag & FCF_SCAN_DONE) || | 3312 | if ((phba->fcf.fcf_flag & FCF_SCAN_DONE) || |
3217 | (phba->hba_flag & FCF_DISC_INPROGRESS)) { | 3313 | (phba->hba_flag & FCF_DISC_INPROGRESS)) { |
@@ -3222,6 +3318,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3222 | spin_unlock_irq(&phba->hbalock); | 3318 | spin_unlock_irq(&phba->hbalock); |
3223 | break; | 3319 | break; |
3224 | } | 3320 | } |
3321 | |||
3225 | if (phba->fcf.fcf_flag & FCF_REDISC_EVT) { | 3322 | if (phba->fcf.fcf_flag & FCF_REDISC_EVT) { |
3226 | /* | 3323 | /* |
3227 | * If fast FCF failover rescan event is pending, | 3324 | * If fast FCF failover rescan event is pending, |
@@ -3232,12 +3329,33 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3232 | } | 3329 | } |
3233 | spin_unlock_irq(&phba->hbalock); | 3330 | spin_unlock_irq(&phba->hbalock); |
3234 | 3331 | ||
3235 | /* Read the FCF table and re-discover SAN. */ | 3332 | if ((phba->fcf.fcf_flag & FCF_DISCOVERY) && |
3236 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | 3333 | !(phba->fcf.fcf_flag & FCF_REDISC_FOV)) { |
3334 | /* | ||
3335 | * During period of FCF discovery, read the FCF | ||
3336 | * table record indexed by the event to update | ||
3337 | * FCF round robin failover eligible FCF bmask. | ||
3338 | */ | ||
3339 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | | ||
3340 | LOG_DISCOVERY, | ||
3341 | "2779 Read new FCF record with " | ||
3342 | "fcf_index:x%x for updating FCF " | ||
3343 | "round robin failover bmask\n", | ||
3344 | acqe_fcoe->index); | ||
3345 | rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index); | ||
3346 | } | ||
3347 | |||
3348 | /* Otherwise, scan the entire FCF table and re-discover SAN */ | ||
3349 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, | ||
3350 | "2770 Start FCF table scan due to new FCF " | ||
3351 | "event: evt_tag:x%x, fcf_index:x%x\n", | ||
3352 | acqe_fcoe->event_tag, acqe_fcoe->index); | ||
3353 | rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, | ||
3354 | LPFC_FCOE_FCF_GET_FIRST); | ||
3237 | if (rc) | 3355 | if (rc) |
3238 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 3356 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, |
3239 | "2547 Read FCF record failed 0x%x\n", | 3357 | "2547 Issue FCF scan read FCF mailbox " |
3240 | rc); | 3358 | "command failed 0x%x\n", rc); |
3241 | break; | 3359 | break; |
3242 | 3360 | ||
3243 | case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL: | 3361 | case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL: |
@@ -3248,47 +3366,63 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3248 | break; | 3366 | break; |
3249 | 3367 | ||
3250 | case LPFC_FCOE_EVENT_TYPE_FCF_DEAD: | 3368 | case LPFC_FCOE_EVENT_TYPE_FCF_DEAD: |
3251 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 3369 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, |
3252 | "2549 FCF disconnected from network index 0x%x" | 3370 | "2549 FCF disconnected from network index 0x%x" |
3253 | " tag 0x%x\n", acqe_fcoe->index, | 3371 | " tag 0x%x\n", acqe_fcoe->index, |
3254 | acqe_fcoe->event_tag); | 3372 | acqe_fcoe->event_tag); |
3255 | /* If the event is not for currently used fcf do nothing */ | 3373 | /* If the event is not for currently used fcf do nothing */ |
3256 | if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index) | 3374 | if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index) |
3257 | break; | 3375 | break; |
3258 | /* | 3376 | /* We request port to rediscover the entire FCF table for |
3259 | * Currently, driver support only one FCF - so treat this as | 3377 | * a fast recovery from case that the current FCF record |
3260 | * a link down, but save the link state because we don't want | 3378 | * is no longer valid if we are not in the middle of FCF |
3261 | * it to be changed to Link Down unless it is already down. | 3379 | * failover process already. |
3262 | */ | 3380 | */ |
3263 | link_state = phba->link_state; | 3381 | spin_lock_irq(&phba->hbalock); |
3264 | lpfc_linkdown(phba); | 3382 | if (phba->fcf.fcf_flag & FCF_DISCOVERY) { |
3265 | phba->link_state = link_state; | 3383 | spin_unlock_irq(&phba->hbalock); |
3266 | /* Unregister FCF if no devices connected to it */ | 3384 | /* Update FLOGI FCF failover eligible FCF bmask */ |
3267 | lpfc_unregister_unused_fcf(phba); | 3385 | lpfc_sli4_fcf_rr_index_clear(phba, acqe_fcoe->index); |
3386 | break; | ||
3387 | } | ||
3388 | /* Mark the fast failover process in progress */ | ||
3389 | phba->fcf.fcf_flag |= FCF_DEAD_DISC; | ||
3390 | spin_unlock_irq(&phba->hbalock); | ||
3391 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, | ||
3392 | "2771 Start FCF fast failover process due to " | ||
3393 | "FCF DEAD event: evt_tag:x%x, fcf_index:x%x " | ||
3394 | "\n", acqe_fcoe->event_tag, acqe_fcoe->index); | ||
3395 | rc = lpfc_sli4_redisc_fcf_table(phba); | ||
3396 | if (rc) { | ||
3397 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | | ||
3398 | LOG_DISCOVERY, | ||
3399 | "2772 Issue FCF rediscover mabilbox " | ||
3400 | "command failed, fail through to FCF " | ||
3401 | "dead event\n"); | ||
3402 | spin_lock_irq(&phba->hbalock); | ||
3403 | phba->fcf.fcf_flag &= ~FCF_DEAD_DISC; | ||
3404 | spin_unlock_irq(&phba->hbalock); | ||
3405 | /* | ||
3406 | * Last resort will fail over by treating this | ||
3407 | * as a link down to FCF registration. | ||
3408 | */ | ||
3409 | lpfc_sli4_fcf_dead_failthrough(phba); | ||
3410 | } else | ||
3411 | /* Handling fast FCF failover to a DEAD FCF event | ||
3412 | * is considered equalivant to receiving CVL to all | ||
3413 | * vports. | ||
3414 | */ | ||
3415 | lpfc_sli4_perform_all_vport_cvl(phba); | ||
3268 | break; | 3416 | break; |
3269 | case LPFC_FCOE_EVENT_TYPE_CVL: | 3417 | case LPFC_FCOE_EVENT_TYPE_CVL: |
3270 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 3418 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, |
3271 | "2718 Clear Virtual Link Received for VPI 0x%x" | 3419 | "2718 Clear Virtual Link Received for VPI 0x%x" |
3272 | " tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag); | 3420 | " tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag); |
3273 | vport = lpfc_find_vport_by_vpid(phba, | 3421 | vport = lpfc_find_vport_by_vpid(phba, |
3274 | acqe_fcoe->index - phba->vpi_base); | 3422 | acqe_fcoe->index - phba->vpi_base); |
3275 | if (!vport) | 3423 | ndlp = lpfc_sli4_perform_vport_cvl(vport); |
3276 | break; | ||
3277 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | ||
3278 | if (!ndlp) | 3424 | if (!ndlp) |
3279 | break; | 3425 | break; |
3280 | shost = lpfc_shost_from_vport(vport); | ||
3281 | if (phba->pport->port_state <= LPFC_FLOGI) | ||
3282 | break; | ||
3283 | /* If virtual link is not yet instantiated ignore CVL */ | ||
3284 | if (vport->port_state <= LPFC_FDISC) | ||
3285 | break; | ||
3286 | |||
3287 | lpfc_linkdown_port(vport); | ||
3288 | lpfc_cleanup_pending_mbox(vport); | ||
3289 | spin_lock_irq(shost->host_lock); | ||
3290 | vport->fc_flag |= FC_VPORT_CVL_RCVD; | ||
3291 | spin_unlock_irq(shost->host_lock); | ||
3292 | active_vlink_present = 0; | 3426 | active_vlink_present = 0; |
3293 | 3427 | ||
3294 | vports = lpfc_create_vport_work_array(phba); | 3428 | vports = lpfc_create_vport_work_array(phba); |
@@ -3311,6 +3445,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3311 | * re-instantiate the Vlink using FDISC. | 3445 | * re-instantiate the Vlink using FDISC. |
3312 | */ | 3446 | */ |
3313 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 3447 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
3448 | shost = lpfc_shost_from_vport(vport); | ||
3314 | spin_lock_irq(shost->host_lock); | 3449 | spin_lock_irq(shost->host_lock); |
3315 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 3450 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
3316 | spin_unlock_irq(shost->host_lock); | 3451 | spin_unlock_irq(shost->host_lock); |
@@ -3321,15 +3456,38 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3321 | * Otherwise, we request port to rediscover | 3456 | * Otherwise, we request port to rediscover |
3322 | * the entire FCF table for a fast recovery | 3457 | * the entire FCF table for a fast recovery |
3323 | * from possible case that the current FCF | 3458 | * from possible case that the current FCF |
3324 | * is no longer valid. | 3459 | * is no longer valid if we are not already |
3460 | * in the FCF failover process. | ||
3325 | */ | 3461 | */ |
3462 | spin_lock_irq(&phba->hbalock); | ||
3463 | if (phba->fcf.fcf_flag & FCF_DISCOVERY) { | ||
3464 | spin_unlock_irq(&phba->hbalock); | ||
3465 | break; | ||
3466 | } | ||
3467 | /* Mark the fast failover process in progress */ | ||
3468 | phba->fcf.fcf_flag |= FCF_ACVL_DISC; | ||
3469 | spin_unlock_irq(&phba->hbalock); | ||
3470 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | | ||
3471 | LOG_DISCOVERY, | ||
3472 | "2773 Start FCF fast failover due " | ||
3473 | "to CVL event: evt_tag:x%x\n", | ||
3474 | acqe_fcoe->event_tag); | ||
3326 | rc = lpfc_sli4_redisc_fcf_table(phba); | 3475 | rc = lpfc_sli4_redisc_fcf_table(phba); |
3327 | if (rc) | 3476 | if (rc) { |
3477 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | | ||
3478 | LOG_DISCOVERY, | ||
3479 | "2774 Issue FCF rediscover " | ||
3480 | "mabilbox command failed, " | ||
3481 | "through to CVL event\n"); | ||
3482 | spin_lock_irq(&phba->hbalock); | ||
3483 | phba->fcf.fcf_flag &= ~FCF_ACVL_DISC; | ||
3484 | spin_unlock_irq(&phba->hbalock); | ||
3328 | /* | 3485 | /* |
3329 | * Last resort will be re-try on the | 3486 | * Last resort will be re-try on the |
3330 | * the current registered FCF entry. | 3487 | * the current registered FCF entry. |
3331 | */ | 3488 | */ |
3332 | lpfc_retry_pport_discovery(phba); | 3489 | lpfc_retry_pport_discovery(phba); |
3490 | } | ||
3333 | } | 3491 | } |
3334 | break; | 3492 | break; |
3335 | default: | 3493 | default: |
@@ -3426,11 +3584,14 @@ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *phba) | |||
3426 | spin_unlock_irq(&phba->hbalock); | 3584 | spin_unlock_irq(&phba->hbalock); |
3427 | 3585 | ||
3428 | /* Scan FCF table from the first entry to re-discover SAN */ | 3586 | /* Scan FCF table from the first entry to re-discover SAN */ |
3429 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | 3587 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, |
3588 | "2777 Start FCF table scan after FCF " | ||
3589 | "rediscovery quiescent period over\n"); | ||
3590 | rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); | ||
3430 | if (rc) | 3591 | if (rc) |
3431 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | 3592 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, |
3432 | "2747 Post FCF rediscovery read FCF record " | 3593 | "2747 Issue FCF scan read FCF mailbox " |
3433 | "failed 0x%x\n", rc); | 3594 | "command failed 0x%x\n", rc); |
3434 | } | 3595 | } |
3435 | 3596 | ||
3436 | /** | 3597 | /** |
@@ -3722,6 +3883,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
3722 | int rc, i, hbq_count, buf_size, dma_buf_size, max_buf_size; | 3883 | int rc, i, hbq_count, buf_size, dma_buf_size, max_buf_size; |
3723 | uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0}; | 3884 | uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0}; |
3724 | struct lpfc_mqe *mqe; | 3885 | struct lpfc_mqe *mqe; |
3886 | int longs; | ||
3725 | 3887 | ||
3726 | /* Before proceed, wait for POST done and device ready */ | 3888 | /* Before proceed, wait for POST done and device ready */ |
3727 | rc = lpfc_sli4_post_status_check(phba); | 3889 | rc = lpfc_sli4_post_status_check(phba); |
@@ -3898,13 +4060,24 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
3898 | goto out_free_active_sgl; | 4060 | goto out_free_active_sgl; |
3899 | } | 4061 | } |
3900 | 4062 | ||
4063 | /* Allocate eligible FCF bmask memory for FCF round robin failover */ | ||
4064 | longs = (LPFC_SLI4_FCF_TBL_INDX_MAX + BITS_PER_LONG - 1)/BITS_PER_LONG; | ||
4065 | phba->fcf.fcf_rr_bmask = kzalloc(longs * sizeof(unsigned long), | ||
4066 | GFP_KERNEL); | ||
4067 | if (!phba->fcf.fcf_rr_bmask) { | ||
4068 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
4069 | "2759 Failed allocate memory for FCF round " | ||
4070 | "robin failover bmask\n"); | ||
4071 | goto out_remove_rpi_hdrs; | ||
4072 | } | ||
4073 | |||
3901 | phba->sli4_hba.fcp_eq_hdl = kzalloc((sizeof(struct lpfc_fcp_eq_hdl) * | 4074 | phba->sli4_hba.fcp_eq_hdl = kzalloc((sizeof(struct lpfc_fcp_eq_hdl) * |
3902 | phba->cfg_fcp_eq_count), GFP_KERNEL); | 4075 | phba->cfg_fcp_eq_count), GFP_KERNEL); |
3903 | if (!phba->sli4_hba.fcp_eq_hdl) { | 4076 | if (!phba->sli4_hba.fcp_eq_hdl) { |
3904 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4077 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
3905 | "2572 Failed allocate memory for fast-path " | 4078 | "2572 Failed allocate memory for fast-path " |
3906 | "per-EQ handle array\n"); | 4079 | "per-EQ handle array\n"); |
3907 | goto out_remove_rpi_hdrs; | 4080 | goto out_free_fcf_rr_bmask; |
3908 | } | 4081 | } |
3909 | 4082 | ||
3910 | phba->sli4_hba.msix_entries = kzalloc((sizeof(struct msix_entry) * | 4083 | phba->sli4_hba.msix_entries = kzalloc((sizeof(struct msix_entry) * |
@@ -3957,6 +4130,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
3957 | 4130 | ||
3958 | out_free_fcp_eq_hdl: | 4131 | out_free_fcp_eq_hdl: |
3959 | kfree(phba->sli4_hba.fcp_eq_hdl); | 4132 | kfree(phba->sli4_hba.fcp_eq_hdl); |
4133 | out_free_fcf_rr_bmask: | ||
4134 | kfree(phba->fcf.fcf_rr_bmask); | ||
3960 | out_remove_rpi_hdrs: | 4135 | out_remove_rpi_hdrs: |
3961 | lpfc_sli4_remove_rpi_hdrs(phba); | 4136 | lpfc_sli4_remove_rpi_hdrs(phba); |
3962 | out_free_active_sgl: | 4137 | out_free_active_sgl: |
@@ -4002,6 +4177,9 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba) | |||
4002 | lpfc_sli4_remove_rpi_hdrs(phba); | 4177 | lpfc_sli4_remove_rpi_hdrs(phba); |
4003 | lpfc_sli4_remove_rpis(phba); | 4178 | lpfc_sli4_remove_rpis(phba); |
4004 | 4179 | ||
4180 | /* Free eligible FCF index bmask */ | ||
4181 | kfree(phba->fcf.fcf_rr_bmask); | ||
4182 | |||
4005 | /* Free the ELS sgl list */ | 4183 | /* Free the ELS sgl list */ |
4006 | lpfc_free_active_sgl(phba); | 4184 | lpfc_free_active_sgl(phba); |
4007 | lpfc_free_sgl_list(phba); | 4185 | lpfc_free_sgl_list(phba); |
@@ -4397,6 +4575,7 @@ lpfc_init_sgl_list(struct lpfc_hba *phba) | |||
4397 | 4575 | ||
4398 | /* The list order is used by later block SGL registraton */ | 4576 | /* The list order is used by later block SGL registraton */ |
4399 | spin_lock_irq(&phba->hbalock); | 4577 | spin_lock_irq(&phba->hbalock); |
4578 | sglq_entry->state = SGL_FREED; | ||
4400 | list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list); | 4579 | list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list); |
4401 | phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry; | 4580 | phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry; |
4402 | phba->sli4_hba.total_sglq_bufs++; | 4581 | phba->sli4_hba.total_sglq_bufs++; |
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h index 954ba57970a3..bb59e9273126 100644 --- a/drivers/scsi/lpfc/lpfc_logmsg.h +++ b/drivers/scsi/lpfc/lpfc_logmsg.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #define LOG_VPORT 0x00004000 /* NPIV events */ | 35 | #define LOG_VPORT 0x00004000 /* NPIV events */ |
36 | #define LOF_SECURITY 0x00008000 /* Security events */ | 36 | #define LOF_SECURITY 0x00008000 /* Security events */ |
37 | #define LOG_EVENT 0x00010000 /* CT,TEMP,DUMP, logging */ | 37 | #define LOG_EVENT 0x00010000 /* CT,TEMP,DUMP, logging */ |
38 | #define LOG_FIP 0x00020000 /* FIP events */ | ||
38 | #define LOG_ALL_MSG 0xffffffff /* LOG all messages */ | 39 | #define LOG_ALL_MSG 0xffffffff /* LOG all messages */ |
39 | 40 | ||
40 | #define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ | 41 | #define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ |
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 6c4dce1a30ca..1e61ae3bc4eb 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -1748,7 +1748,7 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox) | |||
1748 | } | 1748 | } |
1749 | 1749 | ||
1750 | /** | 1750 | /** |
1751 | * lpfc_sli4_mbx_read_fcf_record - Allocate and construct read fcf mbox cmd | 1751 | * lpfc_sli4_mbx_read_fcf_rec - Allocate and construct read fcf mbox cmd |
1752 | * @phba: pointer to lpfc hba data structure. | 1752 | * @phba: pointer to lpfc hba data structure. |
1753 | * @fcf_index: index to fcf table. | 1753 | * @fcf_index: index to fcf table. |
1754 | * | 1754 | * |
@@ -1759,9 +1759,9 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox) | |||
1759 | * NULL. | 1759 | * NULL. |
1760 | **/ | 1760 | **/ |
1761 | int | 1761 | int |
1762 | lpfc_sli4_mbx_read_fcf_record(struct lpfc_hba *phba, | 1762 | lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *phba, |
1763 | struct lpfcMboxq *mboxq, | 1763 | struct lpfcMboxq *mboxq, |
1764 | uint16_t fcf_index) | 1764 | uint16_t fcf_index) |
1765 | { | 1765 | { |
1766 | void *virt_addr; | 1766 | void *virt_addr; |
1767 | dma_addr_t phys_addr; | 1767 | dma_addr_t phys_addr; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 483fb74bc592..b16bb2c9978b 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -620,23 +620,40 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba, | |||
620 | uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); | 620 | uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); |
621 | struct lpfc_scsi_buf *psb, *next_psb; | 621 | struct lpfc_scsi_buf *psb, *next_psb; |
622 | unsigned long iflag = 0; | 622 | unsigned long iflag = 0; |
623 | struct lpfc_iocbq *iocbq; | ||
624 | int i; | ||
623 | 625 | ||
624 | spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock, iflag); | 626 | spin_lock_irqsave(&phba->hbalock, iflag); |
627 | spin_lock(&phba->sli4_hba.abts_scsi_buf_list_lock); | ||
625 | list_for_each_entry_safe(psb, next_psb, | 628 | list_for_each_entry_safe(psb, next_psb, |
626 | &phba->sli4_hba.lpfc_abts_scsi_buf_list, list) { | 629 | &phba->sli4_hba.lpfc_abts_scsi_buf_list, list) { |
627 | if (psb->cur_iocbq.sli4_xritag == xri) { | 630 | if (psb->cur_iocbq.sli4_xritag == xri) { |
628 | list_del(&psb->list); | 631 | list_del(&psb->list); |
629 | psb->exch_busy = 0; | 632 | psb->exch_busy = 0; |
630 | psb->status = IOSTAT_SUCCESS; | 633 | psb->status = IOSTAT_SUCCESS; |
631 | spin_unlock_irqrestore( | 634 | spin_unlock( |
632 | &phba->sli4_hba.abts_scsi_buf_list_lock, | 635 | &phba->sli4_hba.abts_scsi_buf_list_lock); |
633 | iflag); | 636 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
634 | lpfc_release_scsi_buf_s4(phba, psb); | 637 | lpfc_release_scsi_buf_s4(phba, psb); |
635 | return; | 638 | return; |
636 | } | 639 | } |
637 | } | 640 | } |
638 | spin_unlock_irqrestore(&phba->sli4_hba.abts_scsi_buf_list_lock, | 641 | spin_unlock(&phba->sli4_hba.abts_scsi_buf_list_lock); |
639 | iflag); | 642 | for (i = 1; i <= phba->sli.last_iotag; i++) { |
643 | iocbq = phba->sli.iocbq_lookup[i]; | ||
644 | |||
645 | if (!(iocbq->iocb_flag & LPFC_IO_FCP) || | ||
646 | (iocbq->iocb_flag & LPFC_IO_LIBDFC)) | ||
647 | continue; | ||
648 | if (iocbq->sli4_xritag != xri) | ||
649 | continue; | ||
650 | psb = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq); | ||
651 | psb->exch_busy = 0; | ||
652 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
653 | return; | ||
654 | |||
655 | } | ||
656 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
640 | } | 657 | } |
641 | 658 | ||
642 | /** | 659 | /** |
@@ -1006,6 +1023,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
1006 | struct scatterlist *sgel = NULL; | 1023 | struct scatterlist *sgel = NULL; |
1007 | struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; | 1024 | struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; |
1008 | struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl; | 1025 | struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl; |
1026 | struct lpfc_iocbq *iocbq = &lpfc_cmd->cur_iocbq; | ||
1009 | IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; | 1027 | IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; |
1010 | struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde; | 1028 | struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde; |
1011 | dma_addr_t physaddr; | 1029 | dma_addr_t physaddr; |
@@ -1056,6 +1074,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
1056 | physaddr = sg_dma_address(sgel); | 1074 | physaddr = sg_dma_address(sgel); |
1057 | if (phba->sli_rev == 3 && | 1075 | if (phba->sli_rev == 3 && |
1058 | !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) && | 1076 | !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) && |
1077 | !(iocbq->iocb_flag & DSS_SECURITY_OP) && | ||
1059 | nseg <= LPFC_EXT_DATA_BDE_COUNT) { | 1078 | nseg <= LPFC_EXT_DATA_BDE_COUNT) { |
1060 | data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; | 1079 | data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; |
1061 | data_bde->tus.f.bdeSize = sg_dma_len(sgel); | 1080 | data_bde->tus.f.bdeSize = sg_dma_len(sgel); |
@@ -1082,7 +1101,8 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
1082 | * explicitly reinitialized since all iocb memory resources are reused. | 1101 | * explicitly reinitialized since all iocb memory resources are reused. |
1083 | */ | 1102 | */ |
1084 | if (phba->sli_rev == 3 && | 1103 | if (phba->sli_rev == 3 && |
1085 | !(phba->sli3_options & LPFC_SLI3_BG_ENABLED)) { | 1104 | !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) && |
1105 | !(iocbq->iocb_flag & DSS_SECURITY_OP)) { | ||
1086 | if (num_bde > LPFC_EXT_DATA_BDE_COUNT) { | 1106 | if (num_bde > LPFC_EXT_DATA_BDE_COUNT) { |
1087 | /* | 1107 | /* |
1088 | * The extended IOCB format can only fit 3 BDE or a BPL. | 1108 | * The extended IOCB format can only fit 3 BDE or a BPL. |
@@ -1107,6 +1127,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
1107 | } else { | 1127 | } else { |
1108 | iocb_cmd->un.fcpi64.bdl.bdeSize = | 1128 | iocb_cmd->un.fcpi64.bdl.bdeSize = |
1109 | ((num_bde + 2) * sizeof(struct ulp_bde64)); | 1129 | ((num_bde + 2) * sizeof(struct ulp_bde64)); |
1130 | iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1); | ||
1110 | } | 1131 | } |
1111 | fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); | 1132 | fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); |
1112 | 1133 | ||
@@ -2079,8 +2100,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
2079 | 2100 | ||
2080 | if (resp_info & RSP_LEN_VALID) { | 2101 | if (resp_info & RSP_LEN_VALID) { |
2081 | rsplen = be32_to_cpu(fcprsp->rspRspLen); | 2102 | rsplen = be32_to_cpu(fcprsp->rspRspLen); |
2082 | if ((rsplen != 0 && rsplen != 4 && rsplen != 8) || | 2103 | if (rsplen != 0 && rsplen != 4 && rsplen != 8) { |
2083 | (fcprsp->rspInfo3 != RSP_NO_FAILURE)) { | ||
2084 | lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, | 2104 | lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, |
2085 | "2719 Invalid response length: " | 2105 | "2719 Invalid response length: " |
2086 | "tgt x%x lun x%x cmnd x%x rsplen x%x\n", | 2106 | "tgt x%x lun x%x cmnd x%x rsplen x%x\n", |
@@ -2090,6 +2110,17 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
2090 | host_status = DID_ERROR; | 2110 | host_status = DID_ERROR; |
2091 | goto out; | 2111 | goto out; |
2092 | } | 2112 | } |
2113 | if (fcprsp->rspInfo3 != RSP_NO_FAILURE) { | ||
2114 | lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, | ||
2115 | "2757 Protocol failure detected during " | ||
2116 | "processing of FCP I/O op: " | ||
2117 | "tgt x%x lun x%x cmnd x%x rspInfo3 x%x\n", | ||
2118 | cmnd->device->id, | ||
2119 | cmnd->device->lun, cmnd->cmnd[0], | ||
2120 | fcprsp->rspInfo3); | ||
2121 | host_status = DID_ERROR; | ||
2122 | goto out; | ||
2123 | } | ||
2093 | } | 2124 | } |
2094 | 2125 | ||
2095 | if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) { | 2126 | if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) { |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 35e3b96d4e07..fe6660ca6452 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -494,7 +494,7 @@ __lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | |||
494 | * | 494 | * |
495 | * Returns sglq ponter = success, NULL = Failure. | 495 | * Returns sglq ponter = success, NULL = Failure. |
496 | **/ | 496 | **/ |
497 | static struct lpfc_sglq * | 497 | struct lpfc_sglq * |
498 | __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | 498 | __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) |
499 | { | 499 | { |
500 | uint16_t adj_xri; | 500 | uint16_t adj_xri; |
@@ -526,6 +526,7 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba) | |||
526 | return NULL; | 526 | return NULL; |
527 | adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base; | 527 | adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base; |
528 | phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq; | 528 | phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq; |
529 | sglq->state = SGL_ALLOCATED; | ||
529 | return sglq; | 530 | return sglq; |
530 | } | 531 | } |
531 | 532 | ||
@@ -580,15 +581,18 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) | |||
580 | else | 581 | else |
581 | sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag); | 582 | sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag); |
582 | if (sglq) { | 583 | if (sglq) { |
583 | if (iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) { | 584 | if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) && |
585 | (sglq->state != SGL_XRI_ABORTED)) { | ||
584 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, | 586 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, |
585 | iflag); | 587 | iflag); |
586 | list_add(&sglq->list, | 588 | list_add(&sglq->list, |
587 | &phba->sli4_hba.lpfc_abts_els_sgl_list); | 589 | &phba->sli4_hba.lpfc_abts_els_sgl_list); |
588 | spin_unlock_irqrestore( | 590 | spin_unlock_irqrestore( |
589 | &phba->sli4_hba.abts_sgl_list_lock, iflag); | 591 | &phba->sli4_hba.abts_sgl_list_lock, iflag); |
590 | } else | 592 | } else { |
593 | sglq->state = SGL_FREED; | ||
591 | list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list); | 594 | list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list); |
595 | } | ||
592 | } | 596 | } |
593 | 597 | ||
594 | 598 | ||
@@ -2258,41 +2262,56 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2258 | spin_unlock_irqrestore(&phba->hbalock, | 2262 | spin_unlock_irqrestore(&phba->hbalock, |
2259 | iflag); | 2263 | iflag); |
2260 | } | 2264 | } |
2261 | if ((phba->sli_rev == LPFC_SLI_REV4) && | 2265 | if (phba->sli_rev == LPFC_SLI_REV4) { |
2262 | (saveq->iocb_flag & LPFC_EXCHANGE_BUSY)) { | 2266 | if (saveq->iocb_flag & |
2263 | /* Set cmdiocb flag for the exchange | 2267 | LPFC_EXCHANGE_BUSY) { |
2264 | * busy so sgl (xri) will not be | 2268 | /* Set cmdiocb flag for the |
2265 | * released until the abort xri is | 2269 | * exchange busy so sgl (xri) |
2266 | * received from hba, clear the | 2270 | * will not be released until |
2267 | * LPFC_DRIVER_ABORTED bit in case | 2271 | * the abort xri is received |
2268 | * it was driver initiated abort. | 2272 | * from hba. |
2269 | */ | 2273 | */ |
2270 | spin_lock_irqsave(&phba->hbalock, | 2274 | spin_lock_irqsave( |
2271 | iflag); | 2275 | &phba->hbalock, iflag); |
2272 | cmdiocbp->iocb_flag &= | 2276 | cmdiocbp->iocb_flag |= |
2273 | ~LPFC_DRIVER_ABORTED; | 2277 | LPFC_EXCHANGE_BUSY; |
2274 | cmdiocbp->iocb_flag |= | 2278 | spin_unlock_irqrestore( |
2275 | LPFC_EXCHANGE_BUSY; | 2279 | &phba->hbalock, iflag); |
2276 | spin_unlock_irqrestore(&phba->hbalock, | 2280 | } |
2277 | iflag); | 2281 | if (cmdiocbp->iocb_flag & |
2278 | cmdiocbp->iocb.ulpStatus = | 2282 | LPFC_DRIVER_ABORTED) { |
2279 | IOSTAT_LOCAL_REJECT; | 2283 | /* |
2280 | cmdiocbp->iocb.un.ulpWord[4] = | 2284 | * Clear LPFC_DRIVER_ABORTED |
2281 | IOERR_ABORT_REQUESTED; | 2285 | * bit in case it was driver |
2282 | /* | 2286 | * initiated abort. |
2283 | * For SLI4, irsiocb contains NO_XRI | 2287 | */ |
2284 | * in sli_xritag, it shall not affect | 2288 | spin_lock_irqsave( |
2285 | * releasing sgl (xri) process. | 2289 | &phba->hbalock, iflag); |
2286 | */ | 2290 | cmdiocbp->iocb_flag &= |
2287 | saveq->iocb.ulpStatus = | 2291 | ~LPFC_DRIVER_ABORTED; |
2288 | IOSTAT_LOCAL_REJECT; | 2292 | spin_unlock_irqrestore( |
2289 | saveq->iocb.un.ulpWord[4] = | 2293 | &phba->hbalock, iflag); |
2290 | IOERR_SLI_ABORTED; | 2294 | cmdiocbp->iocb.ulpStatus = |
2291 | spin_lock_irqsave(&phba->hbalock, | 2295 | IOSTAT_LOCAL_REJECT; |
2292 | iflag); | 2296 | cmdiocbp->iocb.un.ulpWord[4] = |
2293 | saveq->iocb_flag |= LPFC_DELAY_MEM_FREE; | 2297 | IOERR_ABORT_REQUESTED; |
2294 | spin_unlock_irqrestore(&phba->hbalock, | 2298 | /* |
2295 | iflag); | 2299 | * For SLI4, irsiocb contains |
2300 | * NO_XRI in sli_xritag, it | ||
2301 | * shall not affect releasing | ||
2302 | * sgl (xri) process. | ||
2303 | */ | ||
2304 | saveq->iocb.ulpStatus = | ||
2305 | IOSTAT_LOCAL_REJECT; | ||
2306 | saveq->iocb.un.ulpWord[4] = | ||
2307 | IOERR_SLI_ABORTED; | ||
2308 | spin_lock_irqsave( | ||
2309 | &phba->hbalock, iflag); | ||
2310 | saveq->iocb_flag |= | ||
2311 | LPFC_DELAY_MEM_FREE; | ||
2312 | spin_unlock_irqrestore( | ||
2313 | &phba->hbalock, iflag); | ||
2314 | } | ||
2296 | } | 2315 | } |
2297 | } | 2316 | } |
2298 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); | 2317 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); |
@@ -2515,14 +2534,16 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, | |||
2515 | 2534 | ||
2516 | cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, | 2535 | cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, |
2517 | &rspiocbq); | 2536 | &rspiocbq); |
2518 | if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) { | 2537 | if (unlikely(!cmdiocbq)) |
2519 | spin_unlock_irqrestore(&phba->hbalock, | 2538 | break; |
2520 | iflag); | 2539 | if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) |
2521 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, | 2540 | cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED; |
2522 | &rspiocbq); | 2541 | if (cmdiocbq->iocb_cmpl) { |
2523 | spin_lock_irqsave(&phba->hbalock, | 2542 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
2524 | iflag); | 2543 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, |
2525 | } | 2544 | &rspiocbq); |
2545 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
2546 | } | ||
2526 | break; | 2547 | break; |
2527 | case LPFC_UNSOL_IOCB: | 2548 | case LPFC_UNSOL_IOCB: |
2528 | spin_unlock_irqrestore(&phba->hbalock, iflag); | 2549 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
@@ -3091,6 +3112,12 @@ lpfc_sli_brdready_s3(struct lpfc_hba *phba, uint32_t mask) | |||
3091 | 3112 | ||
3092 | /* Check to see if any errors occurred during init */ | 3113 | /* Check to see if any errors occurred during init */ |
3093 | if ((status & HS_FFERM) || (i >= 20)) { | 3114 | if ((status & HS_FFERM) || (i >= 20)) { |
3115 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
3116 | "2751 Adapter failed to restart, " | ||
3117 | "status reg x%x, FW Data: A8 x%x AC x%x\n", | ||
3118 | status, | ||
3119 | readl(phba->MBslimaddr + 0xa8), | ||
3120 | readl(phba->MBslimaddr + 0xac)); | ||
3094 | phba->link_state = LPFC_HBA_ERROR; | 3121 | phba->link_state = LPFC_HBA_ERROR; |
3095 | retval = 1; | 3122 | retval = 1; |
3096 | } | 3123 | } |
@@ -3278,6 +3305,9 @@ lpfc_sli_brdkill(struct lpfc_hba *phba) | |||
3278 | if (retval != MBX_SUCCESS) { | 3305 | if (retval != MBX_SUCCESS) { |
3279 | if (retval != MBX_BUSY) | 3306 | if (retval != MBX_BUSY) |
3280 | mempool_free(pmb, phba->mbox_mem_pool); | 3307 | mempool_free(pmb, phba->mbox_mem_pool); |
3308 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
3309 | "2752 KILL_BOARD command failed retval %d\n", | ||
3310 | retval); | ||
3281 | spin_lock_irq(&phba->hbalock); | 3311 | spin_lock_irq(&phba->hbalock); |
3282 | phba->link_flag &= ~LS_IGNORE_ERATT; | 3312 | phba->link_flag &= ~LS_IGNORE_ERATT; |
3283 | spin_unlock_irq(&phba->hbalock); | 3313 | spin_unlock_irq(&phba->hbalock); |
@@ -4035,7 +4065,7 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) | |||
4035 | 4065 | ||
4036 | lpfc_sli_hba_setup_error: | 4066 | lpfc_sli_hba_setup_error: |
4037 | phba->link_state = LPFC_HBA_ERROR; | 4067 | phba->link_state = LPFC_HBA_ERROR; |
4038 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | 4068 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
4039 | "0445 Firmware initialization failed\n"); | 4069 | "0445 Firmware initialization failed\n"); |
4040 | return rc; | 4070 | return rc; |
4041 | } | 4071 | } |
@@ -4388,7 +4418,13 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
4388 | spin_unlock_irq(&phba->hbalock); | 4418 | spin_unlock_irq(&phba->hbalock); |
4389 | 4419 | ||
4390 | /* Read the port's service parameters. */ | 4420 | /* Read the port's service parameters. */ |
4391 | lpfc_read_sparam(phba, mboxq, vport->vpi); | 4421 | rc = lpfc_read_sparam(phba, mboxq, vport->vpi); |
4422 | if (rc) { | ||
4423 | phba->link_state = LPFC_HBA_ERROR; | ||
4424 | rc = -ENOMEM; | ||
4425 | goto out_free_vpd; | ||
4426 | } | ||
4427 | |||
4392 | mboxq->vport = vport; | 4428 | mboxq->vport = vport; |
4393 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | 4429 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); |
4394 | mp = (struct lpfc_dmabuf *) mboxq->context1; | 4430 | mp = (struct lpfc_dmabuf *) mboxq->context1; |
@@ -4483,6 +4519,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
4483 | /* Post receive buffers to the device */ | 4519 | /* Post receive buffers to the device */ |
4484 | lpfc_sli4_rb_setup(phba); | 4520 | lpfc_sli4_rb_setup(phba); |
4485 | 4521 | ||
4522 | /* Reset HBA FCF states after HBA reset */ | ||
4523 | phba->fcf.fcf_flag = 0; | ||
4524 | phba->fcf.current_rec.flag = 0; | ||
4525 | |||
4486 | /* Start the ELS watchdog timer */ | 4526 | /* Start the ELS watchdog timer */ |
4487 | mod_timer(&vport->els_tmofunc, | 4527 | mod_timer(&vport->els_tmofunc, |
4488 | jiffies + HZ * (phba->fc_ratov * 2)); | 4528 | jiffies + HZ * (phba->fc_ratov * 2)); |
@@ -7436,6 +7476,7 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, | |||
7436 | { | 7476 | { |
7437 | wait_queue_head_t *pdone_q; | 7477 | wait_queue_head_t *pdone_q; |
7438 | unsigned long iflags; | 7478 | unsigned long iflags; |
7479 | struct lpfc_scsi_buf *lpfc_cmd; | ||
7439 | 7480 | ||
7440 | spin_lock_irqsave(&phba->hbalock, iflags); | 7481 | spin_lock_irqsave(&phba->hbalock, iflags); |
7441 | cmdiocbq->iocb_flag |= LPFC_IO_WAKE; | 7482 | cmdiocbq->iocb_flag |= LPFC_IO_WAKE; |
@@ -7443,6 +7484,14 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, | |||
7443 | memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, | 7484 | memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, |
7444 | &rspiocbq->iocb, sizeof(IOCB_t)); | 7485 | &rspiocbq->iocb, sizeof(IOCB_t)); |
7445 | 7486 | ||
7487 | /* Set the exchange busy flag for task management commands */ | ||
7488 | if ((cmdiocbq->iocb_flag & LPFC_IO_FCP) && | ||
7489 | !(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) { | ||
7490 | lpfc_cmd = container_of(cmdiocbq, struct lpfc_scsi_buf, | ||
7491 | cur_iocbq); | ||
7492 | lpfc_cmd->exch_busy = rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY; | ||
7493 | } | ||
7494 | |||
7446 | pdone_q = cmdiocbq->context_un.wait_queue; | 7495 | pdone_q = cmdiocbq->context_un.wait_queue; |
7447 | if (pdone_q) | 7496 | if (pdone_q) |
7448 | wake_up(pdone_q); | 7497 | wake_up(pdone_q); |
@@ -9061,6 +9110,12 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, | |||
9061 | /* Fake the irspiocb and copy necessary response information */ | 9110 | /* Fake the irspiocb and copy necessary response information */ |
9062 | lpfc_sli4_iocb_param_transfer(phba, &irspiocbq, cmdiocbq, wcqe); | 9111 | lpfc_sli4_iocb_param_transfer(phba, &irspiocbq, cmdiocbq, wcqe); |
9063 | 9112 | ||
9113 | if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) { | ||
9114 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
9115 | cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED; | ||
9116 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
9117 | } | ||
9118 | |||
9064 | /* Pass the cmd_iocb and the rsp state to the upper layer */ | 9119 | /* Pass the cmd_iocb and the rsp state to the upper layer */ |
9065 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, &irspiocbq); | 9120 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, &irspiocbq); |
9066 | } | 9121 | } |
@@ -11941,15 +11996,19 @@ lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *phba, | |||
11941 | } | 11996 | } |
11942 | 11997 | ||
11943 | /** | 11998 | /** |
11944 | * lpfc_sli4_read_fcf_record - Read the driver's default FCF Record. | 11999 | * lpfc_sli4_fcf_scan_read_fcf_rec - Read hba fcf record for fcf scan. |
11945 | * @phba: pointer to lpfc hba data structure. | 12000 | * @phba: pointer to lpfc hba data structure. |
11946 | * @fcf_index: FCF table entry offset. | 12001 | * @fcf_index: FCF table entry offset. |
11947 | * | 12002 | * |
11948 | * This routine is invoked to read up to @fcf_num of FCF record from the | 12003 | * This routine is invoked to scan the entire FCF table by reading FCF |
11949 | * device starting with the given @fcf_index. | 12004 | * record and processing it one at a time starting from the @fcf_index |
12005 | * for initial FCF discovery or fast FCF failover rediscovery. | ||
12006 | * | ||
12007 | * Return 0 if the mailbox command is submitted sucessfully, none 0 | ||
12008 | * otherwise. | ||
11950 | **/ | 12009 | **/ |
11951 | int | 12010 | int |
11952 | lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) | 12011 | lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index) |
11953 | { | 12012 | { |
11954 | int rc = 0, error; | 12013 | int rc = 0, error; |
11955 | LPFC_MBOXQ_t *mboxq; | 12014 | LPFC_MBOXQ_t *mboxq; |
@@ -11961,17 +12020,17 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) | |||
11961 | "2000 Failed to allocate mbox for " | 12020 | "2000 Failed to allocate mbox for " |
11962 | "READ_FCF cmd\n"); | 12021 | "READ_FCF cmd\n"); |
11963 | error = -ENOMEM; | 12022 | error = -ENOMEM; |
11964 | goto fail_fcfscan; | 12023 | goto fail_fcf_scan; |
11965 | } | 12024 | } |
11966 | /* Construct the read FCF record mailbox command */ | 12025 | /* Construct the read FCF record mailbox command */ |
11967 | rc = lpfc_sli4_mbx_read_fcf_record(phba, mboxq, fcf_index); | 12026 | rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index); |
11968 | if (rc) { | 12027 | if (rc) { |
11969 | error = -EINVAL; | 12028 | error = -EINVAL; |
11970 | goto fail_fcfscan; | 12029 | goto fail_fcf_scan; |
11971 | } | 12030 | } |
11972 | /* Issue the mailbox command asynchronously */ | 12031 | /* Issue the mailbox command asynchronously */ |
11973 | mboxq->vport = phba->pport; | 12032 | mboxq->vport = phba->pport; |
11974 | mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record; | 12033 | mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_scan_read_fcf_rec; |
11975 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); | 12034 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); |
11976 | if (rc == MBX_NOT_FINISHED) | 12035 | if (rc == MBX_NOT_FINISHED) |
11977 | error = -EIO; | 12036 | error = -EIO; |
@@ -11979,9 +12038,13 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) | |||
11979 | spin_lock_irq(&phba->hbalock); | 12038 | spin_lock_irq(&phba->hbalock); |
11980 | phba->hba_flag |= FCF_DISC_INPROGRESS; | 12039 | phba->hba_flag |= FCF_DISC_INPROGRESS; |
11981 | spin_unlock_irq(&phba->hbalock); | 12040 | spin_unlock_irq(&phba->hbalock); |
12041 | /* Reset FCF round robin index bmask for new scan */ | ||
12042 | if (fcf_index == LPFC_FCOE_FCF_GET_FIRST) | ||
12043 | memset(phba->fcf.fcf_rr_bmask, 0, | ||
12044 | sizeof(*phba->fcf.fcf_rr_bmask)); | ||
11982 | error = 0; | 12045 | error = 0; |
11983 | } | 12046 | } |
11984 | fail_fcfscan: | 12047 | fail_fcf_scan: |
11985 | if (error) { | 12048 | if (error) { |
11986 | if (mboxq) | 12049 | if (mboxq) |
11987 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | 12050 | lpfc_sli4_mbox_cmd_free(phba, mboxq); |
@@ -11994,6 +12057,181 @@ fail_fcfscan: | |||
11994 | } | 12057 | } |
11995 | 12058 | ||
11996 | /** | 12059 | /** |
12060 | * lpfc_sli4_fcf_rr_read_fcf_rec - Read hba fcf record for round robin fcf. | ||
12061 | * @phba: pointer to lpfc hba data structure. | ||
12062 | * @fcf_index: FCF table entry offset. | ||
12063 | * | ||
12064 | * This routine is invoked to read an FCF record indicated by @fcf_index | ||
12065 | * and to use it for FLOGI round robin FCF failover. | ||
12066 | * | ||
12067 | * Return 0 if the mailbox command is submitted sucessfully, none 0 | ||
12068 | * otherwise. | ||
12069 | **/ | ||
12070 | int | ||
12071 | lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index) | ||
12072 | { | ||
12073 | int rc = 0, error; | ||
12074 | LPFC_MBOXQ_t *mboxq; | ||
12075 | |||
12076 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
12077 | if (!mboxq) { | ||
12078 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT, | ||
12079 | "2763 Failed to allocate mbox for " | ||
12080 | "READ_FCF cmd\n"); | ||
12081 | error = -ENOMEM; | ||
12082 | goto fail_fcf_read; | ||
12083 | } | ||
12084 | /* Construct the read FCF record mailbox command */ | ||
12085 | rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index); | ||
12086 | if (rc) { | ||
12087 | error = -EINVAL; | ||
12088 | goto fail_fcf_read; | ||
12089 | } | ||
12090 | /* Issue the mailbox command asynchronously */ | ||
12091 | mboxq->vport = phba->pport; | ||
12092 | mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_rr_read_fcf_rec; | ||
12093 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); | ||
12094 | if (rc == MBX_NOT_FINISHED) | ||
12095 | error = -EIO; | ||
12096 | else | ||
12097 | error = 0; | ||
12098 | |||
12099 | fail_fcf_read: | ||
12100 | if (error && mboxq) | ||
12101 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
12102 | return error; | ||
12103 | } | ||
12104 | |||
12105 | /** | ||
12106 | * lpfc_sli4_read_fcf_rec - Read hba fcf record for update eligible fcf bmask. | ||
12107 | * @phba: pointer to lpfc hba data structure. | ||
12108 | * @fcf_index: FCF table entry offset. | ||
12109 | * | ||
12110 | * This routine is invoked to read an FCF record indicated by @fcf_index to | ||
12111 | * determine whether it's eligible for FLOGI round robin failover list. | ||
12112 | * | ||
12113 | * Return 0 if the mailbox command is submitted sucessfully, none 0 | ||
12114 | * otherwise. | ||
12115 | **/ | ||
12116 | int | ||
12117 | lpfc_sli4_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index) | ||
12118 | { | ||
12119 | int rc = 0, error; | ||
12120 | LPFC_MBOXQ_t *mboxq; | ||
12121 | |||
12122 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
12123 | if (!mboxq) { | ||
12124 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT, | ||
12125 | "2758 Failed to allocate mbox for " | ||
12126 | "READ_FCF cmd\n"); | ||
12127 | error = -ENOMEM; | ||
12128 | goto fail_fcf_read; | ||
12129 | } | ||
12130 | /* Construct the read FCF record mailbox command */ | ||
12131 | rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index); | ||
12132 | if (rc) { | ||
12133 | error = -EINVAL; | ||
12134 | goto fail_fcf_read; | ||
12135 | } | ||
12136 | /* Issue the mailbox command asynchronously */ | ||
12137 | mboxq->vport = phba->pport; | ||
12138 | mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_rec; | ||
12139 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); | ||
12140 | if (rc == MBX_NOT_FINISHED) | ||
12141 | error = -EIO; | ||
12142 | else | ||
12143 | error = 0; | ||
12144 | |||
12145 | fail_fcf_read: | ||
12146 | if (error && mboxq) | ||
12147 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
12148 | return error; | ||
12149 | } | ||
12150 | |||
12151 | /** | ||
12152 | * lpfc_sli4_fcf_rr_next_index_get - Get next eligible fcf record index | ||
12153 | * @phba: pointer to lpfc hba data structure. | ||
12154 | * | ||
12155 | * This routine is to get the next eligible FCF record index in a round | ||
12156 | * robin fashion. If the next eligible FCF record index equals to the | ||
12157 | * initial round robin FCF record index, LPFC_FCOE_FCF_NEXT_NONE (0xFFFF) | ||
12158 | * shall be returned, otherwise, the next eligible FCF record's index | ||
12159 | * shall be returned. | ||
12160 | **/ | ||
12161 | uint16_t | ||
12162 | lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba) | ||
12163 | { | ||
12164 | uint16_t next_fcf_index; | ||
12165 | |||
12166 | /* Search from the currently registered FCF index */ | ||
12167 | next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask, | ||
12168 | LPFC_SLI4_FCF_TBL_INDX_MAX, | ||
12169 | phba->fcf.current_rec.fcf_indx); | ||
12170 | /* Wrap around condition on phba->fcf.fcf_rr_bmask */ | ||
12171 | if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) | ||
12172 | next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask, | ||
12173 | LPFC_SLI4_FCF_TBL_INDX_MAX, 0); | ||
12174 | /* Round robin failover stop condition */ | ||
12175 | if (next_fcf_index == phba->fcf.fcf_rr_init_indx) | ||
12176 | return LPFC_FCOE_FCF_NEXT_NONE; | ||
12177 | |||
12178 | return next_fcf_index; | ||
12179 | } | ||
12180 | |||
12181 | /** | ||
12182 | * lpfc_sli4_fcf_rr_index_set - Set bmask with eligible fcf record index | ||
12183 | * @phba: pointer to lpfc hba data structure. | ||
12184 | * | ||
12185 | * This routine sets the FCF record index in to the eligible bmask for | ||
12186 | * round robin failover search. It checks to make sure that the index | ||
12187 | * does not go beyond the range of the driver allocated bmask dimension | ||
12188 | * before setting the bit. | ||
12189 | * | ||
12190 | * Returns 0 if the index bit successfully set, otherwise, it returns | ||
12191 | * -EINVAL. | ||
12192 | **/ | ||
12193 | int | ||
12194 | lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *phba, uint16_t fcf_index) | ||
12195 | { | ||
12196 | if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) { | ||
12197 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP, | ||
12198 | "2610 HBA FCF index reached driver's " | ||
12199 | "book keeping dimension: fcf_index:%d, " | ||
12200 | "driver_bmask_max:%d\n", | ||
12201 | fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX); | ||
12202 | return -EINVAL; | ||
12203 | } | ||
12204 | /* Set the eligible FCF record index bmask */ | ||
12205 | set_bit(fcf_index, phba->fcf.fcf_rr_bmask); | ||
12206 | |||
12207 | return 0; | ||
12208 | } | ||
12209 | |||
12210 | /** | ||
12211 | * lpfc_sli4_fcf_rr_index_set - Clear bmask from eligible fcf record index | ||
12212 | * @phba: pointer to lpfc hba data structure. | ||
12213 | * | ||
12214 | * This routine clears the FCF record index from the eligible bmask for | ||
12215 | * round robin failover search. It checks to make sure that the index | ||
12216 | * does not go beyond the range of the driver allocated bmask dimension | ||
12217 | * before clearing the bit. | ||
12218 | **/ | ||
12219 | void | ||
12220 | lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index) | ||
12221 | { | ||
12222 | if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) { | ||
12223 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP, | ||
12224 | "2762 HBA FCF index goes beyond driver's " | ||
12225 | "book keeping dimension: fcf_index:%d, " | ||
12226 | "driver_bmask_max:%d\n", | ||
12227 | fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX); | ||
12228 | return; | ||
12229 | } | ||
12230 | /* Clear the eligible FCF record index bmask */ | ||
12231 | clear_bit(fcf_index, phba->fcf.fcf_rr_bmask); | ||
12232 | } | ||
12233 | |||
12234 | /** | ||
11997 | * lpfc_mbx_cmpl_redisc_fcf_table - completion routine for rediscover FCF table | 12235 | * lpfc_mbx_cmpl_redisc_fcf_table - completion routine for rediscover FCF table |
11998 | * @phba: pointer to lpfc hba data structure. | 12236 | * @phba: pointer to lpfc hba data structure. |
11999 | * | 12237 | * |
@@ -12014,21 +12252,40 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) | |||
12014 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | 12252 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, |
12015 | &redisc_fcf->header.cfg_shdr.response); | 12253 | &redisc_fcf->header.cfg_shdr.response); |
12016 | if (shdr_status || shdr_add_status) { | 12254 | if (shdr_status || shdr_add_status) { |
12017 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 12255 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP, |
12018 | "2746 Requesting for FCF rediscovery failed " | 12256 | "2746 Requesting for FCF rediscovery failed " |
12019 | "status x%x add_status x%x\n", | 12257 | "status x%x add_status x%x\n", |
12020 | shdr_status, shdr_add_status); | 12258 | shdr_status, shdr_add_status); |
12021 | /* | 12259 | if (phba->fcf.fcf_flag & FCF_ACVL_DISC) { |
12022 | * Request failed, last resort to re-try current | 12260 | spin_lock_irq(&phba->hbalock); |
12023 | * registered FCF entry | 12261 | phba->fcf.fcf_flag &= ~FCF_ACVL_DISC; |
12024 | */ | 12262 | spin_unlock_irq(&phba->hbalock); |
12025 | lpfc_retry_pport_discovery(phba); | 12263 | /* |
12026 | } else | 12264 | * CVL event triggered FCF rediscover request failed, |
12265 | * last resort to re-try current registered FCF entry. | ||
12266 | */ | ||
12267 | lpfc_retry_pport_discovery(phba); | ||
12268 | } else { | ||
12269 | spin_lock_irq(&phba->hbalock); | ||
12270 | phba->fcf.fcf_flag &= ~FCF_DEAD_DISC; | ||
12271 | spin_unlock_irq(&phba->hbalock); | ||
12272 | /* | ||
12273 | * DEAD FCF event triggered FCF rediscover request | ||
12274 | * failed, last resort to fail over as a link down | ||
12275 | * to FCF registration. | ||
12276 | */ | ||
12277 | lpfc_sli4_fcf_dead_failthrough(phba); | ||
12278 | } | ||
12279 | } else { | ||
12280 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP, | ||
12281 | "2775 Start FCF rediscovery quiescent period " | ||
12282 | "wait timer before scaning FCF table\n"); | ||
12027 | /* | 12283 | /* |
12028 | * Start FCF rediscovery wait timer for pending FCF | 12284 | * Start FCF rediscovery wait timer for pending FCF |
12029 | * before rescan FCF record table. | 12285 | * before rescan FCF record table. |
12030 | */ | 12286 | */ |
12031 | lpfc_fcf_redisc_wait_start_timer(phba); | 12287 | lpfc_fcf_redisc_wait_start_timer(phba); |
12288 | } | ||
12032 | 12289 | ||
12033 | mempool_free(mbox, phba->mbox_mem_pool); | 12290 | mempool_free(mbox, phba->mbox_mem_pool); |
12034 | } | 12291 | } |
@@ -12047,6 +12304,9 @@ lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba) | |||
12047 | struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf; | 12304 | struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf; |
12048 | int rc, length; | 12305 | int rc, length; |
12049 | 12306 | ||
12307 | /* Cancel retry delay timers to all vports before FCF rediscover */ | ||
12308 | lpfc_cancel_all_vport_retry_delay_timer(phba); | ||
12309 | |||
12050 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 12310 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
12051 | if (!mbox) { | 12311 | if (!mbox) { |
12052 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 12312 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
@@ -12078,6 +12338,31 @@ lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba) | |||
12078 | } | 12338 | } |
12079 | 12339 | ||
12080 | /** | 12340 | /** |
12341 | * lpfc_sli4_fcf_dead_failthrough - Failthrough routine to fcf dead event | ||
12342 | * @phba: pointer to lpfc hba data structure. | ||
12343 | * | ||
12344 | * This function is the failover routine as a last resort to the FCF DEAD | ||
12345 | * event when driver failed to perform fast FCF failover. | ||
12346 | **/ | ||
12347 | void | ||
12348 | lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *phba) | ||
12349 | { | ||
12350 | uint32_t link_state; | ||
12351 | |||
12352 | /* | ||
12353 | * Last resort as FCF DEAD event failover will treat this as | ||
12354 | * a link down, but save the link state because we don't want | ||
12355 | * it to be changed to Link Down unless it is already down. | ||
12356 | */ | ||
12357 | link_state = phba->link_state; | ||
12358 | lpfc_linkdown(phba); | ||
12359 | phba->link_state = link_state; | ||
12360 | |||
12361 | /* Unregister FCF if no devices connected to it */ | ||
12362 | lpfc_unregister_unused_fcf(phba); | ||
12363 | } | ||
12364 | |||
12365 | /** | ||
12081 | * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled. | 12366 | * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled. |
12082 | * @phba: pointer to lpfc hba data structure. | 12367 | * @phba: pointer to lpfc hba data structure. |
12083 | * | 12368 | * |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index dfcf5437d1f5..b4a639c47616 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
@@ -62,6 +62,7 @@ struct lpfc_iocbq { | |||
62 | #define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */ | 62 | #define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */ |
63 | #define LPFC_EXCHANGE_BUSY 0x40 /* SLI4 hba reported XB in response */ | 63 | #define LPFC_EXCHANGE_BUSY 0x40 /* SLI4 hba reported XB in response */ |
64 | #define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */ | 64 | #define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */ |
65 | #define DSS_SECURITY_OP 0x100 /* security IO */ | ||
65 | 66 | ||
66 | #define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */ | 67 | #define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */ |
67 | #define LPFC_FIP_ELS_ID_SHIFT 14 | 68 | #define LPFC_FIP_ELS_ID_SHIFT 14 |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 86308836600f..4a35e7b9bc5b 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -153,15 +153,27 @@ struct lpfc_fcf { | |||
153 | #define FCF_REGISTERED 0x02 /* FCF registered with FW */ | 153 | #define FCF_REGISTERED 0x02 /* FCF registered with FW */ |
154 | #define FCF_SCAN_DONE 0x04 /* FCF table scan done */ | 154 | #define FCF_SCAN_DONE 0x04 /* FCF table scan done */ |
155 | #define FCF_IN_USE 0x08 /* Atleast one discovery completed */ | 155 | #define FCF_IN_USE 0x08 /* Atleast one discovery completed */ |
156 | #define FCF_REDISC_PEND 0x10 /* FCF rediscovery pending */ | 156 | #define FCF_INIT_DISC 0x10 /* Initial FCF discovery */ |
157 | #define FCF_REDISC_EVT 0x20 /* FCF rediscovery event to worker thread */ | 157 | #define FCF_DEAD_DISC 0x20 /* FCF DEAD fast FCF failover discovery */ |
158 | #define FCF_REDISC_FOV 0x40 /* Post FCF rediscovery fast failover */ | 158 | #define FCF_ACVL_DISC 0x40 /* All CVL fast FCF failover discovery */ |
159 | #define FCF_DISCOVERY (FCF_INIT_DISC | FCF_DEAD_DISC | FCF_ACVL_DISC) | ||
160 | #define FCF_REDISC_PEND 0x80 /* FCF rediscovery pending */ | ||
161 | #define FCF_REDISC_EVT 0x100 /* FCF rediscovery event to worker thread */ | ||
162 | #define FCF_REDISC_FOV 0x200 /* Post FCF rediscovery fast failover */ | ||
159 | uint32_t addr_mode; | 163 | uint32_t addr_mode; |
164 | uint16_t fcf_rr_init_indx; | ||
160 | struct lpfc_fcf_rec current_rec; | 165 | struct lpfc_fcf_rec current_rec; |
161 | struct lpfc_fcf_rec failover_rec; | 166 | struct lpfc_fcf_rec failover_rec; |
162 | struct timer_list redisc_wait; | 167 | struct timer_list redisc_wait; |
168 | unsigned long *fcf_rr_bmask; /* Eligible FCF indexes for RR failover */ | ||
163 | }; | 169 | }; |
164 | 170 | ||
171 | /* | ||
172 | * Maximum FCF table index, it is for driver internal book keeping, it | ||
173 | * just needs to be no less than the supported HBA's FCF table size. | ||
174 | */ | ||
175 | #define LPFC_SLI4_FCF_TBL_INDX_MAX 32 | ||
176 | |||
165 | #define LPFC_REGION23_SIGNATURE "RG23" | 177 | #define LPFC_REGION23_SIGNATURE "RG23" |
166 | #define LPFC_REGION23_VERSION 1 | 178 | #define LPFC_REGION23_VERSION 1 |
167 | #define LPFC_REGION23_LAST_REC 0xff | 179 | #define LPFC_REGION23_LAST_REC 0xff |
@@ -431,11 +443,18 @@ enum lpfc_sge_type { | |||
431 | SCSI_BUFF_TYPE | 443 | SCSI_BUFF_TYPE |
432 | }; | 444 | }; |
433 | 445 | ||
446 | enum lpfc_sgl_state { | ||
447 | SGL_FREED, | ||
448 | SGL_ALLOCATED, | ||
449 | SGL_XRI_ABORTED | ||
450 | }; | ||
451 | |||
434 | struct lpfc_sglq { | 452 | struct lpfc_sglq { |
435 | /* lpfc_sglqs are used in double linked lists */ | 453 | /* lpfc_sglqs are used in double linked lists */ |
436 | struct list_head list; | 454 | struct list_head list; |
437 | struct list_head clist; | 455 | struct list_head clist; |
438 | enum lpfc_sge_type buff_type; /* is this a scsi sgl */ | 456 | enum lpfc_sge_type buff_type; /* is this a scsi sgl */ |
457 | enum lpfc_sgl_state state; | ||
439 | uint16_t iotag; /* pre-assigned IO tag */ | 458 | uint16_t iotag; /* pre-assigned IO tag */ |
440 | uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */ | 459 | uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */ |
441 | struct sli4_sge *sgl; /* pre-assigned SGL */ | 460 | struct sli4_sge *sgl; /* pre-assigned SGL */ |
@@ -463,8 +482,8 @@ void lpfc_sli4_mbox_cmd_free(struct lpfc_hba *, struct lpfcMboxq *); | |||
463 | void lpfc_sli4_mbx_sge_set(struct lpfcMboxq *, uint32_t, dma_addr_t, uint32_t); | 482 | void lpfc_sli4_mbx_sge_set(struct lpfcMboxq *, uint32_t, dma_addr_t, uint32_t); |
464 | void lpfc_sli4_mbx_sge_get(struct lpfcMboxq *, uint32_t, | 483 | void lpfc_sli4_mbx_sge_get(struct lpfcMboxq *, uint32_t, |
465 | struct lpfc_mbx_sge *); | 484 | struct lpfc_mbx_sge *); |
466 | int lpfc_sli4_mbx_read_fcf_record(struct lpfc_hba *, struct lpfcMboxq *, | 485 | int lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *, struct lpfcMboxq *, |
467 | uint16_t); | 486 | uint16_t); |
468 | 487 | ||
469 | void lpfc_sli4_hba_reset(struct lpfc_hba *); | 488 | void lpfc_sli4_hba_reset(struct lpfc_hba *); |
470 | struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t, | 489 | struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t, |
@@ -523,8 +542,13 @@ int lpfc_sli4_init_vpi(struct lpfc_hba *, uint16_t); | |||
523 | uint32_t lpfc_sli4_cq_release(struct lpfc_queue *, bool); | 542 | uint32_t lpfc_sli4_cq_release(struct lpfc_queue *, bool); |
524 | uint32_t lpfc_sli4_eq_release(struct lpfc_queue *, bool); | 543 | uint32_t lpfc_sli4_eq_release(struct lpfc_queue *, bool); |
525 | void lpfc_sli4_fcfi_unreg(struct lpfc_hba *, uint16_t); | 544 | void lpfc_sli4_fcfi_unreg(struct lpfc_hba *, uint16_t); |
526 | int lpfc_sli4_read_fcf_record(struct lpfc_hba *, uint16_t); | 545 | int lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *, uint16_t); |
527 | void lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *, LPFC_MBOXQ_t *); | 546 | int lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *, uint16_t); |
547 | int lpfc_sli4_read_fcf_rec(struct lpfc_hba *, uint16_t); | ||
548 | void lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *); | ||
549 | void lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *); | ||
550 | void lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *); | ||
551 | int lpfc_sli4_unregister_fcf(struct lpfc_hba *); | ||
528 | int lpfc_sli4_post_status_check(struct lpfc_hba *); | 552 | int lpfc_sli4_post_status_check(struct lpfc_hba *); |
529 | uint8_t lpfc_sli4_mbox_opcode_get(struct lpfc_hba *, struct lpfcMboxq *); | 553 | uint8_t lpfc_sli4_mbox_opcode_get(struct lpfc_hba *, struct lpfcMboxq *); |
530 | 554 | ||
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index ac276aa46fba..013deec5dae8 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
@@ -18,7 +18,7 @@ | |||
18 | * included with this package. * | 18 | * included with this package. * |
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | #define LPFC_DRIVER_VERSION "8.3.9" | 21 | #define LPFC_DRIVER_VERSION "8.3.10" |
22 | #define LPFC_DRIVER_NAME "lpfc" | 22 | #define LPFC_DRIVER_NAME "lpfc" |
23 | #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" | 23 | #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" |
24 | #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" | 24 | #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" |
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index dc86e873102a..869f76cbc58a 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -123,7 +123,12 @@ lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
123 | } | 123 | } |
124 | mb = &pmb->u.mb; | 124 | mb = &pmb->u.mb; |
125 | 125 | ||
126 | lpfc_read_sparam(phba, pmb, vport->vpi); | 126 | rc = lpfc_read_sparam(phba, pmb, vport->vpi); |
127 | if (rc) { | ||
128 | mempool_free(pmb, phba->mbox_mem_pool); | ||
129 | return -ENOMEM; | ||
130 | } | ||
131 | |||
127 | /* | 132 | /* |
128 | * Grab buffer pointer and clear context1 so we can use | 133 | * Grab buffer pointer and clear context1 so we can use |
129 | * lpfc_sli_issue_box_wait | 134 | * lpfc_sli_issue_box_wait |
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 24223473f573..60de85091502 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c | |||
@@ -1433,6 +1433,10 @@ int osd_finalize_request(struct osd_request *or, | |||
1433 | cdbh->command_specific_options |= or->attributes_mode; | 1433 | cdbh->command_specific_options |= or->attributes_mode; |
1434 | if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) { | 1434 | if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) { |
1435 | ret = _osd_req_finalize_attr_page(or); | 1435 | ret = _osd_req_finalize_attr_page(or); |
1436 | if (ret) { | ||
1437 | OSD_DEBUG("_osd_req_finalize_attr_page failed\n"); | ||
1438 | return ret; | ||
1439 | } | ||
1436 | } else { | 1440 | } else { |
1437 | /* TODO: I think that for the GET_ATTR command these 2 should | 1441 | /* TODO: I think that for the GET_ATTR command these 2 should |
1438 | * be reversed to keep them in execution order (for embeded | 1442 | * be reversed to keep them in execution order (for embeded |
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index c2341af587a3..021246454872 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c | |||
@@ -1717,6 +1717,7 @@ static int nsp_cs_config(struct pcmcia_device *link) | |||
1717 | cfg_mem->data = data; | 1717 | cfg_mem->data = data; |
1718 | 1718 | ||
1719 | ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem); | 1719 | ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem); |
1720 | if (ret) | ||
1720 | goto cs_failed; | 1721 | goto cs_failed; |
1721 | 1722 | ||
1722 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | 1723 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { |
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c index bd88349b8526..2c146b44d95f 100644 --- a/drivers/scsi/raid_class.c +++ b/drivers/scsi/raid_class.c | |||
@@ -63,6 +63,7 @@ static int raid_match(struct attribute_container *cont, struct device *dev) | |||
63 | * emulated RAID devices, so start with SCSI */ | 63 | * emulated RAID devices, so start with SCSI */ |
64 | struct raid_internal *i = ac_to_raid_internal(cont); | 64 | struct raid_internal *i = ac_to_raid_internal(cont); |
65 | 65 | ||
66 | #if defined(CONFIG_SCSI) || defined(CONFIG_SCSI_MODULE) | ||
66 | if (scsi_is_sdev_device(dev)) { | 67 | if (scsi_is_sdev_device(dev)) { |
67 | struct scsi_device *sdev = to_scsi_device(dev); | 68 | struct scsi_device *sdev = to_scsi_device(dev); |
68 | 69 | ||
@@ -71,6 +72,7 @@ static int raid_match(struct attribute_container *cont, struct device *dev) | |||
71 | 72 | ||
72 | return i->f->is_raid(dev); | 73 | return i->f->is_raid(dev); |
73 | } | 74 | } |
75 | #endif | ||
74 | /* FIXME: look at other subsystems too */ | 76 | /* FIXME: look at other subsystems too */ |
75 | return 0; | 77 | return 0; |
76 | } | 78 | } |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 79660ee3e211..1d5b72173dd8 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -1232,6 +1232,15 @@ store_fc_vport_delete(struct device *dev, struct device_attribute *attr, | |||
1232 | { | 1232 | { |
1233 | struct fc_vport *vport = transport_class_to_vport(dev); | 1233 | struct fc_vport *vport = transport_class_to_vport(dev); |
1234 | struct Scsi_Host *shost = vport_to_shost(vport); | 1234 | struct Scsi_Host *shost = vport_to_shost(vport); |
1235 | unsigned long flags; | ||
1236 | |||
1237 | spin_lock_irqsave(shost->host_lock, flags); | ||
1238 | if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) { | ||
1239 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1240 | return -EBUSY; | ||
1241 | } | ||
1242 | vport->flags |= FC_VPORT_DELETING; | ||
1243 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1235 | 1244 | ||
1236 | fc_queue_work(shost, &vport->vport_delete_work); | 1245 | fc_queue_work(shost, &vport->vport_delete_work); |
1237 | return count; | 1246 | return count; |
@@ -1821,6 +1830,9 @@ store_fc_host_vport_delete(struct device *dev, struct device_attribute *attr, | |||
1821 | list_for_each_entry(vport, &fc_host->vports, peers) { | 1830 | list_for_each_entry(vport, &fc_host->vports, peers) { |
1822 | if ((vport->channel == 0) && | 1831 | if ((vport->channel == 0) && |
1823 | (vport->port_name == wwpn) && (vport->node_name == wwnn)) { | 1832 | (vport->port_name == wwpn) && (vport->node_name == wwnn)) { |
1833 | if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) | ||
1834 | break; | ||
1835 | vport->flags |= FC_VPORT_DELETING; | ||
1824 | match = 1; | 1836 | match = 1; |
1825 | break; | 1837 | break; |
1826 | } | 1838 | } |
@@ -3370,18 +3382,6 @@ fc_vport_terminate(struct fc_vport *vport) | |||
3370 | unsigned long flags; | 3382 | unsigned long flags; |
3371 | int stat; | 3383 | int stat; |
3372 | 3384 | ||
3373 | spin_lock_irqsave(shost->host_lock, flags); | ||
3374 | if (vport->flags & FC_VPORT_CREATING) { | ||
3375 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
3376 | return -EBUSY; | ||
3377 | } | ||
3378 | if (vport->flags & (FC_VPORT_DEL)) { | ||
3379 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
3380 | return -EALREADY; | ||
3381 | } | ||
3382 | vport->flags |= FC_VPORT_DELETING; | ||
3383 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
3384 | |||
3385 | if (i->f->vport_delete) | 3385 | if (i->f->vport_delete) |
3386 | stat = i->f->vport_delete(vport); | 3386 | stat = i->f->vport_delete(vport); |
3387 | else | 3387 | else |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 83881dfb33c0..7b75c8a2a49d 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1948,7 +1948,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) | |||
1948 | { | 1948 | { |
1949 | struct request_queue *q = sdkp->disk->queue; | 1949 | struct request_queue *q = sdkp->disk->queue; |
1950 | unsigned int sector_sz = sdkp->device->sector_size; | 1950 | unsigned int sector_sz = sdkp->device->sector_size; |
1951 | const int vpd_len = 32; | 1951 | const int vpd_len = 64; |
1952 | unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL); | 1952 | unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL); |
1953 | 1953 | ||
1954 | if (!buffer || | 1954 | if (!buffer || |
@@ -1998,7 +1998,7 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp) | |||
1998 | { | 1998 | { |
1999 | unsigned char *buffer; | 1999 | unsigned char *buffer; |
2000 | u16 rot; | 2000 | u16 rot; |
2001 | const int vpd_len = 32; | 2001 | const int vpd_len = 64; |
2002 | 2002 | ||
2003 | buffer = kmalloc(vpd_len, GFP_KERNEL); | 2003 | buffer = kmalloc(vpd_len, GFP_KERNEL); |
2004 | 2004 | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index a9802e76b5fa..722eac18f382 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c | |||
@@ -61,7 +61,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, | |||
61 | void __iomem *pram; | 61 | void __iomem *pram; |
62 | unsigned long offset; | 62 | unsigned long offset; |
63 | struct resource res; | 63 | struct resource res; |
64 | unsigned long len; | 64 | resource_size_t len; |
65 | 65 | ||
66 | /* Don't remap parameter RAM if it has already been initialized | 66 | /* Don't remap parameter RAM if it has already been initialized |
67 | * during console setup. | 67 | * during console setup. |
@@ -74,7 +74,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, | |||
74 | if (of_address_to_resource(np, 1, &res)) | 74 | if (of_address_to_resource(np, 1, &res)) |
75 | return NULL; | 75 | return NULL; |
76 | 76 | ||
77 | len = 1 + res.end - res.start; | 77 | len = resource_size(&res); |
78 | pram = ioremap(res.start, len); | 78 | pram = ioremap(res.start, len); |
79 | if (!pram) | 79 | if (!pram) |
80 | return NULL; | 80 | return NULL; |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index e91db4b38012..175d202ab37e 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -745,6 +745,7 @@ static struct pcmcia_device_id serial_ids[] = { | |||
745 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), | 745 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), |
746 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), | 746 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), |
747 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), | 747 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), |
748 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e), | ||
748 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), | 749 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), |
749 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), | 750 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), |
750 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), | 751 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 980f39449ee5..f7b9aff88f4a 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <linux/list.h> | 50 | #include <linux/list.h> |
51 | #include <linux/dmaengine.h> | 51 | #include <linux/dmaengine.h> |
52 | #include <linux/scatterlist.h> | 52 | #include <linux/scatterlist.h> |
53 | #include <linux/timer.h> | ||
54 | 53 | ||
55 | #ifdef CONFIG_SUPERH | 54 | #ifdef CONFIG_SUPERH |
56 | #include <asm/sh_bios.h> | 55 | #include <asm/sh_bios.h> |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index d514e28d0755..d2e0321049e2 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -474,7 +474,7 @@ static void sunsab_stop_rx(struct uart_port *port) | |||
474 | { | 474 | { |
475 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | 475 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; |
476 | 476 | ||
477 | up->interrupt_mask0 |= SAB82532_ISR0_TCD; | 477 | up->interrupt_mask0 |= SAB82532_IMR0_TCD; |
478 | writeb(up->interrupt_mask1, &up->regs->w.imr0); | 478 | writeb(up->interrupt_mask1, &up->regs->w.imr0); |
479 | } | 479 | } |
480 | 480 | ||
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index ab2ab3c81834..f0a6c61b17f7 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <asm/io.h> | 21 | #include <asm/io.h> |
22 | #if defined(CONFIG_OF) | 22 | #if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)) |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/of_device.h> | 24 | #include <linux/of_device.h> |
25 | #include <linux/of_platform.h> | 25 | #include <linux/of_platform.h> |
@@ -581,7 +581,7 @@ static struct platform_driver ulite_platform_driver = { | |||
581 | /* --------------------------------------------------------------------- | 581 | /* --------------------------------------------------------------------- |
582 | * OF bus bindings | 582 | * OF bus bindings |
583 | */ | 583 | */ |
584 | #if defined(CONFIG_OF) | 584 | #if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)) |
585 | static int __devinit | 585 | static int __devinit |
586 | ulite_of_probe(struct of_device *op, const struct of_device_id *match) | 586 | ulite_of_probe(struct of_device *op, const struct of_device_id *match) |
587 | { | 587 | { |
@@ -631,11 +631,11 @@ static inline void __exit ulite_of_unregister(void) | |||
631 | { | 631 | { |
632 | of_unregister_platform_driver(&ulite_of_driver); | 632 | of_unregister_platform_driver(&ulite_of_driver); |
633 | } | 633 | } |
634 | #else /* CONFIG_OF */ | 634 | #else /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */ |
635 | /* CONFIG_OF not enabled; do nothing helpers */ | 635 | /* Appropriate config not enabled; do nothing helpers */ |
636 | static inline int __init ulite_of_register(void) { return 0; } | 636 | static inline int __init ulite_of_register(void) { return 0; } |
637 | static inline void __exit ulite_of_unregister(void) { } | 637 | static inline void __exit ulite_of_unregister(void) { } |
638 | #endif /* CONFIG_OF */ | 638 | #endif /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */ |
639 | 639 | ||
640 | /* --------------------------------------------------------------------- | 640 | /* --------------------------------------------------------------------- |
641 | * Module setup/teardown | 641 | * Module setup/teardown |
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index c2750391fd34..a3d8677af6a5 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Shared interrupt handling code for IPR and INTC2 types of IRQs. | 2 | * Shared interrupt handling code for IPR and INTC2 types of IRQs. |
3 | * | 3 | * |
4 | * Copyright (C) 2007, 2008 Magnus Damm | 4 | * Copyright (C) 2007, 2008 Magnus Damm |
5 | * Copyright (C) 2009 Paul Mundt | 5 | * Copyright (C) 2009, 2010 Paul Mundt |
6 | * | 6 | * |
7 | * Based on intc2.c and ipr.c | 7 | * Based on intc2.c and ipr.c |
8 | * | 8 | * |
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/list.h> | 26 | #include <linux/list.h> |
27 | #include <linux/topology.h> | 27 | #include <linux/topology.h> |
28 | #include <linux/bitmap.h> | 28 | #include <linux/bitmap.h> |
29 | #include <linux/cpumask.h> | ||
29 | 30 | ||
30 | #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ | 31 | #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ |
31 | ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ | 32 | ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ |
@@ -234,6 +235,10 @@ static inline void _intc_enable(unsigned int irq, unsigned long handle) | |||
234 | unsigned int cpu; | 235 | unsigned int cpu; |
235 | 236 | ||
236 | for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { | 237 | for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { |
238 | #ifdef CONFIG_SMP | ||
239 | if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity)) | ||
240 | continue; | ||
241 | #endif | ||
237 | addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu); | 242 | addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu); |
238 | intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\ | 243 | intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\ |
239 | [_INTC_FN(handle)], irq); | 244 | [_INTC_FN(handle)], irq); |
@@ -253,6 +258,10 @@ static void intc_disable(unsigned int irq) | |||
253 | unsigned int cpu; | 258 | unsigned int cpu; |
254 | 259 | ||
255 | for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { | 260 | for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { |
261 | #ifdef CONFIG_SMP | ||
262 | if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity)) | ||
263 | continue; | ||
264 | #endif | ||
256 | addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); | 265 | addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); |
257 | intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\ | 266 | intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\ |
258 | [_INTC_FN(handle)], irq); | 267 | [_INTC_FN(handle)], irq); |
@@ -301,6 +310,23 @@ static int intc_set_wake(unsigned int irq, unsigned int on) | |||
301 | return 0; /* allow wakeup, but setup hardware in intc_suspend() */ | 310 | return 0; /* allow wakeup, but setup hardware in intc_suspend() */ |
302 | } | 311 | } |
303 | 312 | ||
313 | #ifdef CONFIG_SMP | ||
314 | /* | ||
315 | * This is held with the irq desc lock held, so we don't require any | ||
316 | * additional locking here at the intc desc level. The affinity mask is | ||
317 | * later tested in the enable/disable paths. | ||
318 | */ | ||
319 | static int intc_set_affinity(unsigned int irq, const struct cpumask *cpumask) | ||
320 | { | ||
321 | if (!cpumask_intersects(cpumask, cpu_online_mask)) | ||
322 | return -1; | ||
323 | |||
324 | cpumask_copy(irq_to_desc(irq)->affinity, cpumask); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | #endif | ||
329 | |||
304 | static void intc_mask_ack(unsigned int irq) | 330 | static void intc_mask_ack(unsigned int irq) |
305 | { | 331 | { |
306 | struct intc_desc_int *d = get_intc_desc(irq); | 332 | struct intc_desc_int *d = get_intc_desc(irq); |
@@ -847,6 +873,9 @@ void __init register_intc_controller(struct intc_desc *desc) | |||
847 | d->chip.shutdown = intc_disable; | 873 | d->chip.shutdown = intc_disable; |
848 | d->chip.set_type = intc_set_sense; | 874 | d->chip.set_type = intc_set_sense; |
849 | d->chip.set_wake = intc_set_wake; | 875 | d->chip.set_wake = intc_set_wake; |
876 | #ifdef CONFIG_SMP | ||
877 | d->chip.set_affinity = intc_set_affinity; | ||
878 | #endif | ||
850 | 879 | ||
851 | if (hw->ack_regs) { | 880 | if (hw->ack_regs) { |
852 | for (i = 0; i < hw->nr_ack_regs; i++) | 881 | for (i = 0; i < hw->nr_ack_regs; i++) |
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 715c518b1b68..4dd786b99b8b 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c | |||
@@ -578,6 +578,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, | |||
578 | struct spi_master *spi_cntrl; | 578 | struct spi_master *spi_cntrl; |
579 | u32 l = 0, div = 0; | 579 | u32 l = 0, div = 0; |
580 | u8 word_len = spi->bits_per_word; | 580 | u8 word_len = spi->bits_per_word; |
581 | u32 speed_hz = spi->max_speed_hz; | ||
581 | 582 | ||
582 | mcspi = spi_master_get_devdata(spi->master); | 583 | mcspi = spi_master_get_devdata(spi->master); |
583 | spi_cntrl = mcspi->master; | 584 | spi_cntrl = mcspi->master; |
@@ -587,9 +588,12 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, | |||
587 | 588 | ||
588 | cs->word_len = word_len; | 589 | cs->word_len = word_len; |
589 | 590 | ||
590 | if (spi->max_speed_hz) { | 591 | if (t && t->speed_hz) |
592 | speed_hz = t->speed_hz; | ||
593 | |||
594 | if (speed_hz) { | ||
591 | while (div <= 15 && (OMAP2_MCSPI_MAX_FREQ / (1 << div)) | 595 | while (div <= 15 && (OMAP2_MCSPI_MAX_FREQ / (1 << div)) |
592 | > spi->max_speed_hz) | 596 | > speed_hz) |
593 | div++; | 597 | div++; |
594 | } else | 598 | } else |
595 | div = 15; | 599 | div = 15; |
@@ -751,11 +755,13 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) | |||
751 | mcspi = spi_master_get_devdata(spi->master); | 755 | mcspi = spi_master_get_devdata(spi->master); |
752 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 756 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
753 | 757 | ||
754 | /* Unlink controller state from context save list */ | 758 | if (spi->controller_state) { |
755 | cs = spi->controller_state; | 759 | /* Unlink controller state from context save list */ |
756 | list_del(&cs->node); | 760 | cs = spi->controller_state; |
761 | list_del(&cs->node); | ||
757 | 762 | ||
758 | kfree(spi->controller_state); | 763 | kfree(spi->controller_state); |
764 | } | ||
759 | 765 | ||
760 | if (mcspi_dma->dma_rx_channel != -1) { | 766 | if (mcspi_dma->dma_rx_channel != -1) { |
761 | omap_free_dma(mcspi_dma->dma_rx_channel); | 767 | omap_free_dma(mcspi_dma->dma_rx_channel); |
diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index dd7ea4c075db..eb44b60e1eb5 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c | |||
@@ -394,6 +394,7 @@ MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); | |||
394 | 394 | ||
395 | static int __init samsung_init(void) | 395 | static int __init samsung_init(void) |
396 | { | 396 | { |
397 | struct backlight_properties props; | ||
397 | struct sabi_retval sretval; | 398 | struct sabi_retval sretval; |
398 | const char *testStr = "SECLINUX"; | 399 | const char *testStr = "SECLINUX"; |
399 | void __iomem *memcheck; | 400 | void __iomem *memcheck; |
@@ -486,12 +487,14 @@ static int __init samsung_init(void) | |||
486 | goto error_no_platform; | 487 | goto error_no_platform; |
487 | 488 | ||
488 | /* create a backlight device to talk to this one */ | 489 | /* create a backlight device to talk to this one */ |
490 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
491 | props.max_brightness = MAX_BRIGHT; | ||
489 | backlight_device = backlight_device_register("samsung", &sdev->dev, | 492 | backlight_device = backlight_device_register("samsung", &sdev->dev, |
490 | NULL, &backlight_ops); | 493 | NULL, &backlight_ops, |
494 | &props); | ||
491 | if (IS_ERR(backlight_device)) | 495 | if (IS_ERR(backlight_device)) |
492 | goto error_no_backlight; | 496 | goto error_no_backlight; |
493 | 497 | ||
494 | backlight_device->props.max_brightness = MAX_BRIGHT; | ||
495 | backlight_device->props.brightness = read_brightness(); | 498 | backlight_device->props.brightness = read_brightness(); |
496 | backlight_device->props.power = FB_BLANK_UNBLANK; | 499 | backlight_device->props.power = FB_BLANK_UNBLANK; |
497 | backlight_update_status(backlight_device); | 500 | backlight_update_status(backlight_device); |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 975d556b4787..be6331e2c276 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1441,7 +1441,7 @@ static int acm_resume(struct usb_interface *intf) | |||
1441 | wb = acm->delayed_wb; | 1441 | wb = acm->delayed_wb; |
1442 | acm->delayed_wb = NULL; | 1442 | acm->delayed_wb = NULL; |
1443 | spin_unlock_irq(&acm->write_lock); | 1443 | spin_unlock_irq(&acm->write_lock); |
1444 | acm_start_wb(acm, acm->delayed_wb); | 1444 | acm_start_wb(acm, wb); |
1445 | } else { | 1445 | } else { |
1446 | spin_unlock_irq(&acm->write_lock); | 1446 | spin_unlock_irq(&acm->write_lock); |
1447 | } | 1447 | } |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 18aafcb08fc8..189141ca4e05 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -52,7 +52,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); | |||
52 | #define WDM_READ 4 | 52 | #define WDM_READ 4 |
53 | #define WDM_INT_STALL 5 | 53 | #define WDM_INT_STALL 5 |
54 | #define WDM_POLL_RUNNING 6 | 54 | #define WDM_POLL_RUNNING 6 |
55 | 55 | #define WDM_RESPONDING 7 | |
56 | #define WDM_SUSPENDING 8 | ||
56 | 57 | ||
57 | #define WDM_MAX 16 | 58 | #define WDM_MAX 16 |
58 | 59 | ||
@@ -87,9 +88,7 @@ struct wdm_device { | |||
87 | int count; | 88 | int count; |
88 | dma_addr_t shandle; | 89 | dma_addr_t shandle; |
89 | dma_addr_t ihandle; | 90 | dma_addr_t ihandle; |
90 | struct mutex wlock; | 91 | struct mutex lock; |
91 | struct mutex rlock; | ||
92 | struct mutex plock; | ||
93 | wait_queue_head_t wait; | 92 | wait_queue_head_t wait; |
94 | struct work_struct rxwork; | 93 | struct work_struct rxwork; |
95 | int werr; | 94 | int werr; |
@@ -117,21 +116,22 @@ static void wdm_in_callback(struct urb *urb) | |||
117 | int status = urb->status; | 116 | int status = urb->status; |
118 | 117 | ||
119 | spin_lock(&desc->iuspin); | 118 | spin_lock(&desc->iuspin); |
119 | clear_bit(WDM_RESPONDING, &desc->flags); | ||
120 | 120 | ||
121 | if (status) { | 121 | if (status) { |
122 | switch (status) { | 122 | switch (status) { |
123 | case -ENOENT: | 123 | case -ENOENT: |
124 | dev_dbg(&desc->intf->dev, | 124 | dev_dbg(&desc->intf->dev, |
125 | "nonzero urb status received: -ENOENT"); | 125 | "nonzero urb status received: -ENOENT"); |
126 | break; | 126 | goto skip_error; |
127 | case -ECONNRESET: | 127 | case -ECONNRESET: |
128 | dev_dbg(&desc->intf->dev, | 128 | dev_dbg(&desc->intf->dev, |
129 | "nonzero urb status received: -ECONNRESET"); | 129 | "nonzero urb status received: -ECONNRESET"); |
130 | break; | 130 | goto skip_error; |
131 | case -ESHUTDOWN: | 131 | case -ESHUTDOWN: |
132 | dev_dbg(&desc->intf->dev, | 132 | dev_dbg(&desc->intf->dev, |
133 | "nonzero urb status received: -ESHUTDOWN"); | 133 | "nonzero urb status received: -ESHUTDOWN"); |
134 | break; | 134 | goto skip_error; |
135 | case -EPIPE: | 135 | case -EPIPE: |
136 | dev_err(&desc->intf->dev, | 136 | dev_err(&desc->intf->dev, |
137 | "nonzero urb status received: -EPIPE\n"); | 137 | "nonzero urb status received: -EPIPE\n"); |
@@ -147,6 +147,7 @@ static void wdm_in_callback(struct urb *urb) | |||
147 | desc->reslength = urb->actual_length; | 147 | desc->reslength = urb->actual_length; |
148 | memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); | 148 | memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); |
149 | desc->length += desc->reslength; | 149 | desc->length += desc->reslength; |
150 | skip_error: | ||
150 | wake_up(&desc->wait); | 151 | wake_up(&desc->wait); |
151 | 152 | ||
152 | set_bit(WDM_READ, &desc->flags); | 153 | set_bit(WDM_READ, &desc->flags); |
@@ -229,13 +230,16 @@ static void wdm_int_callback(struct urb *urb) | |||
229 | desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 230 | desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
230 | spin_lock(&desc->iuspin); | 231 | spin_lock(&desc->iuspin); |
231 | clear_bit(WDM_READ, &desc->flags); | 232 | clear_bit(WDM_READ, &desc->flags); |
232 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { | 233 | set_bit(WDM_RESPONDING, &desc->flags); |
234 | if (!test_bit(WDM_DISCONNECTING, &desc->flags) | ||
235 | && !test_bit(WDM_SUSPENDING, &desc->flags)) { | ||
233 | rv = usb_submit_urb(desc->response, GFP_ATOMIC); | 236 | rv = usb_submit_urb(desc->response, GFP_ATOMIC); |
234 | dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", | 237 | dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", |
235 | __func__, rv); | 238 | __func__, rv); |
236 | } | 239 | } |
237 | spin_unlock(&desc->iuspin); | 240 | spin_unlock(&desc->iuspin); |
238 | if (rv < 0) { | 241 | if (rv < 0) { |
242 | clear_bit(WDM_RESPONDING, &desc->flags); | ||
239 | if (rv == -EPERM) | 243 | if (rv == -EPERM) |
240 | return; | 244 | return; |
241 | if (rv == -ENOMEM) { | 245 | if (rv == -ENOMEM) { |
@@ -305,14 +309,38 @@ static ssize_t wdm_write | |||
305 | if (we < 0) | 309 | if (we < 0) |
306 | return -EIO; | 310 | return -EIO; |
307 | 311 | ||
308 | r = mutex_lock_interruptible(&desc->wlock); /* concurrent writes */ | 312 | desc->outbuf = buf = kmalloc(count, GFP_KERNEL); |
313 | if (!buf) { | ||
314 | rv = -ENOMEM; | ||
315 | goto outnl; | ||
316 | } | ||
317 | |||
318 | r = copy_from_user(buf, buffer, count); | ||
319 | if (r > 0) { | ||
320 | kfree(buf); | ||
321 | rv = -EFAULT; | ||
322 | goto outnl; | ||
323 | } | ||
324 | |||
325 | /* concurrent writes and disconnect */ | ||
326 | r = mutex_lock_interruptible(&desc->lock); | ||
309 | rv = -ERESTARTSYS; | 327 | rv = -ERESTARTSYS; |
310 | if (r) | 328 | if (r) { |
329 | kfree(buf); | ||
311 | goto outnl; | 330 | goto outnl; |
331 | } | ||
332 | |||
333 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
334 | kfree(buf); | ||
335 | rv = -ENODEV; | ||
336 | goto outnp; | ||
337 | } | ||
312 | 338 | ||
313 | r = usb_autopm_get_interface(desc->intf); | 339 | r = usb_autopm_get_interface(desc->intf); |
314 | if (r < 0) | 340 | if (r < 0) { |
341 | kfree(buf); | ||
315 | goto outnp; | 342 | goto outnp; |
343 | } | ||
316 | 344 | ||
317 | if (!file->f_flags && O_NONBLOCK) | 345 | if (!file->f_flags && O_NONBLOCK) |
318 | r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, | 346 | r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, |
@@ -320,24 +348,8 @@ static ssize_t wdm_write | |||
320 | else | 348 | else |
321 | if (test_bit(WDM_IN_USE, &desc->flags)) | 349 | if (test_bit(WDM_IN_USE, &desc->flags)) |
322 | r = -EAGAIN; | 350 | r = -EAGAIN; |
323 | if (r < 0) | 351 | if (r < 0) { |
324 | goto out; | ||
325 | |||
326 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
327 | rv = -ENODEV; | ||
328 | goto out; | ||
329 | } | ||
330 | |||
331 | desc->outbuf = buf = kmalloc(count, GFP_KERNEL); | ||
332 | if (!buf) { | ||
333 | rv = -ENOMEM; | ||
334 | goto out; | ||
335 | } | ||
336 | |||
337 | r = copy_from_user(buf, buffer, count); | ||
338 | if (r > 0) { | ||
339 | kfree(buf); | 352 | kfree(buf); |
340 | rv = -EFAULT; | ||
341 | goto out; | 353 | goto out; |
342 | } | 354 | } |
343 | 355 | ||
@@ -374,7 +386,7 @@ static ssize_t wdm_write | |||
374 | out: | 386 | out: |
375 | usb_autopm_put_interface(desc->intf); | 387 | usb_autopm_put_interface(desc->intf); |
376 | outnp: | 388 | outnp: |
377 | mutex_unlock(&desc->wlock); | 389 | mutex_unlock(&desc->lock); |
378 | outnl: | 390 | outnl: |
379 | return rv < 0 ? rv : count; | 391 | return rv < 0 ? rv : count; |
380 | } | 392 | } |
@@ -387,7 +399,7 @@ static ssize_t wdm_read | |||
387 | struct wdm_device *desc = file->private_data; | 399 | struct wdm_device *desc = file->private_data; |
388 | 400 | ||
389 | 401 | ||
390 | rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */ | 402 | rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */ |
391 | if (rv < 0) | 403 | if (rv < 0) |
392 | return -ERESTARTSYS; | 404 | return -ERESTARTSYS; |
393 | 405 | ||
@@ -424,11 +436,8 @@ retry: | |||
424 | spin_lock_irq(&desc->iuspin); | 436 | spin_lock_irq(&desc->iuspin); |
425 | 437 | ||
426 | if (desc->rerr) { /* read completed, error happened */ | 438 | if (desc->rerr) { /* read completed, error happened */ |
427 | int t = desc->rerr; | ||
428 | desc->rerr = 0; | 439 | desc->rerr = 0; |
429 | spin_unlock_irq(&desc->iuspin); | 440 | spin_unlock_irq(&desc->iuspin); |
430 | dev_err(&desc->intf->dev, | ||
431 | "reading had resulted in %d\n", t); | ||
432 | rv = -EIO; | 441 | rv = -EIO; |
433 | goto err; | 442 | goto err; |
434 | } | 443 | } |
@@ -465,9 +474,7 @@ retry: | |||
465 | rv = cntr; | 474 | rv = cntr; |
466 | 475 | ||
467 | err: | 476 | err: |
468 | mutex_unlock(&desc->rlock); | 477 | mutex_unlock(&desc->lock); |
469 | if (rv < 0 && rv != -EAGAIN) | ||
470 | dev_err(&desc->intf->dev, "wdm_read: exit error\n"); | ||
471 | return rv; | 478 | return rv; |
472 | } | 479 | } |
473 | 480 | ||
@@ -533,7 +540,7 @@ static int wdm_open(struct inode *inode, struct file *file) | |||
533 | } | 540 | } |
534 | intf->needs_remote_wakeup = 1; | 541 | intf->needs_remote_wakeup = 1; |
535 | 542 | ||
536 | mutex_lock(&desc->plock); | 543 | mutex_lock(&desc->lock); |
537 | if (!desc->count++) { | 544 | if (!desc->count++) { |
538 | rv = usb_submit_urb(desc->validity, GFP_KERNEL); | 545 | rv = usb_submit_urb(desc->validity, GFP_KERNEL); |
539 | if (rv < 0) { | 546 | if (rv < 0) { |
@@ -544,7 +551,7 @@ static int wdm_open(struct inode *inode, struct file *file) | |||
544 | } else { | 551 | } else { |
545 | rv = 0; | 552 | rv = 0; |
546 | } | 553 | } |
547 | mutex_unlock(&desc->plock); | 554 | mutex_unlock(&desc->lock); |
548 | usb_autopm_put_interface(desc->intf); | 555 | usb_autopm_put_interface(desc->intf); |
549 | out: | 556 | out: |
550 | mutex_unlock(&wdm_mutex); | 557 | mutex_unlock(&wdm_mutex); |
@@ -556,9 +563,9 @@ static int wdm_release(struct inode *inode, struct file *file) | |||
556 | struct wdm_device *desc = file->private_data; | 563 | struct wdm_device *desc = file->private_data; |
557 | 564 | ||
558 | mutex_lock(&wdm_mutex); | 565 | mutex_lock(&wdm_mutex); |
559 | mutex_lock(&desc->plock); | 566 | mutex_lock(&desc->lock); |
560 | desc->count--; | 567 | desc->count--; |
561 | mutex_unlock(&desc->plock); | 568 | mutex_unlock(&desc->lock); |
562 | 569 | ||
563 | if (!desc->count) { | 570 | if (!desc->count) { |
564 | dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); | 571 | dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); |
@@ -655,9 +662,7 @@ next_desc: | |||
655 | desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); | 662 | desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); |
656 | if (!desc) | 663 | if (!desc) |
657 | goto out; | 664 | goto out; |
658 | mutex_init(&desc->wlock); | 665 | mutex_init(&desc->lock); |
659 | mutex_init(&desc->rlock); | ||
660 | mutex_init(&desc->plock); | ||
661 | spin_lock_init(&desc->iuspin); | 666 | spin_lock_init(&desc->iuspin); |
662 | init_waitqueue_head(&desc->wait); | 667 | init_waitqueue_head(&desc->wait); |
663 | desc->wMaxCommand = maxcom; | 668 | desc->wMaxCommand = maxcom; |
@@ -771,14 +776,17 @@ static void wdm_disconnect(struct usb_interface *intf) | |||
771 | /* to terminate pending flushes */ | 776 | /* to terminate pending flushes */ |
772 | clear_bit(WDM_IN_USE, &desc->flags); | 777 | clear_bit(WDM_IN_USE, &desc->flags); |
773 | spin_unlock_irqrestore(&desc->iuspin, flags); | 778 | spin_unlock_irqrestore(&desc->iuspin, flags); |
774 | cancel_work_sync(&desc->rxwork); | 779 | mutex_lock(&desc->lock); |
775 | kill_urbs(desc); | 780 | kill_urbs(desc); |
781 | cancel_work_sync(&desc->rxwork); | ||
782 | mutex_unlock(&desc->lock); | ||
776 | wake_up_all(&desc->wait); | 783 | wake_up_all(&desc->wait); |
777 | if (!desc->count) | 784 | if (!desc->count) |
778 | cleanup(desc); | 785 | cleanup(desc); |
779 | mutex_unlock(&wdm_mutex); | 786 | mutex_unlock(&wdm_mutex); |
780 | } | 787 | } |
781 | 788 | ||
789 | #ifdef CONFIG_PM | ||
782 | static int wdm_suspend(struct usb_interface *intf, pm_message_t message) | 790 | static int wdm_suspend(struct usb_interface *intf, pm_message_t message) |
783 | { | 791 | { |
784 | struct wdm_device *desc = usb_get_intfdata(intf); | 792 | struct wdm_device *desc = usb_get_intfdata(intf); |
@@ -786,22 +794,30 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) | |||
786 | 794 | ||
787 | dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); | 795 | dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); |
788 | 796 | ||
789 | mutex_lock(&desc->plock); | 797 | /* if this is an autosuspend the caller does the locking */ |
790 | #ifdef CONFIG_PM | 798 | if (!(message.event & PM_EVENT_AUTO)) |
799 | mutex_lock(&desc->lock); | ||
800 | spin_lock_irq(&desc->iuspin); | ||
801 | |||
791 | if ((message.event & PM_EVENT_AUTO) && | 802 | if ((message.event & PM_EVENT_AUTO) && |
792 | test_bit(WDM_IN_USE, &desc->flags)) { | 803 | (test_bit(WDM_IN_USE, &desc->flags) |
804 | || test_bit(WDM_RESPONDING, &desc->flags))) { | ||
805 | spin_unlock_irq(&desc->iuspin); | ||
793 | rv = -EBUSY; | 806 | rv = -EBUSY; |
794 | } else { | 807 | } else { |
795 | #endif | 808 | |
796 | cancel_work_sync(&desc->rxwork); | 809 | set_bit(WDM_SUSPENDING, &desc->flags); |
810 | spin_unlock_irq(&desc->iuspin); | ||
811 | /* callback submits work - order is essential */ | ||
797 | kill_urbs(desc); | 812 | kill_urbs(desc); |
798 | #ifdef CONFIG_PM | 813 | cancel_work_sync(&desc->rxwork); |
799 | } | 814 | } |
800 | #endif | 815 | if (!(message.event & PM_EVENT_AUTO)) |
801 | mutex_unlock(&desc->plock); | 816 | mutex_unlock(&desc->lock); |
802 | 817 | ||
803 | return rv; | 818 | return rv; |
804 | } | 819 | } |
820 | #endif | ||
805 | 821 | ||
806 | static int recover_from_urb_loss(struct wdm_device *desc) | 822 | static int recover_from_urb_loss(struct wdm_device *desc) |
807 | { | 823 | { |
@@ -815,23 +831,27 @@ static int recover_from_urb_loss(struct wdm_device *desc) | |||
815 | } | 831 | } |
816 | return rv; | 832 | return rv; |
817 | } | 833 | } |
834 | |||
835 | #ifdef CONFIG_PM | ||
818 | static int wdm_resume(struct usb_interface *intf) | 836 | static int wdm_resume(struct usb_interface *intf) |
819 | { | 837 | { |
820 | struct wdm_device *desc = usb_get_intfdata(intf); | 838 | struct wdm_device *desc = usb_get_intfdata(intf); |
821 | int rv; | 839 | int rv; |
822 | 840 | ||
823 | dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); | 841 | dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); |
824 | mutex_lock(&desc->plock); | 842 | |
843 | clear_bit(WDM_SUSPENDING, &desc->flags); | ||
825 | rv = recover_from_urb_loss(desc); | 844 | rv = recover_from_urb_loss(desc); |
826 | mutex_unlock(&desc->plock); | 845 | |
827 | return rv; | 846 | return rv; |
828 | } | 847 | } |
848 | #endif | ||
829 | 849 | ||
830 | static int wdm_pre_reset(struct usb_interface *intf) | 850 | static int wdm_pre_reset(struct usb_interface *intf) |
831 | { | 851 | { |
832 | struct wdm_device *desc = usb_get_intfdata(intf); | 852 | struct wdm_device *desc = usb_get_intfdata(intf); |
833 | 853 | ||
834 | mutex_lock(&desc->plock); | 854 | mutex_lock(&desc->lock); |
835 | return 0; | 855 | return 0; |
836 | } | 856 | } |
837 | 857 | ||
@@ -841,7 +861,7 @@ static int wdm_post_reset(struct usb_interface *intf) | |||
841 | int rv; | 861 | int rv; |
842 | 862 | ||
843 | rv = recover_from_urb_loss(desc); | 863 | rv = recover_from_urb_loss(desc); |
844 | mutex_unlock(&desc->plock); | 864 | mutex_unlock(&desc->lock); |
845 | return 0; | 865 | return 0; |
846 | } | 866 | } |
847 | 867 | ||
@@ -849,9 +869,11 @@ static struct usb_driver wdm_driver = { | |||
849 | .name = "cdc_wdm", | 869 | .name = "cdc_wdm", |
850 | .probe = wdm_probe, | 870 | .probe = wdm_probe, |
851 | .disconnect = wdm_disconnect, | 871 | .disconnect = wdm_disconnect, |
872 | #ifdef CONFIG_PM | ||
852 | .suspend = wdm_suspend, | 873 | .suspend = wdm_suspend, |
853 | .resume = wdm_resume, | 874 | .resume = wdm_resume, |
854 | .reset_resume = wdm_resume, | 875 | .reset_resume = wdm_resume, |
876 | #endif | ||
855 | .pre_reset = wdm_pre_reset, | 877 | .pre_reset = wdm_pre_reset, |
856 | .post_reset = wdm_post_reset, | 878 | .post_reset = wdm_post_reset, |
857 | .id_table = wdm_ids, | 879 | .id_table = wdm_ids, |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e909ff7b9094..3466fdc5bb11 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -1207,6 +1207,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1207 | free_async(as); | 1207 | free_async(as); |
1208 | return -ENOMEM; | 1208 | return -ENOMEM; |
1209 | } | 1209 | } |
1210 | /* Isochronous input data may end up being discontiguous | ||
1211 | * if some of the packets are short. Clear the buffer so | ||
1212 | * that the gaps don't leak kernel data to userspace. | ||
1213 | */ | ||
1214 | if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO) | ||
1215 | memset(as->urb->transfer_buffer, 0, | ||
1216 | uurb->buffer_length); | ||
1210 | } | 1217 | } |
1211 | as->urb->dev = ps->dev; | 1218 | as->urb->dev = ps->dev; |
1212 | as->urb->pipe = (uurb->type << 30) | | 1219 | as->urb->pipe = (uurb->type << 30) | |
@@ -1345,10 +1352,14 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1345 | void __user *addr = as->userurb; | 1352 | void __user *addr = as->userurb; |
1346 | unsigned int i; | 1353 | unsigned int i; |
1347 | 1354 | ||
1348 | if (as->userbuffer && urb->actual_length) | 1355 | if (as->userbuffer && urb->actual_length) { |
1349 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, | 1356 | if (urb->number_of_packets > 0) /* Isochronous */ |
1350 | urb->actual_length)) | 1357 | i = urb->transfer_buffer_length; |
1358 | else /* Non-Isoc */ | ||
1359 | i = urb->actual_length; | ||
1360 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) | ||
1351 | goto err_out; | 1361 | goto err_out; |
1362 | } | ||
1352 | if (put_user(as->status, &userurb->status)) | 1363 | if (put_user(as->status, &userurb->status)) |
1353 | goto err_out; | 1364 | goto err_out; |
1354 | if (put_user(urb->actual_length, &userurb->actual_length)) | 1365 | if (put_user(urb->actual_length, &userurb->actual_length)) |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 27080561a1c2..45a32dadb406 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -453,6 +453,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
453 | if (urb->interval > (1 << 15)) | 453 | if (urb->interval > (1 << 15)) |
454 | return -EINVAL; | 454 | return -EINVAL; |
455 | max = 1 << 15; | 455 | max = 1 << 15; |
456 | break; | ||
456 | case USB_SPEED_WIRELESS: | 457 | case USB_SPEED_WIRELESS: |
457 | if (urb->interval > 16) | 458 | if (urb->interval > 16) |
458 | return -EINVAL; | 459 | return -EINVAL; |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 7460cd797f45..11a3e0fa4331 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -747,7 +747,7 @@ config USB_MASS_STORAGE | |||
747 | which may be used with composite framework. | 747 | which may be used with composite framework. |
748 | 748 | ||
749 | Say "y" to link the driver statically, or "m" to build | 749 | Say "y" to link the driver statically, or "m" to build |
750 | a dynamically linked module called "g_file_storage". If unsure, | 750 | a dynamically linked module called "g_mass_storage". If unsure, |
751 | consider File-backed Storage Gadget. | 751 | consider File-backed Storage Gadget. |
752 | 752 | ||
753 | config USB_G_SERIAL | 753 | config USB_G_SERIAL |
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 65a5f94cbc04..3568de210f79 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -266,7 +266,7 @@ struct usb_ep * __init usb_ep_autoconfig ( | |||
266 | } | 266 | } |
267 | 267 | ||
268 | #ifdef CONFIG_BLACKFIN | 268 | #ifdef CONFIG_BLACKFIN |
269 | } else if (gadget_is_musbhsfc(gadget) || gadget_is_musbhdrc(gadget)) { | 269 | } else if (gadget_is_musbhdrc(gadget)) { |
270 | if ((USB_ENDPOINT_XFER_BULK == type) || | 270 | if ((USB_ENDPOINT_XFER_BULK == type) || |
271 | (USB_ENDPOINT_XFER_ISOC == type)) { | 271 | (USB_ENDPOINT_XFER_ISOC == type)) { |
272 | if (USB_DIR_IN & desc->bEndpointAddress) | 272 | if (USB_DIR_IN & desc->bEndpointAddress) |
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 5a3cdd08f1d0..f4911c09022e 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -2910,7 +2910,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) | |||
2910 | } | 2910 | } |
2911 | 2911 | ||
2912 | 2912 | ||
2913 | static int fsg_bind(struct usb_configuration *c, struct usb_function *f) | 2913 | static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f) |
2914 | { | 2914 | { |
2915 | struct fsg_dev *fsg = fsg_from_func(f); | 2915 | struct fsg_dev *fsg = fsg_from_func(f); |
2916 | struct usb_gadget *gadget = c->cdev->gadget; | 2916 | struct usb_gadget *gadget = c->cdev->gadget; |
@@ -2954,7 +2954,6 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) | |||
2954 | autoconf_fail: | 2954 | autoconf_fail: |
2955 | ERROR(fsg, "unable to autoconfigure all endpoints\n"); | 2955 | ERROR(fsg, "unable to autoconfigure all endpoints\n"); |
2956 | rc = -ENOTSUPP; | 2956 | rc = -ENOTSUPP; |
2957 | fsg_unbind(c, f); | ||
2958 | return rc; | 2957 | return rc; |
2959 | } | 2958 | } |
2960 | 2959 | ||
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index 1edbc12fff18..e511fec9f26d 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
@@ -136,6 +136,12 @@ | |||
136 | #define gadget_is_r8a66597(g) 0 | 136 | #define gadget_is_r8a66597(g) 0 |
137 | #endif | 137 | #endif |
138 | 138 | ||
139 | #ifdef CONFIG_USB_S3C_HSOTG | ||
140 | #define gadget_is_s3c_hsotg(g) (!strcmp("s3c-hsotg", (g)->name)) | ||
141 | #else | ||
142 | #define gadget_is_s3c_hsotg(g) 0 | ||
143 | #endif | ||
144 | |||
139 | 145 | ||
140 | /** | 146 | /** |
141 | * usb_gadget_controller_number - support bcdDevice id convention | 147 | * usb_gadget_controller_number - support bcdDevice id convention |
@@ -192,6 +198,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
192 | return 0x24; | 198 | return 0x24; |
193 | else if (gadget_is_r8a66597(gadget)) | 199 | else if (gadget_is_r8a66597(gadget)) |
194 | return 0x25; | 200 | return 0x25; |
201 | else if (gadget_is_s3c_hsotg(gadget)) | ||
202 | return 0x26; | ||
195 | return -ENOENT; | 203 | return -ENOENT; |
196 | } | 204 | } |
197 | 205 | ||
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index e8edc640381e..1088d08c7ed8 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1768,7 +1768,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1768 | * usb_gadget_driver_{register,unregister}() must change. | 1768 | * usb_gadget_driver_{register,unregister}() must change. |
1769 | */ | 1769 | */ |
1770 | if (the_controller) { | 1770 | if (the_controller) { |
1771 | WARNING(dev, "ignoring %s\n", pci_name(pdev)); | 1771 | pr_warning("ignoring %s\n", pci_name(pdev)); |
1772 | return -EBUSY; | 1772 | return -EBUSY; |
1773 | } | 1773 | } |
1774 | if (!pdev->irq) { | 1774 | if (!pdev->irq) { |
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 76496f5d272c..a930d7fd7e7a 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c | |||
@@ -211,8 +211,6 @@ static int __init cdc_do_config(struct usb_configuration *c) | |||
211 | ret = fsg_add(c->cdev, c, fsg_common); | 211 | ret = fsg_add(c->cdev, c, fsg_common); |
212 | if (ret < 0) | 212 | if (ret < 0) |
213 | return ret; | 213 | return ret; |
214 | if (ret < 0) | ||
215 | return ret; | ||
216 | 214 | ||
217 | return 0; | 215 | return 0; |
218 | } | 216 | } |
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 8b45145b9136..5e13d23b5f0c 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/err.h> | ||
26 | #include <linux/io.h> | 27 | #include <linux/io.h> |
27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
28 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 4e0c67f1f51b..b6315aa47f7a 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -12,7 +12,7 @@ fhci-objs := fhci-hcd.o fhci-hub.o fhci-q.o fhci-mem.o \ | |||
12 | ifeq ($(CONFIG_FHCI_DEBUG),y) | 12 | ifeq ($(CONFIG_FHCI_DEBUG),y) |
13 | fhci-objs += fhci-dbg.o | 13 | fhci-objs += fhci-dbg.o |
14 | endif | 14 | endif |
15 | xhci-objs := xhci-hcd.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o | 15 | xhci-hcd-objs := xhci.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o |
16 | 16 | ||
17 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ | 17 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ |
18 | 18 | ||
@@ -25,7 +25,7 @@ obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o | |||
25 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o | 25 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o |
26 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o | 26 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o |
27 | obj-$(CONFIG_USB_FHCI_HCD) += fhci.o | 27 | obj-$(CONFIG_USB_FHCI_HCD) += fhci.o |
28 | obj-$(CONFIG_USB_XHCI_HCD) += xhci.o | 28 | obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o |
29 | obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o | 29 | obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o |
30 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o | 30 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o |
31 | obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o | 31 | obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index d8d6d3461d32..dc55a62859c6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -995,7 +995,7 @@ rescan: | |||
995 | /* endpoints can be iso streams. for now, we don't | 995 | /* endpoints can be iso streams. for now, we don't |
996 | * accelerate iso completions ... so spin a while. | 996 | * accelerate iso completions ... so spin a while. |
997 | */ | 997 | */ |
998 | if (qh->hw->hw_info1 == 0) { | 998 | if (qh->hw == NULL) { |
999 | ehci_vdbg (ehci, "iso delay\n"); | 999 | ehci_vdbg (ehci, "iso delay\n"); |
1000 | goto idle_timeout; | 1000 | goto idle_timeout; |
1001 | } | 1001 | } |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 39340ae00ac4..a0aaaaff2560 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -1123,8 +1123,8 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) | |||
1123 | urb->interval); | 1123 | urb->interval); |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | /* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */ | 1126 | /* if dev->ep [epnum] is a QH, hw is set */ |
1127 | } else if (unlikely (stream->hw_info1 != 0)) { | 1127 | } else if (unlikely (stream->hw != NULL)) { |
1128 | ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", | 1128 | ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", |
1129 | urb->dev->devpath, epnum, | 1129 | urb->dev->devpath, epnum, |
1130 | usb_pipein(urb->pipe) ? "in" : "out"); | 1130 | usb_pipein(urb->pipe) ? "in" : "out"); |
@@ -1565,13 +1565,27 @@ itd_patch( | |||
1565 | static inline void | 1565 | static inline void |
1566 | itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) | 1566 | itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) |
1567 | { | 1567 | { |
1568 | /* always prepend ITD/SITD ... only QH tree is order-sensitive */ | 1568 | union ehci_shadow *prev = &ehci->pshadow[frame]; |
1569 | itd->itd_next = ehci->pshadow [frame]; | 1569 | __hc32 *hw_p = &ehci->periodic[frame]; |
1570 | itd->hw_next = ehci->periodic [frame]; | 1570 | union ehci_shadow here = *prev; |
1571 | ehci->pshadow [frame].itd = itd; | 1571 | __hc32 type = 0; |
1572 | |||
1573 | /* skip any iso nodes which might belong to previous microframes */ | ||
1574 | while (here.ptr) { | ||
1575 | type = Q_NEXT_TYPE(ehci, *hw_p); | ||
1576 | if (type == cpu_to_hc32(ehci, Q_TYPE_QH)) | ||
1577 | break; | ||
1578 | prev = periodic_next_shadow(ehci, prev, type); | ||
1579 | hw_p = shadow_next_periodic(ehci, &here, type); | ||
1580 | here = *prev; | ||
1581 | } | ||
1582 | |||
1583 | itd->itd_next = here; | ||
1584 | itd->hw_next = *hw_p; | ||
1585 | prev->itd = itd; | ||
1572 | itd->frame = frame; | 1586 | itd->frame = frame; |
1573 | wmb (); | 1587 | wmb (); |
1574 | ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); | 1588 | *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); |
1575 | } | 1589 | } |
1576 | 1590 | ||
1577 | /* fit urb's itds into the selected schedule slot; activate as needed */ | 1591 | /* fit urb's itds into the selected schedule slot; activate as needed */ |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2d85e21ff282..b1dce96dd621 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -394,9 +394,8 @@ struct ehci_iso_sched { | |||
394 | * acts like a qh would, if EHCI had them for ISO. | 394 | * acts like a qh would, if EHCI had them for ISO. |
395 | */ | 395 | */ |
396 | struct ehci_iso_stream { | 396 | struct ehci_iso_stream { |
397 | /* first two fields match QH, but info1 == 0 */ | 397 | /* first field matches ehci_hq, but is NULL */ |
398 | __hc32 hw_next; | 398 | struct ehci_qh_hw *hw; |
399 | __hc32 hw_info1; | ||
400 | 399 | ||
401 | u32 refcount; | 400 | u32 refcount; |
402 | u8 bEndpointAddress; | 401 | u8 bEndpointAddress; |
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index bee558aed427..f71a73a93d0c 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -418,7 +418,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb) | |||
418 | 418 | ||
419 | /* this function must be called with interrupt disabled */ | 419 | /* this function must be called with interrupt disabled */ |
420 | static void free_usb_address(struct r8a66597 *r8a66597, | 420 | static void free_usb_address(struct r8a66597 *r8a66597, |
421 | struct r8a66597_device *dev) | 421 | struct r8a66597_device *dev, int reset) |
422 | { | 422 | { |
423 | int port; | 423 | int port; |
424 | 424 | ||
@@ -430,7 +430,13 @@ static void free_usb_address(struct r8a66597 *r8a66597, | |||
430 | dev->state = USB_STATE_DEFAULT; | 430 | dev->state = USB_STATE_DEFAULT; |
431 | r8a66597->address_map &= ~(1 << dev->address); | 431 | r8a66597->address_map &= ~(1 << dev->address); |
432 | dev->address = 0; | 432 | dev->address = 0; |
433 | dev_set_drvdata(&dev->udev->dev, NULL); | 433 | /* |
434 | * Only when resetting USB, it is necessary to erase drvdata. When | ||
435 | * a usb device with usb hub is disconnect, "dev->udev" is already | ||
436 | * freed on usb_desconnect(). So we cannot access the data. | ||
437 | */ | ||
438 | if (reset) | ||
439 | dev_set_drvdata(&dev->udev->dev, NULL); | ||
434 | list_del(&dev->device_list); | 440 | list_del(&dev->device_list); |
435 | kfree(dev); | 441 | kfree(dev); |
436 | 442 | ||
@@ -1069,7 +1075,7 @@ static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597, int port) | |||
1069 | struct r8a66597_device *dev = r8a66597->root_hub[port].dev; | 1075 | struct r8a66597_device *dev = r8a66597->root_hub[port].dev; |
1070 | 1076 | ||
1071 | disable_r8a66597_pipe_all(r8a66597, dev); | 1077 | disable_r8a66597_pipe_all(r8a66597, dev); |
1072 | free_usb_address(r8a66597, dev); | 1078 | free_usb_address(r8a66597, dev, 0); |
1073 | 1079 | ||
1074 | start_root_hub_sampling(r8a66597, port, 0); | 1080 | start_root_hub_sampling(r8a66597, port, 0); |
1075 | } | 1081 | } |
@@ -2085,7 +2091,7 @@ static void update_usb_address_map(struct r8a66597 *r8a66597, | |||
2085 | spin_lock_irqsave(&r8a66597->lock, flags); | 2091 | spin_lock_irqsave(&r8a66597->lock, flags); |
2086 | dev = get_r8a66597_device(r8a66597, addr); | 2092 | dev = get_r8a66597_device(r8a66597, addr); |
2087 | disable_r8a66597_pipe_all(r8a66597, dev); | 2093 | disable_r8a66597_pipe_all(r8a66597, dev); |
2088 | free_usb_address(r8a66597, dev); | 2094 | free_usb_address(r8a66597, dev, 0); |
2089 | put_child_connect_map(r8a66597, addr); | 2095 | put_child_connect_map(r8a66597, addr); |
2090 | spin_unlock_irqrestore(&r8a66597->lock, flags); | 2096 | spin_unlock_irqrestore(&r8a66597->lock, flags); |
2091 | } | 2097 | } |
@@ -2228,7 +2234,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
2228 | rh->port |= (1 << USB_PORT_FEAT_RESET); | 2234 | rh->port |= (1 << USB_PORT_FEAT_RESET); |
2229 | 2235 | ||
2230 | disable_r8a66597_pipe_all(r8a66597, dev); | 2236 | disable_r8a66597_pipe_all(r8a66597, dev); |
2231 | free_usb_address(r8a66597, dev); | 2237 | free_usb_address(r8a66597, dev, 1); |
2232 | 2238 | ||
2233 | r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT, | 2239 | r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT, |
2234 | get_dvstctr_reg(port)); | 2240 | get_dvstctr_reg(port)); |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 49f7d72f8b1b..bba9b19ed1b9 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -566,8 +566,13 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev, | |||
566 | if (interval < 3) | 566 | if (interval < 3) |
567 | interval = 3; | 567 | interval = 3; |
568 | if ((1 << interval) != 8*ep->desc.bInterval) | 568 | if ((1 << interval) != 8*ep->desc.bInterval) |
569 | dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n", | 569 | dev_warn(&udev->dev, |
570 | ep->desc.bEndpointAddress, 1 << interval); | 570 | "ep %#x - rounding interval" |
571 | " to %d microframes, " | ||
572 | "ep desc says %d microframes\n", | ||
573 | ep->desc.bEndpointAddress, | ||
574 | 1 << interval, | ||
575 | 8*ep->desc.bInterval); | ||
571 | } | 576 | } |
572 | break; | 577 | break; |
573 | default: | 578 | default: |
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci.c index 4cb69e0af834..492a61c2c79d 100644 --- a/drivers/usb/host/xhci-hcd.c +++ b/drivers/usb/host/xhci.c | |||
@@ -1173,6 +1173,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
1173 | cmd_completion = &virt_dev->cmd_completion; | 1173 | cmd_completion = &virt_dev->cmd_completion; |
1174 | cmd_status = &virt_dev->cmd_status; | 1174 | cmd_status = &virt_dev->cmd_status; |
1175 | } | 1175 | } |
1176 | init_completion(cmd_completion); | ||
1176 | 1177 | ||
1177 | if (!ctx_change) | 1178 | if (!ctx_change) |
1178 | ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, | 1179 | ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, |
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 4d2952f1fb13..3adab041355a 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c | |||
@@ -202,6 +202,7 @@ static void appledisplay_work(struct work_struct *work) | |||
202 | static int appledisplay_probe(struct usb_interface *iface, | 202 | static int appledisplay_probe(struct usb_interface *iface, |
203 | const struct usb_device_id *id) | 203 | const struct usb_device_id *id) |
204 | { | 204 | { |
205 | struct backlight_properties props; | ||
205 | struct appledisplay *pdata; | 206 | struct appledisplay *pdata; |
206 | struct usb_device *udev = interface_to_usbdev(iface); | 207 | struct usb_device *udev = interface_to_usbdev(iface); |
207 | struct usb_host_interface *iface_desc; | 208 | struct usb_host_interface *iface_desc; |
@@ -279,16 +280,16 @@ static int appledisplay_probe(struct usb_interface *iface, | |||
279 | /* Register backlight device */ | 280 | /* Register backlight device */ |
280 | snprintf(bl_name, sizeof(bl_name), "appledisplay%d", | 281 | snprintf(bl_name, sizeof(bl_name), "appledisplay%d", |
281 | atomic_inc_return(&count_displays) - 1); | 282 | atomic_inc_return(&count_displays) - 1); |
283 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
284 | props.max_brightness = 0xff; | ||
282 | pdata->bd = backlight_device_register(bl_name, NULL, pdata, | 285 | pdata->bd = backlight_device_register(bl_name, NULL, pdata, |
283 | &appledisplay_bl_data); | 286 | &appledisplay_bl_data, &props); |
284 | if (IS_ERR(pdata->bd)) { | 287 | if (IS_ERR(pdata->bd)) { |
285 | dev_err(&iface->dev, "Backlight registration failed\n"); | 288 | dev_err(&iface->dev, "Backlight registration failed\n"); |
286 | retval = PTR_ERR(pdata->bd); | 289 | retval = PTR_ERR(pdata->bd); |
287 | goto error; | 290 | goto error; |
288 | } | 291 | } |
289 | 292 | ||
290 | pdata->bd->props.max_brightness = 0xff; | ||
291 | |||
292 | /* Try to get brightness */ | 293 | /* Try to get brightness */ |
293 | brightness = appledisplay_bl_get_brightness(pdata->bd); | 294 | brightness = appledisplay_bl_get_brightness(pdata->bd); |
294 | 295 | ||
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b4bbf8f2c238..0e8b8ab1d168 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -379,7 +379,6 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
379 | u8 devctl, u8 power) | 379 | u8 devctl, u8 power) |
380 | { | 380 | { |
381 | irqreturn_t handled = IRQ_NONE; | 381 | irqreturn_t handled = IRQ_NONE; |
382 | void __iomem *mbase = musb->mregs; | ||
383 | 382 | ||
384 | DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, | 383 | DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, |
385 | int_usb); | 384 | int_usb); |
@@ -394,6 +393,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
394 | 393 | ||
395 | if (devctl & MUSB_DEVCTL_HM) { | 394 | if (devctl & MUSB_DEVCTL_HM) { |
396 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 395 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
396 | void __iomem *mbase = musb->mregs; | ||
397 | |||
397 | switch (musb->xceiv->state) { | 398 | switch (musb->xceiv->state) { |
398 | case OTG_STATE_A_SUSPEND: | 399 | case OTG_STATE_A_SUSPEND: |
399 | /* remote wakeup? later, GetPortStatus | 400 | /* remote wakeup? later, GetPortStatus |
@@ -471,6 +472,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
471 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 472 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
472 | /* see manual for the order of the tests */ | 473 | /* see manual for the order of the tests */ |
473 | if (int_usb & MUSB_INTR_SESSREQ) { | 474 | if (int_usb & MUSB_INTR_SESSREQ) { |
475 | void __iomem *mbase = musb->mregs; | ||
476 | |||
474 | DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); | 477 | DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); |
475 | 478 | ||
476 | /* IRQ arrives from ID pin sense or (later, if VBUS power | 479 | /* IRQ arrives from ID pin sense or (later, if VBUS power |
@@ -519,6 +522,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
519 | case OTG_STATE_A_WAIT_BCON: | 522 | case OTG_STATE_A_WAIT_BCON: |
520 | case OTG_STATE_A_WAIT_VRISE: | 523 | case OTG_STATE_A_WAIT_VRISE: |
521 | if (musb->vbuserr_retry) { | 524 | if (musb->vbuserr_retry) { |
525 | void __iomem *mbase = musb->mregs; | ||
526 | |||
522 | musb->vbuserr_retry--; | 527 | musb->vbuserr_retry--; |
523 | ignore = 1; | 528 | ignore = 1; |
524 | devctl |= MUSB_DEVCTL_SESSION; | 529 | devctl |= MUSB_DEVCTL_SESSION; |
@@ -622,6 +627,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
622 | 627 | ||
623 | if (int_usb & MUSB_INTR_CONNECT) { | 628 | if (int_usb & MUSB_INTR_CONNECT) { |
624 | struct usb_hcd *hcd = musb_to_hcd(musb); | 629 | struct usb_hcd *hcd = musb_to_hcd(musb); |
630 | void __iomem *mbase = musb->mregs; | ||
625 | 631 | ||
626 | handled = IRQ_HANDLED; | 632 | handled = IRQ_HANDLED; |
627 | musb->is_active = 1; | 633 | musb->is_active = 1; |
@@ -2007,7 +2013,6 @@ bad_config: | |||
2007 | /* host side needs more setup */ | 2013 | /* host side needs more setup */ |
2008 | if (is_host_enabled(musb)) { | 2014 | if (is_host_enabled(musb)) { |
2009 | struct usb_hcd *hcd = musb_to_hcd(musb); | 2015 | struct usb_hcd *hcd = musb_to_hcd(musb); |
2010 | u8 busctl; | ||
2011 | 2016 | ||
2012 | otg_set_host(musb->xceiv, &hcd->self); | 2017 | otg_set_host(musb->xceiv, &hcd->self); |
2013 | 2018 | ||
@@ -2018,9 +2023,9 @@ bad_config: | |||
2018 | 2023 | ||
2019 | /* program PHY to use external vBus if required */ | 2024 | /* program PHY to use external vBus if required */ |
2020 | if (plat->extvbus) { | 2025 | if (plat->extvbus) { |
2021 | busctl = musb_readb(musb->mregs, MUSB_ULPI_BUSCONTROL); | 2026 | u8 busctl = musb_read_ulpi_buscontrol(musb->mregs); |
2022 | busctl |= MUSB_ULPI_USE_EXTVBUS; | 2027 | busctl |= MUSB_ULPI_USE_EXTVBUS; |
2023 | musb_writeb(musb->mregs, MUSB_ULPI_BUSCONTROL, busctl); | 2028 | musb_write_ulpi_buscontrol(musb->mregs, busctl); |
2024 | } | 2029 | } |
2025 | } | 2030 | } |
2026 | 2031 | ||
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index d849fb81c131..cd9f4a9a06c6 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -469,7 +469,7 @@ struct musb_csr_regs { | |||
469 | 469 | ||
470 | struct musb_context_registers { | 470 | struct musb_context_registers { |
471 | 471 | ||
472 | #if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) | 472 | #ifdef CONFIG_PM |
473 | u32 otg_sysconfig, otg_forcestandby; | 473 | u32 otg_sysconfig, otg_forcestandby; |
474 | #endif | 474 | #endif |
475 | u8 power; | 475 | u8 power; |
@@ -483,7 +483,7 @@ struct musb_context_registers { | |||
483 | struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; | 483 | struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; |
484 | }; | 484 | }; |
485 | 485 | ||
486 | #if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) | 486 | #ifdef CONFIG_PM |
487 | extern void musb_platform_save_context(struct musb *musb, | 487 | extern void musb_platform_save_context(struct musb *musb, |
488 | struct musb_context_registers *musb_context); | 488 | struct musb_context_registers *musb_context); |
489 | extern void musb_platform_restore_context(struct musb *musb, | 489 | extern void musb_platform_restore_context(struct musb *musb, |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 3421cf9858b5..dec896e888db 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -1689,7 +1689,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1689 | dma->desired_mode = 1; | 1689 | dma->desired_mode = 1; |
1690 | if (rx_count < hw_ep->max_packet_sz_rx) { | 1690 | if (rx_count < hw_ep->max_packet_sz_rx) { |
1691 | length = rx_count; | 1691 | length = rx_count; |
1692 | dma->bDesiredMode = 0; | 1692 | dma->desired_mode = 0; |
1693 | } else { | 1693 | } else { |
1694 | length = urb->transfer_buffer_length; | 1694 | length = urb->transfer_buffer_length; |
1695 | } | 1695 | } |
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 8d8062b10e2f..fa55aacc385d 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h | |||
@@ -326,6 +326,11 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) | |||
326 | musb_writew(mbase, MUSB_RXFIFOADD, c_off); | 326 | musb_writew(mbase, MUSB_RXFIFOADD, c_off); |
327 | } | 327 | } |
328 | 328 | ||
329 | static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) | ||
330 | { | ||
331 | musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val); | ||
332 | } | ||
333 | |||
329 | static inline u8 musb_read_txfifosz(void __iomem *mbase) | 334 | static inline u8 musb_read_txfifosz(void __iomem *mbase) |
330 | { | 335 | { |
331 | return musb_readb(mbase, MUSB_TXFIFOSZ); | 336 | return musb_readb(mbase, MUSB_TXFIFOSZ); |
@@ -346,6 +351,11 @@ static inline u16 musb_read_rxfifoadd(void __iomem *mbase) | |||
346 | return musb_readw(mbase, MUSB_RXFIFOADD); | 351 | return musb_readw(mbase, MUSB_RXFIFOADD); |
347 | } | 352 | } |
348 | 353 | ||
354 | static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) | ||
355 | { | ||
356 | return musb_readb(mbase, MUSB_ULPI_BUSCONTROL); | ||
357 | } | ||
358 | |||
349 | static inline u8 musb_read_configdata(void __iomem *mbase) | 359 | static inline u8 musb_read_configdata(void __iomem *mbase) |
350 | { | 360 | { |
351 | musb_writeb(mbase, MUSB_INDEX, 0); | 361 | musb_writeb(mbase, MUSB_INDEX, 0); |
@@ -510,20 +520,33 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) | |||
510 | { | 520 | { |
511 | } | 521 | } |
512 | 522 | ||
523 | static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) | ||
524 | { | ||
525 | } | ||
526 | |||
513 | static inline u8 musb_read_txfifosz(void __iomem *mbase) | 527 | static inline u8 musb_read_txfifosz(void __iomem *mbase) |
514 | { | 528 | { |
529 | return 0; | ||
515 | } | 530 | } |
516 | 531 | ||
517 | static inline u16 musb_read_txfifoadd(void __iomem *mbase) | 532 | static inline u16 musb_read_txfifoadd(void __iomem *mbase) |
518 | { | 533 | { |
534 | return 0; | ||
519 | } | 535 | } |
520 | 536 | ||
521 | static inline u8 musb_read_rxfifosz(void __iomem *mbase) | 537 | static inline u8 musb_read_rxfifosz(void __iomem *mbase) |
522 | { | 538 | { |
539 | return 0; | ||
523 | } | 540 | } |
524 | 541 | ||
525 | static inline u16 musb_read_rxfifoadd(void __iomem *mbase) | 542 | static inline u16 musb_read_rxfifoadd(void __iomem *mbase) |
526 | { | 543 | { |
544 | return 0; | ||
545 | } | ||
546 | |||
547 | static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) | ||
548 | { | ||
549 | return 0; | ||
527 | } | 550 | } |
528 | 551 | ||
529 | static inline u8 musb_read_configdata(void __iomem *mbase) | 552 | static inline u8 musb_read_configdata(void __iomem *mbase) |
@@ -577,22 +600,27 @@ static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, | |||
577 | 600 | ||
578 | static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) | 601 | static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) |
579 | { | 602 | { |
603 | return 0; | ||
580 | } | 604 | } |
581 | 605 | ||
582 | static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) | 606 | static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) |
583 | { | 607 | { |
608 | return 0; | ||
584 | } | 609 | } |
585 | 610 | ||
586 | static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) | 611 | static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) |
587 | { | 612 | { |
613 | return 0; | ||
588 | } | 614 | } |
589 | 615 | ||
590 | static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) | 616 | static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) |
591 | { | 617 | { |
618 | return 0; | ||
592 | } | 619 | } |
593 | 620 | ||
594 | static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) | 621 | static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) |
595 | { | 622 | { |
623 | return 0; | ||
596 | } | 624 | } |
597 | 625 | ||
598 | static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum) | 626 | static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum) |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index c78b255e3f83..a0ecb42cb33a 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -474,14 +474,14 @@ config USB_SERIAL_OTI6858 | |||
474 | 474 | ||
475 | config USB_SERIAL_QCAUX | 475 | config USB_SERIAL_QCAUX |
476 | tristate "USB Qualcomm Auxiliary Serial Port Driver" | 476 | tristate "USB Qualcomm Auxiliary Serial Port Driver" |
477 | ---help--- | 477 | help |
478 | Say Y here if you want to use the auxiliary serial ports provided | 478 | Say Y here if you want to use the auxiliary serial ports provided |
479 | by many modems based on Qualcomm chipsets. These ports often use | 479 | by many modems based on Qualcomm chipsets. These ports often use |
480 | a proprietary protocol called DM and cannot be used for AT- or | 480 | a proprietary protocol called DM and cannot be used for AT- or |
481 | PPP-based communication. | 481 | PPP-based communication. |
482 | 482 | ||
483 | To compile this driver as a module, choose M here: the | 483 | To compile this driver as a module, choose M here: the |
484 | module will be called moto_modem. If unsure, choose N. | 484 | module will be called qcaux. If unsure, choose N. |
485 | 485 | ||
486 | config USB_SERIAL_QUALCOMM | 486 | config USB_SERIAL_QUALCOMM |
487 | tristate "USB Qualcomm Serial modem" | 487 | tristate "USB Qualcomm Serial modem" |
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index b22ac3258523..f347da2ef00a 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -181,6 +181,7 @@ static int usb_console_setup(struct console *co, char *options) | |||
181 | /* The console is special in terms of closing the device so | 181 | /* The console is special in terms of closing the device so |
182 | * indicate this port is now acting as a system console. */ | 182 | * indicate this port is now acting as a system console. */ |
183 | port->console = 1; | 183 | port->console = 1; |
184 | port->port.console = 1; | ||
184 | 185 | ||
185 | mutex_unlock(&serial->disc_mutex); | 186 | mutex_unlock(&serial->disc_mutex); |
186 | return retval; | 187 | return retval; |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 507382b0a9ed..ec9b0449ccf6 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -313,11 +313,6 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, | |||
313 | return -EPROTO; | 313 | return -EPROTO; |
314 | } | 314 | } |
315 | 315 | ||
316 | /* Single data value */ | ||
317 | result = usb_control_msg(serial->dev, | ||
318 | usb_sndctrlpipe(serial->dev, 0), | ||
319 | request, REQTYPE_HOST_TO_DEVICE, data[0], | ||
320 | 0, NULL, 0, 300); | ||
321 | return 0; | 316 | return 0; |
322 | } | 317 | } |
323 | 318 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 6af0dfa5f5ac..1d7c4fac02e8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -91,7 +91,7 @@ struct ftdi_private { | |||
91 | unsigned long tx_outstanding_bytes; | 91 | unsigned long tx_outstanding_bytes; |
92 | unsigned long tx_outstanding_urbs; | 92 | unsigned long tx_outstanding_urbs; |
93 | unsigned short max_packet_size; | 93 | unsigned short max_packet_size; |
94 | struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() */ | 94 | struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */ |
95 | }; | 95 | }; |
96 | 96 | ||
97 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ | 97 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ |
@@ -658,6 +658,7 @@ static struct usb_device_id id_table_combined [] = { | |||
658 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, | 658 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, |
659 | { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, | 659 | { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, |
660 | { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, | 660 | { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, |
661 | { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, | ||
661 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, | 662 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, |
662 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, | 663 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, |
663 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, | 664 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, |
@@ -1272,8 +1273,8 @@ check_and_exit: | |||
1272 | (priv->flags & ASYNC_SPD_MASK)) || | 1273 | (priv->flags & ASYNC_SPD_MASK)) || |
1273 | (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && | 1274 | (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && |
1274 | (old_priv.custom_divisor != priv->custom_divisor))) { | 1275 | (old_priv.custom_divisor != priv->custom_divisor))) { |
1275 | mutex_unlock(&priv->cfg_lock); | ||
1276 | change_speed(tty, port); | 1276 | change_speed(tty, port); |
1277 | mutex_unlock(&priv->cfg_lock); | ||
1277 | } | 1278 | } |
1278 | else | 1279 | else |
1279 | mutex_unlock(&priv->cfg_lock); | 1280 | mutex_unlock(&priv->cfg_lock); |
@@ -2264,9 +2265,11 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2264 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | 2265 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
2265 | } else { | 2266 | } else { |
2266 | /* set the baudrate determined before */ | 2267 | /* set the baudrate determined before */ |
2268 | mutex_lock(&priv->cfg_lock); | ||
2267 | if (change_speed(tty, port)) | 2269 | if (change_speed(tty, port)) |
2268 | dev_err(&port->dev, "%s urb failed to set baudrate\n", | 2270 | dev_err(&port->dev, "%s urb failed to set baudrate\n", |
2269 | __func__); | 2271 | __func__); |
2272 | mutex_unlock(&priv->cfg_lock); | ||
2270 | /* Ensure RTS and DTR are raised when baudrate changed from 0 */ | 2273 | /* Ensure RTS and DTR are raised when baudrate changed from 0 */ |
2271 | if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) | 2274 | if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) |
2272 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); | 2275 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 0727e198503e..75482cbc3998 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -501,6 +501,13 @@ | |||
501 | #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ | 501 | #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ |
502 | 502 | ||
503 | /* | 503 | /* |
504 | * Contec products (http://www.contec.com) | ||
505 | * Submitted by Daniel Sangorrin | ||
506 | */ | ||
507 | #define CONTEC_VID 0x06CE /* Vendor ID */ | ||
508 | #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ | ||
509 | |||
510 | /* | ||
504 | * Definitions for B&B Electronics products. | 511 | * Definitions for B&B Electronics products. |
505 | */ | 512 | */ |
506 | #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ | 513 | #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 89fac36684c5..f804acb138ec 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -130,7 +130,7 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port | |||
130 | spin_unlock_irqrestore(&port->lock, flags); | 130 | spin_unlock_irqrestore(&port->lock, flags); |
131 | 131 | ||
132 | /* if we have a bulk endpoint, start reading from it */ | 132 | /* if we have a bulk endpoint, start reading from it */ |
133 | if (serial->num_bulk_in) { | 133 | if (port->bulk_in_size) { |
134 | /* Start reading from the device */ | 134 | /* Start reading from the device */ |
135 | usb_fill_bulk_urb(port->read_urb, serial->dev, | 135 | usb_fill_bulk_urb(port->read_urb, serial->dev, |
136 | usb_rcvbulkpipe(serial->dev, | 136 | usb_rcvbulkpipe(serial->dev, |
@@ -159,10 +159,10 @@ static void generic_cleanup(struct usb_serial_port *port) | |||
159 | dbg("%s - port %d", __func__, port->number); | 159 | dbg("%s - port %d", __func__, port->number); |
160 | 160 | ||
161 | if (serial->dev) { | 161 | if (serial->dev) { |
162 | /* shutdown any bulk reads that might be going on */ | 162 | /* shutdown any bulk transfers that might be going on */ |
163 | if (serial->num_bulk_out) | 163 | if (port->bulk_out_size) |
164 | usb_kill_urb(port->write_urb); | 164 | usb_kill_urb(port->write_urb); |
165 | if (serial->num_bulk_in) | 165 | if (port->bulk_in_size) |
166 | usb_kill_urb(port->read_urb); | 166 | usb_kill_urb(port->read_urb); |
167 | } | 167 | } |
168 | } | 168 | } |
@@ -333,15 +333,15 @@ int usb_serial_generic_write(struct tty_struct *tty, | |||
333 | 333 | ||
334 | dbg("%s - port %d", __func__, port->number); | 334 | dbg("%s - port %d", __func__, port->number); |
335 | 335 | ||
336 | /* only do something if we have a bulk out endpoint */ | ||
337 | if (!port->bulk_out_size) | ||
338 | return -ENODEV; | ||
339 | |||
336 | if (count == 0) { | 340 | if (count == 0) { |
337 | dbg("%s - write request of 0 bytes", __func__); | 341 | dbg("%s - write request of 0 bytes", __func__); |
338 | return 0; | 342 | return 0; |
339 | } | 343 | } |
340 | 344 | ||
341 | /* only do something if we have a bulk out endpoint */ | ||
342 | if (!serial->num_bulk_out) | ||
343 | return 0; | ||
344 | |||
345 | if (serial->type->max_in_flight_urbs) | 345 | if (serial->type->max_in_flight_urbs) |
346 | return usb_serial_multi_urb_write(tty, port, | 346 | return usb_serial_multi_urb_write(tty, port, |
347 | buf, count); | 347 | buf, count); |
@@ -364,14 +364,19 @@ int usb_serial_generic_write_room(struct tty_struct *tty) | |||
364 | int room = 0; | 364 | int room = 0; |
365 | 365 | ||
366 | dbg("%s - port %d", __func__, port->number); | 366 | dbg("%s - port %d", __func__, port->number); |
367 | |||
368 | if (!port->bulk_out_size) | ||
369 | return 0; | ||
370 | |||
367 | spin_lock_irqsave(&port->lock, flags); | 371 | spin_lock_irqsave(&port->lock, flags); |
368 | if (serial->type->max_in_flight_urbs) { | 372 | if (serial->type->max_in_flight_urbs) { |
369 | if (port->urbs_in_flight < serial->type->max_in_flight_urbs) | 373 | if (port->urbs_in_flight < serial->type->max_in_flight_urbs) |
370 | room = port->bulk_out_size * | 374 | room = port->bulk_out_size * |
371 | (serial->type->max_in_flight_urbs - | 375 | (serial->type->max_in_flight_urbs - |
372 | port->urbs_in_flight); | 376 | port->urbs_in_flight); |
373 | } else if (serial->num_bulk_out) | 377 | } else { |
374 | room = kfifo_avail(&port->write_fifo); | 378 | room = kfifo_avail(&port->write_fifo); |
379 | } | ||
375 | spin_unlock_irqrestore(&port->lock, flags); | 380 | spin_unlock_irqrestore(&port->lock, flags); |
376 | 381 | ||
377 | dbg("%s - returns %d", __func__, room); | 382 | dbg("%s - returns %d", __func__, room); |
@@ -382,15 +387,18 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) | |||
382 | { | 387 | { |
383 | struct usb_serial_port *port = tty->driver_data; | 388 | struct usb_serial_port *port = tty->driver_data; |
384 | struct usb_serial *serial = port->serial; | 389 | struct usb_serial *serial = port->serial; |
385 | int chars = 0; | ||
386 | unsigned long flags; | 390 | unsigned long flags; |
391 | int chars; | ||
387 | 392 | ||
388 | dbg("%s - port %d", __func__, port->number); | 393 | dbg("%s - port %d", __func__, port->number); |
389 | 394 | ||
395 | if (!port->bulk_out_size) | ||
396 | return 0; | ||
397 | |||
390 | spin_lock_irqsave(&port->lock, flags); | 398 | spin_lock_irqsave(&port->lock, flags); |
391 | if (serial->type->max_in_flight_urbs) | 399 | if (serial->type->max_in_flight_urbs) |
392 | chars = port->tx_bytes_flight; | 400 | chars = port->tx_bytes_flight; |
393 | else if (serial->num_bulk_out) | 401 | else |
394 | chars = kfifo_len(&port->write_fifo); | 402 | chars = kfifo_len(&port->write_fifo); |
395 | spin_unlock_irqrestore(&port->lock, flags); | 403 | spin_unlock_irqrestore(&port->lock, flags); |
396 | 404 | ||
@@ -415,11 +423,13 @@ void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port, | |||
415 | ((serial->type->read_bulk_callback) ? | 423 | ((serial->type->read_bulk_callback) ? |
416 | serial->type->read_bulk_callback : | 424 | serial->type->read_bulk_callback : |
417 | usb_serial_generic_read_bulk_callback), port); | 425 | usb_serial_generic_read_bulk_callback), port); |
426 | |||
418 | result = usb_submit_urb(urb, mem_flags); | 427 | result = usb_submit_urb(urb, mem_flags); |
419 | if (result) | 428 | if (result && result != -EPERM) { |
420 | dev_err(&port->dev, | 429 | dev_err(&port->dev, |
421 | "%s - failed resubmitting read urb, error %d\n", | 430 | "%s - failed resubmitting read urb, error %d\n", |
422 | __func__, result); | 431 | __func__, result); |
432 | } | ||
423 | } | 433 | } |
424 | EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb); | 434 | EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb); |
425 | 435 | ||
@@ -498,23 +508,18 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) | |||
498 | if (port->urbs_in_flight < 0) | 508 | if (port->urbs_in_flight < 0) |
499 | port->urbs_in_flight = 0; | 509 | port->urbs_in_flight = 0; |
500 | spin_unlock_irqrestore(&port->lock, flags); | 510 | spin_unlock_irqrestore(&port->lock, flags); |
501 | |||
502 | if (status) { | ||
503 | dbg("%s - nonzero multi-urb write bulk status " | ||
504 | "received: %d", __func__, status); | ||
505 | return; | ||
506 | } | ||
507 | } else { | 511 | } else { |
508 | port->write_urb_busy = 0; | 512 | port->write_urb_busy = 0; |
509 | 513 | ||
510 | if (status) { | 514 | if (status) |
511 | dbg("%s - nonzero multi-urb write bulk status " | ||
512 | "received: %d", __func__, status); | ||
513 | kfifo_reset_out(&port->write_fifo); | 515 | kfifo_reset_out(&port->write_fifo); |
514 | } else | 516 | else |
515 | usb_serial_generic_write_start(port); | 517 | usb_serial_generic_write_start(port); |
516 | } | 518 | } |
517 | 519 | ||
520 | if (status) | ||
521 | dbg("%s - non-zero urb status: %d", __func__, status); | ||
522 | |||
518 | usb_serial_port_softint(port); | 523 | usb_serial_port_softint(port); |
519 | } | 524 | } |
520 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); | 525 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 847b805d63a3..950cb311ca94 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -288,7 +288,9 @@ static int option_resume(struct usb_serial *serial); | |||
288 | 288 | ||
289 | #define QUALCOMM_VENDOR_ID 0x05C6 | 289 | #define QUALCOMM_VENDOR_ID 0x05C6 |
290 | 290 | ||
291 | #define MAXON_VENDOR_ID 0x16d8 | 291 | #define CMOTECH_VENDOR_ID 0x16d8 |
292 | #define CMOTECH_PRODUCT_6008 0x6008 | ||
293 | #define CMOTECH_PRODUCT_6280 0x6280 | ||
292 | 294 | ||
293 | #define TELIT_VENDOR_ID 0x1bc7 | 295 | #define TELIT_VENDOR_ID 0x1bc7 |
294 | #define TELIT_PRODUCT_UC864E 0x1003 | 296 | #define TELIT_PRODUCT_UC864E 0x1003 |
@@ -309,6 +311,7 @@ static int option_resume(struct usb_serial *serial); | |||
309 | #define DLINK_VENDOR_ID 0x1186 | 311 | #define DLINK_VENDOR_ID 0x1186 |
310 | #define DLINK_PRODUCT_DWM_652 0x3e04 | 312 | #define DLINK_PRODUCT_DWM_652 0x3e04 |
311 | #define DLINK_PRODUCT_DWM_652_U5 0xce16 | 313 | #define DLINK_PRODUCT_DWM_652_U5 0xce16 |
314 | #define DLINK_PRODUCT_DWM_652_U5A 0xce1e | ||
312 | 315 | ||
313 | #define QISDA_VENDOR_ID 0x1da5 | 316 | #define QISDA_VENDOR_ID 0x1da5 |
314 | #define QISDA_PRODUCT_H21_4512 0x4512 | 317 | #define QISDA_PRODUCT_H21_4512 0x4512 |
@@ -332,6 +335,24 @@ static int option_resume(struct usb_serial *serial); | |||
332 | #define ALCATEL_VENDOR_ID 0x1bbb | 335 | #define ALCATEL_VENDOR_ID 0x1bbb |
333 | #define ALCATEL_PRODUCT_X060S 0x0000 | 336 | #define ALCATEL_PRODUCT_X060S 0x0000 |
334 | 337 | ||
338 | #define PIRELLI_VENDOR_ID 0x1266 | ||
339 | #define PIRELLI_PRODUCT_C100_1 0x1002 | ||
340 | #define PIRELLI_PRODUCT_C100_2 0x1003 | ||
341 | #define PIRELLI_PRODUCT_1004 0x1004 | ||
342 | #define PIRELLI_PRODUCT_1005 0x1005 | ||
343 | #define PIRELLI_PRODUCT_1006 0x1006 | ||
344 | #define PIRELLI_PRODUCT_1007 0x1007 | ||
345 | #define PIRELLI_PRODUCT_1008 0x1008 | ||
346 | #define PIRELLI_PRODUCT_1009 0x1009 | ||
347 | #define PIRELLI_PRODUCT_100A 0x100a | ||
348 | #define PIRELLI_PRODUCT_100B 0x100b | ||
349 | #define PIRELLI_PRODUCT_100C 0x100c | ||
350 | #define PIRELLI_PRODUCT_100D 0x100d | ||
351 | #define PIRELLI_PRODUCT_100E 0x100e | ||
352 | #define PIRELLI_PRODUCT_100F 0x100f | ||
353 | #define PIRELLI_PRODUCT_1011 0x1011 | ||
354 | #define PIRELLI_PRODUCT_1012 0x1012 | ||
355 | |||
335 | /* Airplus products */ | 356 | /* Airplus products */ |
336 | #define AIRPLUS_VENDOR_ID 0x1011 | 357 | #define AIRPLUS_VENDOR_ID 0x1011 |
337 | #define AIRPLUS_PRODUCT_MCD650 0x3198 | 358 | #define AIRPLUS_PRODUCT_MCD650 0x3198 |
@@ -547,7 +568,8 @@ static const struct usb_device_id option_ids[] = { | |||
547 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, | 568 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, |
548 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ | 569 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ |
549 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 570 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
550 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ | 571 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ |
572 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, | ||
551 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, | 573 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, |
552 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, | 574 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, |
553 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ | 575 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ |
@@ -659,6 +681,7 @@ static const struct usb_device_id option_ids[] = { | |||
659 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 681 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
660 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 682 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
661 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ | 683 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ |
684 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5A) }, | ||
662 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, | 685 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, |
663 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, | 686 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, |
664 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, | 687 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, |
@@ -666,7 +689,6 @@ static const struct usb_device_id option_ids[] = { | |||
666 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, | 689 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, |
667 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ | 690 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ |
668 | { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, | 691 | { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, |
669 | { USB_DEVICE(ALINK_VENDOR_ID, 0xce16) }, | ||
670 | { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, | 692 | { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, |
671 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, | 693 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, |
672 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, | 694 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, |
@@ -675,6 +697,24 @@ static const struct usb_device_id option_ids[] = { | |||
675 | .driver_info = (kernel_ulong_t)&four_g_w14_blacklist | 697 | .driver_info = (kernel_ulong_t)&four_g_w14_blacklist |
676 | }, | 698 | }, |
677 | { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, | 699 | { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, |
700 | /* Pirelli */ | ||
701 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)}, | ||
702 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)}, | ||
703 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)}, | ||
704 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)}, | ||
705 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)}, | ||
706 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)}, | ||
707 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)}, | ||
708 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)}, | ||
709 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)}, | ||
710 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) }, | ||
711 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) }, | ||
712 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) }, | ||
713 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) }, | ||
714 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, | ||
715 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, | ||
716 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, | ||
717 | |||
678 | { } /* Terminating entry */ | 718 | { } /* Terminating entry */ |
679 | }; | 719 | }; |
680 | MODULE_DEVICE_TABLE(usb, option_ids); | 720 | MODULE_DEVICE_TABLE(usb, option_ids); |
@@ -798,12 +838,19 @@ static int option_probe(struct usb_serial *serial, | |||
798 | const struct usb_device_id *id) | 838 | const struct usb_device_id *id) |
799 | { | 839 | { |
800 | struct option_intf_private *data; | 840 | struct option_intf_private *data; |
841 | |||
801 | /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ | 842 | /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ |
802 | if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && | 843 | if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && |
803 | serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && | 844 | serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && |
804 | serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) | 845 | serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) |
805 | return -ENODEV; | 846 | return -ENODEV; |
806 | 847 | ||
848 | /* Bandrich modem and AT command interface is 0xff */ | ||
849 | if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID || | ||
850 | serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) && | ||
851 | serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) | ||
852 | return -ENODEV; | ||
853 | |||
807 | data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL); | 854 | data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL); |
808 | if (!data) | 855 | if (!data) |
809 | return -ENOMEM; | 856 | return -ENOMEM; |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 310ff6ec6567..53a2d5a935a2 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -47,6 +47,35 @@ static const struct usb_device_id id_table[] = { | |||
47 | {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ | 47 | {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ |
48 | {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ | 48 | {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ |
49 | {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ | 49 | {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ |
50 | {USB_DEVICE(0x413c, 0x8185)}, /* Dell Gobi 2000 QDL device (N0218, VU936) */ | ||
51 | {USB_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ | ||
52 | {USB_DEVICE(0x05c6, 0x9224)}, /* Sony Gobi 2000 QDL device (N0279, VU730) */ | ||
53 | {USB_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ | ||
54 | {USB_DEVICE(0x05c6, 0x9244)}, /* Samsung Gobi 2000 QDL device (VL176) */ | ||
55 | {USB_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ | ||
56 | {USB_DEVICE(0x03f0, 0x241d)}, /* HP Gobi 2000 QDL device (VP412) */ | ||
57 | {USB_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ | ||
58 | {USB_DEVICE(0x05c6, 0x9214)}, /* Acer Gobi 2000 QDL device (VP413) */ | ||
59 | {USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ | ||
60 | {USB_DEVICE(0x05c6, 0x9264)}, /* Asus Gobi 2000 QDL device (VR305) */ | ||
61 | {USB_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ | ||
62 | {USB_DEVICE(0x05c6, 0x9234)}, /* Top Global Gobi 2000 QDL device (VR306) */ | ||
63 | {USB_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ | ||
64 | {USB_DEVICE(0x05c6, 0x9274)}, /* iRex Technologies Gobi 2000 QDL device (VR307) */ | ||
65 | {USB_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ | ||
66 | {USB_DEVICE(0x1199, 0x9000)}, /* Sierra Wireless Gobi 2000 QDL device (VT773) */ | ||
67 | {USB_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
68 | {USB_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
69 | {USB_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
70 | {USB_DEVICE(0x1199, 0x9004)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
71 | {USB_DEVICE(0x1199, 0x9005)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
72 | {USB_DEVICE(0x1199, 0x9006)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
73 | {USB_DEVICE(0x1199, 0x9007)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
74 | {USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
75 | {USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
76 | {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||
77 | {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ | ||
78 | {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ | ||
50 | { } /* Terminating entry */ | 79 | { } /* Terminating entry */ |
51 | }; | 80 | }; |
52 | MODULE_DEVICE_TABLE(usb, id_table); | 81 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 98b549b1cab2..ccf1dbbb87ef 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -374,6 +374,15 @@ UNUSUAL_DEV( 0x04ce, 0x0002, 0x0074, 0x0074, | |||
374 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 374 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
375 | US_FL_FIX_INQUIRY), | 375 | US_FL_FIX_INQUIRY), |
376 | 376 | ||
377 | /* Reported by Ondrej Zary <linux@rainbow-software.org> | ||
378 | * The device reports one sector more and breaks when that sector is accessed | ||
379 | */ | ||
380 | UNUSUAL_DEV( 0x04ce, 0x0002, 0x026c, 0x026c, | ||
381 | "ScanLogic", | ||
382 | "SL11R-IDE", | ||
383 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
384 | US_FL_FIX_CAPACITY), | ||
385 | |||
377 | /* Reported by Kriston Fincher <kriston@airmail.net> | 386 | /* Reported by Kriston Fincher <kriston@airmail.net> |
378 | * Patch submitted by Sean Millichamp <sean@bruenor.org> | 387 | * Patch submitted by Sean Millichamp <sean@bruenor.org> |
379 | * This is to support the Panasonic PalmCam PV-SD4090 | 388 | * This is to support the Panasonic PalmCam PV-SD4090 |
@@ -1380,20 +1389,6 @@ UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100, | |||
1380 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1389 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1381 | US_FL_IGNORE_RESIDUE ), | 1390 | US_FL_IGNORE_RESIDUE ), |
1382 | 1391 | ||
1383 | /* Jeremy Katz <katzj@redhat.com>: | ||
1384 | * The Blackberry Pearl can run in two modes; a usb-storage only mode | ||
1385 | * and a mode that allows access via mass storage and to its database. | ||
1386 | * The berry_charge module will set the device to dual mode and thus we | ||
1387 | * should ignore its native mode if that module is built | ||
1388 | */ | ||
1389 | #ifdef CONFIG_USB_BERRY_CHARGE | ||
1390 | UNUSUAL_DEV( 0x0fca, 0x0006, 0x0001, 0x0001, | ||
1391 | "RIM", | ||
1392 | "Blackberry Pearl", | ||
1393 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1394 | US_FL_IGNORE_DEVICE ), | ||
1395 | #endif | ||
1396 | |||
1397 | /* Reported by Michael Stattmann <michael@stattmann.com> */ | 1392 | /* Reported by Michael Stattmann <michael@stattmann.com> */ |
1398 | UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, | 1393 | UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, |
1399 | "Sony Ericsson", | 1394 | "Sony Ericsson", |
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index e7eeb63fab23..b409c228f254 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c | |||
@@ -891,7 +891,7 @@ static int hwarc_post_reset(struct usb_interface *iface) | |||
891 | } | 891 | } |
892 | 892 | ||
893 | /** USB device ID's that we handle */ | 893 | /** USB device ID's that we handle */ |
894 | static struct usb_device_id hwarc_id_table[] = { | 894 | static const struct usb_device_id hwarc_id_table[] = { |
895 | /* D-Link DUB-1210 */ | 895 | /* D-Link DUB-1210 */ |
896 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3d02, 0xe0, 0x01, 0x02), | 896 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3d02, 0xe0, 0x01, 0x02), |
897 | .driver_info = WUSB_QUIRK_WHCI_CMD_EVT }, | 897 | .driver_info = WUSB_QUIRK_WHCI_CMD_EVT }, |
diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c index 0bb665a0c024..a99e211a1b87 100644 --- a/drivers/uwb/i1480/dfu/usb.c +++ b/drivers/uwb/i1480/dfu/usb.c | |||
@@ -120,8 +120,7 @@ int i1480_usb_write(struct i1480 *i1480, u32 memory_address, | |||
120 | result = usb_control_msg( | 120 | result = usb_control_msg( |
121 | i1480_usb->usb_dev, usb_sndctrlpipe(i1480_usb->usb_dev, 0), | 121 | i1480_usb->usb_dev, usb_sndctrlpipe(i1480_usb->usb_dev, 0), |
122 | 0xf0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 122 | 0xf0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
123 | cpu_to_le16(memory_address & 0xffff), | 123 | memory_address, (memory_address >> 16), |
124 | cpu_to_le16((memory_address >> 16) & 0xffff), | ||
125 | i1480->cmd_buf, buffer_size, 100 /* FIXME: arbitrary */); | 124 | i1480->cmd_buf, buffer_size, 100 /* FIXME: arbitrary */); |
126 | if (result < 0) | 125 | if (result < 0) |
127 | break; | 126 | break; |
@@ -166,8 +165,7 @@ int i1480_usb_read(struct i1480 *i1480, u32 addr, size_t size) | |||
166 | result = usb_control_msg( | 165 | result = usb_control_msg( |
167 | i1480_usb->usb_dev, usb_rcvctrlpipe(i1480_usb->usb_dev, 0), | 166 | i1480_usb->usb_dev, usb_rcvctrlpipe(i1480_usb->usb_dev, 0), |
168 | 0xf0, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 167 | 0xf0, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
169 | cpu_to_le16(itr_addr & 0xffff), | 168 | itr_addr, (itr_addr >> 16), |
170 | cpu_to_le16((itr_addr >> 16) & 0xffff), | ||
171 | i1480->cmd_buf + itr, itr_size, | 169 | i1480->cmd_buf + itr, itr_size, |
172 | 100 /* FIXME: arbitrary */); | 170 | 100 /* FIXME: arbitrary */); |
173 | if (result < 0) { | 171 | if (result < 0) { |
@@ -413,6 +411,10 @@ error: | |||
413 | return result; | 411 | return result; |
414 | } | 412 | } |
415 | 413 | ||
414 | MODULE_FIRMWARE("i1480-pre-phy-0.0.bin"); | ||
415 | MODULE_FIRMWARE("i1480-usb-0.0.bin"); | ||
416 | MODULE_FIRMWARE("i1480-phy-0.0.bin"); | ||
417 | |||
416 | #define i1480_USB_DEV(v, p) \ | 418 | #define i1480_USB_DEV(v, p) \ |
417 | { \ | 419 | { \ |
418 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE \ | 420 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE \ |
@@ -430,7 +432,7 @@ error: | |||
430 | 432 | ||
431 | 433 | ||
432 | /** USB device ID's that we handle */ | 434 | /** USB device ID's that we handle */ |
433 | static struct usb_device_id i1480_usb_id_table[] = { | 435 | static const struct usb_device_id i1480_usb_id_table[] = { |
434 | i1480_USB_DEV(0x8086, 0xdf3b), | 436 | i1480_USB_DEV(0x8086, 0xdf3b), |
435 | i1480_USB_DEV(0x15a9, 0x0005), | 437 | i1480_USB_DEV(0x15a9, 0x0005), |
436 | i1480_USB_DEV(0x07d1, 0x3802), | 438 | i1480_USB_DEV(0x07d1, 0x3802), |
diff --git a/drivers/uwb/wlp/messages.c b/drivers/uwb/wlp/messages.c index aa42fcee4c4f..75164866c2d8 100644 --- a/drivers/uwb/wlp/messages.c +++ b/drivers/uwb/wlp/messages.c | |||
@@ -259,6 +259,63 @@ out: | |||
259 | } | 259 | } |
260 | 260 | ||
261 | 261 | ||
262 | static ssize_t wlp_get_attribute(struct wlp *wlp, u16 type_code, | ||
263 | struct wlp_attr_hdr *attr_hdr, void *value, ssize_t value_len, | ||
264 | ssize_t buflen) | ||
265 | { | ||
266 | struct device *dev = &wlp->rc->uwb_dev.dev; | ||
267 | ssize_t attr_len = sizeof(*attr_hdr) + value_len; | ||
268 | if (buflen < 0) | ||
269 | return -EINVAL; | ||
270 | if (buflen < attr_len) { | ||
271 | dev_err(dev, "WLP: Not enough space in buffer to parse" | ||
272 | " attribute field. Need %d, received %zu\n", | ||
273 | (int)attr_len, buflen); | ||
274 | return -EIO; | ||
275 | } | ||
276 | if (wlp_check_attr_hdr(wlp, attr_hdr, type_code, value_len) < 0) { | ||
277 | dev_err(dev, "WLP: Header verification failed. \n"); | ||
278 | return -EINVAL; | ||
279 | } | ||
280 | memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), value_len); | ||
281 | return attr_len; | ||
282 | } | ||
283 | |||
284 | static ssize_t wlp_vget_attribute(struct wlp *wlp, u16 type_code, | ||
285 | struct wlp_attr_hdr *attr_hdr, void *value, ssize_t max_value_len, | ||
286 | ssize_t buflen) | ||
287 | { | ||
288 | struct device *dev = &wlp->rc->uwb_dev.dev; | ||
289 | size_t len; | ||
290 | if (buflen < 0) | ||
291 | return -EINVAL; | ||
292 | if (buflen < sizeof(*attr_hdr)) { | ||
293 | dev_err(dev, "WLP: Not enough space in buffer to parse" | ||
294 | " header.\n"); | ||
295 | return -EIO; | ||
296 | } | ||
297 | if (le16_to_cpu(attr_hdr->type) != type_code) { | ||
298 | dev_err(dev, "WLP: Unexpected attribute type. Got %u, " | ||
299 | "expected %u.\n", le16_to_cpu(attr_hdr->type), | ||
300 | type_code); | ||
301 | return -EINVAL; | ||
302 | } | ||
303 | len = le16_to_cpu(attr_hdr->length); | ||
304 | if (len > max_value_len) { | ||
305 | dev_err(dev, "WLP: Attribute larger than maximum " | ||
306 | "allowed. Received %zu, max is %d.\n", len, | ||
307 | (int)max_value_len); | ||
308 | return -EFBIG; | ||
309 | } | ||
310 | if (buflen < sizeof(*attr_hdr) + len) { | ||
311 | dev_err(dev, "WLP: Not enough space in buffer to parse " | ||
312 | "variable data.\n"); | ||
313 | return -EIO; | ||
314 | } | ||
315 | memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), len); | ||
316 | return sizeof(*attr_hdr) + len; | ||
317 | } | ||
318 | |||
262 | /** | 319 | /** |
263 | * Get value of attribute from fixed size attribute field. | 320 | * Get value of attribute from fixed size attribute field. |
264 | * | 321 | * |
@@ -274,22 +331,8 @@ out: | |||
274 | ssize_t wlp_get_##name(struct wlp *wlp, struct wlp_attr_##name *attr, \ | 331 | ssize_t wlp_get_##name(struct wlp *wlp, struct wlp_attr_##name *attr, \ |
275 | type *value, ssize_t buflen) \ | 332 | type *value, ssize_t buflen) \ |
276 | { \ | 333 | { \ |
277 | struct device *dev = &wlp->rc->uwb_dev.dev; \ | 334 | return wlp_get_attribute(wlp, (type_code), &attr->hdr, \ |
278 | if (buflen < 0) \ | 335 | value, sizeof(*value), buflen); \ |
279 | return -EINVAL; \ | ||
280 | if (buflen < sizeof(*attr)) { \ | ||
281 | dev_err(dev, "WLP: Not enough space in buffer to parse" \ | ||
282 | " attribute field. Need %d, received %zu\n", \ | ||
283 | (int)sizeof(*attr), buflen); \ | ||
284 | return -EIO; \ | ||
285 | } \ | ||
286 | if (wlp_check_attr_hdr(wlp, &attr->hdr, type_code, \ | ||
287 | sizeof(attr->name)) < 0) { \ | ||
288 | dev_err(dev, "WLP: Header verification failed. \n"); \ | ||
289 | return -EINVAL; \ | ||
290 | } \ | ||
291 | *value = attr->name; \ | ||
292 | return sizeof(*attr); \ | ||
293 | } | 336 | } |
294 | 337 | ||
295 | #define wlp_get_sparse(type, type_code, name) \ | 338 | #define wlp_get_sparse(type, type_code, name) \ |
@@ -313,35 +356,8 @@ static ssize_t wlp_get_##name(struct wlp *wlp, \ | |||
313 | struct wlp_attr_##name *attr, \ | 356 | struct wlp_attr_##name *attr, \ |
314 | type_val *value, ssize_t buflen) \ | 357 | type_val *value, ssize_t buflen) \ |
315 | { \ | 358 | { \ |
316 | struct device *dev = &wlp->rc->uwb_dev.dev; \ | 359 | return wlp_vget_attribute(wlp, (type_code), &attr->hdr, \ |
317 | size_t len; \ | 360 | value, (max), buflen); \ |
318 | if (buflen < 0) \ | ||
319 | return -EINVAL; \ | ||
320 | if (buflen < sizeof(*attr)) { \ | ||
321 | dev_err(dev, "WLP: Not enough space in buffer to parse" \ | ||
322 | " header.\n"); \ | ||
323 | return -EIO; \ | ||
324 | } \ | ||
325 | if (le16_to_cpu(attr->hdr.type) != type_code) { \ | ||
326 | dev_err(dev, "WLP: Unexpected attribute type. Got %u, " \ | ||
327 | "expected %u.\n", le16_to_cpu(attr->hdr.type), \ | ||
328 | type_code); \ | ||
329 | return -EINVAL; \ | ||
330 | } \ | ||
331 | len = le16_to_cpu(attr->hdr.length); \ | ||
332 | if (len > max) { \ | ||
333 | dev_err(dev, "WLP: Attribute larger than maximum " \ | ||
334 | "allowed. Received %zu, max is %d.\n", len, \ | ||
335 | (int)max); \ | ||
336 | return -EFBIG; \ | ||
337 | } \ | ||
338 | if (buflen < sizeof(*attr) + len) { \ | ||
339 | dev_err(dev, "WLP: Not enough space in buffer to parse "\ | ||
340 | "variable data.\n"); \ | ||
341 | return -EIO; \ | ||
342 | } \ | ||
343 | memcpy(value, (void *) attr + sizeof(*attr), len); \ | ||
344 | return sizeof(*attr) + len; \ | ||
345 | } | 361 | } |
346 | 362 | ||
347 | wlp_get(u8, WLP_ATTR_WLP_VER, version) | 363 | wlp_get(u8, WLP_ATTR_WLP_VER, version) |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index dabe804ba575..6e16244f3ed1 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -914,7 +914,7 @@ config FB_XVR2500 | |||
914 | 914 | ||
915 | config FB_XVR1000 | 915 | config FB_XVR1000 |
916 | bool "Sun XVR-1000 support" | 916 | bool "Sun XVR-1000 support" |
917 | depends on SPARC64 | 917 | depends on (FB = y) && SPARC64 |
918 | select FB_CFB_FILLRECT | 918 | select FB_CFB_FILLRECT |
919 | select FB_CFB_COPYAREA | 919 | select FB_CFB_COPYAREA |
920 | select FB_CFB_IMAGEBLIT | 920 | select FB_CFB_IMAGEBLIT |
@@ -1881,7 +1881,7 @@ config FB_W100 | |||
1881 | 1881 | ||
1882 | config FB_SH_MOBILE_LCDC | 1882 | config FB_SH_MOBILE_LCDC |
1883 | tristate "SuperH Mobile LCDC framebuffer support" | 1883 | tristate "SuperH Mobile LCDC framebuffer support" |
1884 | depends on FB && SUPERH && HAVE_CLK | 1884 | depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK |
1885 | select FB_SYS_FILLRECT | 1885 | select FB_SYS_FILLRECT |
1886 | select FB_SYS_COPYAREA | 1886 | select FB_SYS_COPYAREA |
1887 | select FB_SYS_IMAGEBLIT | 1887 | select FB_SYS_IMAGEBLIT |
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index a21efcd10b78..afe21e6eb544 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c | |||
@@ -65,16 +65,16 @@ static void clcdfb_disable(struct clcd_fb *fb) | |||
65 | if (fb->board->disable) | 65 | if (fb->board->disable) |
66 | fb->board->disable(fb); | 66 | fb->board->disable(fb); |
67 | 67 | ||
68 | val = readl(fb->regs + CLCD_CNTL); | 68 | val = readl(fb->regs + fb->off_cntl); |
69 | if (val & CNTL_LCDPWR) { | 69 | if (val & CNTL_LCDPWR) { |
70 | val &= ~CNTL_LCDPWR; | 70 | val &= ~CNTL_LCDPWR; |
71 | writel(val, fb->regs + CLCD_CNTL); | 71 | writel(val, fb->regs + fb->off_cntl); |
72 | 72 | ||
73 | clcdfb_sleep(20); | 73 | clcdfb_sleep(20); |
74 | } | 74 | } |
75 | if (val & CNTL_LCDEN) { | 75 | if (val & CNTL_LCDEN) { |
76 | val &= ~CNTL_LCDEN; | 76 | val &= ~CNTL_LCDEN; |
77 | writel(val, fb->regs + CLCD_CNTL); | 77 | writel(val, fb->regs + fb->off_cntl); |
78 | } | 78 | } |
79 | 79 | ||
80 | /* | 80 | /* |
@@ -94,7 +94,7 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) | |||
94 | * Bring up by first enabling.. | 94 | * Bring up by first enabling.. |
95 | */ | 95 | */ |
96 | cntl |= CNTL_LCDEN; | 96 | cntl |= CNTL_LCDEN; |
97 | writel(cntl, fb->regs + CLCD_CNTL); | 97 | writel(cntl, fb->regs + fb->off_cntl); |
98 | 98 | ||
99 | clcdfb_sleep(20); | 99 | clcdfb_sleep(20); |
100 | 100 | ||
@@ -102,7 +102,7 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) | |||
102 | * and now apply power. | 102 | * and now apply power. |
103 | */ | 103 | */ |
104 | cntl |= CNTL_LCDPWR; | 104 | cntl |= CNTL_LCDPWR; |
105 | writel(cntl, fb->regs + CLCD_CNTL); | 105 | writel(cntl, fb->regs + fb->off_cntl); |
106 | 106 | ||
107 | /* | 107 | /* |
108 | * finally, enable the interface. | 108 | * finally, enable the interface. |
@@ -233,7 +233,7 @@ static int clcdfb_set_par(struct fb_info *info) | |||
233 | readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1), | 233 | readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1), |
234 | readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3), | 234 | readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3), |
235 | readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS), | 235 | readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS), |
236 | readl(fb->regs + CLCD_IENB), readl(fb->regs + CLCD_CNTL)); | 236 | readl(fb->regs + fb->off_ienb), readl(fb->regs + fb->off_cntl)); |
237 | #endif | 237 | #endif |
238 | 238 | ||
239 | return 0; | 239 | return 0; |
@@ -345,6 +345,23 @@ static int clcdfb_register(struct clcd_fb *fb) | |||
345 | { | 345 | { |
346 | int ret; | 346 | int ret; |
347 | 347 | ||
348 | /* | ||
349 | * ARM PL111 always has IENB at 0x1c; it's only PL110 | ||
350 | * which is reversed on some platforms. | ||
351 | */ | ||
352 | if (amba_manf(fb->dev) == 0x41 && amba_part(fb->dev) == 0x111) { | ||
353 | fb->off_ienb = CLCD_PL111_IENB; | ||
354 | fb->off_cntl = CLCD_PL111_CNTL; | ||
355 | } else { | ||
356 | #ifdef CONFIG_ARCH_VERSATILE | ||
357 | fb->off_ienb = CLCD_PL111_IENB; | ||
358 | fb->off_cntl = CLCD_PL111_CNTL; | ||
359 | #else | ||
360 | fb->off_ienb = CLCD_PL110_IENB; | ||
361 | fb->off_cntl = CLCD_PL110_CNTL; | ||
362 | #endif | ||
363 | } | ||
364 | |||
348 | fb->clk = clk_get(&fb->dev->dev, NULL); | 365 | fb->clk = clk_get(&fb->dev->dev, NULL); |
349 | if (IS_ERR(fb->clk)) { | 366 | if (IS_ERR(fb->clk)) { |
350 | ret = PTR_ERR(fb->clk); | 367 | ret = PTR_ERR(fb->clk); |
@@ -416,7 +433,7 @@ static int clcdfb_register(struct clcd_fb *fb) | |||
416 | /* | 433 | /* |
417 | * Ensure interrupts are disabled. | 434 | * Ensure interrupts are disabled. |
418 | */ | 435 | */ |
419 | writel(0, fb->regs + CLCD_IENB); | 436 | writel(0, fb->regs + fb->off_ienb); |
420 | 437 | ||
421 | fb_set_var(&fb->fb, &fb->fb.var); | 438 | fb_set_var(&fb->fb, &fb->fb.var); |
422 | 439 | ||
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 3d886c6902f9..11de3bfd4e54 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -117,6 +117,7 @@ static struct backlight_ops atmel_lcdc_bl_ops = { | |||
117 | 117 | ||
118 | static void init_backlight(struct atmel_lcdfb_info *sinfo) | 118 | static void init_backlight(struct atmel_lcdfb_info *sinfo) |
119 | { | 119 | { |
120 | struct backlight_properties props; | ||
120 | struct backlight_device *bl; | 121 | struct backlight_device *bl; |
121 | 122 | ||
122 | sinfo->bl_power = FB_BLANK_UNBLANK; | 123 | sinfo->bl_power = FB_BLANK_UNBLANK; |
@@ -124,8 +125,10 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo) | |||
124 | if (sinfo->backlight) | 125 | if (sinfo->backlight) |
125 | return; | 126 | return; |
126 | 127 | ||
127 | bl = backlight_device_register("backlight", &sinfo->pdev->dev, | 128 | memset(&props, 0, sizeof(struct backlight_properties)); |
128 | sinfo, &atmel_lcdc_bl_ops); | 129 | props.max_brightness = 0xff; |
130 | bl = backlight_device_register("backlight", &sinfo->pdev->dev, sinfo, | ||
131 | &atmel_lcdc_bl_ops, &props); | ||
129 | if (IS_ERR(bl)) { | 132 | if (IS_ERR(bl)) { |
130 | dev_err(&sinfo->pdev->dev, "error %ld on backlight register\n", | 133 | dev_err(&sinfo->pdev->dev, "error %ld on backlight register\n", |
131 | PTR_ERR(bl)); | 134 | PTR_ERR(bl)); |
@@ -135,7 +138,6 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo) | |||
135 | 138 | ||
136 | bl->props.power = FB_BLANK_UNBLANK; | 139 | bl->props.power = FB_BLANK_UNBLANK; |
137 | bl->props.fb_blank = FB_BLANK_UNBLANK; | 140 | bl->props.fb_blank = FB_BLANK_UNBLANK; |
138 | bl->props.max_brightness = 0xff; | ||
139 | bl->props.brightness = atmel_bl_get_brightness(bl); | 141 | bl->props.brightness = atmel_bl_get_brightness(bl); |
140 | } | 142 | } |
141 | 143 | ||
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 9ee67d6da710..a489be0c4614 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c | |||
@@ -1802,6 +1802,7 @@ static void aty128_bl_set_power(struct fb_info *info, int power) | |||
1802 | 1802 | ||
1803 | static void aty128_bl_init(struct aty128fb_par *par) | 1803 | static void aty128_bl_init(struct aty128fb_par *par) |
1804 | { | 1804 | { |
1805 | struct backlight_properties props; | ||
1805 | struct fb_info *info = pci_get_drvdata(par->pdev); | 1806 | struct fb_info *info = pci_get_drvdata(par->pdev); |
1806 | struct backlight_device *bd; | 1807 | struct backlight_device *bd; |
1807 | char name[12]; | 1808 | char name[12]; |
@@ -1817,7 +1818,10 @@ static void aty128_bl_init(struct aty128fb_par *par) | |||
1817 | 1818 | ||
1818 | snprintf(name, sizeof(name), "aty128bl%d", info->node); | 1819 | snprintf(name, sizeof(name), "aty128bl%d", info->node); |
1819 | 1820 | ||
1820 | bd = backlight_device_register(name, info->dev, par, &aty128_bl_data); | 1821 | memset(&props, 0, sizeof(struct backlight_properties)); |
1822 | props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | ||
1823 | bd = backlight_device_register(name, info->dev, par, &aty128_bl_data, | ||
1824 | &props); | ||
1821 | if (IS_ERR(bd)) { | 1825 | if (IS_ERR(bd)) { |
1822 | info->bl_dev = NULL; | 1826 | info->bl_dev = NULL; |
1823 | printk(KERN_WARNING "aty128: Backlight registration failed\n"); | 1827 | printk(KERN_WARNING "aty128: Backlight registration failed\n"); |
@@ -1829,7 +1833,6 @@ static void aty128_bl_init(struct aty128fb_par *par) | |||
1829 | 63 * FB_BACKLIGHT_MAX / MAX_LEVEL, | 1833 | 63 * FB_BACKLIGHT_MAX / MAX_LEVEL, |
1830 | 219 * FB_BACKLIGHT_MAX / MAX_LEVEL); | 1834 | 219 * FB_BACKLIGHT_MAX / MAX_LEVEL); |
1831 | 1835 | ||
1832 | bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | ||
1833 | bd->props.brightness = bd->props.max_brightness; | 1836 | bd->props.brightness = bd->props.max_brightness; |
1834 | bd->props.power = FB_BLANK_UNBLANK; | 1837 | bd->props.power = FB_BLANK_UNBLANK; |
1835 | backlight_update_status(bd); | 1838 | backlight_update_status(bd); |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index e45ab8db2ddc..29d72851f85b 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -2232,6 +2232,7 @@ static struct backlight_ops aty_bl_data = { | |||
2232 | 2232 | ||
2233 | static void aty_bl_init(struct atyfb_par *par) | 2233 | static void aty_bl_init(struct atyfb_par *par) |
2234 | { | 2234 | { |
2235 | struct backlight_properties props; | ||
2235 | struct fb_info *info = pci_get_drvdata(par->pdev); | 2236 | struct fb_info *info = pci_get_drvdata(par->pdev); |
2236 | struct backlight_device *bd; | 2237 | struct backlight_device *bd; |
2237 | char name[12]; | 2238 | char name[12]; |
@@ -2243,7 +2244,10 @@ static void aty_bl_init(struct atyfb_par *par) | |||
2243 | 2244 | ||
2244 | snprintf(name, sizeof(name), "atybl%d", info->node); | 2245 | snprintf(name, sizeof(name), "atybl%d", info->node); |
2245 | 2246 | ||
2246 | bd = backlight_device_register(name, info->dev, par, &aty_bl_data); | 2247 | memset(&props, 0, sizeof(struct backlight_properties)); |
2248 | props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | ||
2249 | bd = backlight_device_register(name, info->dev, par, &aty_bl_data, | ||
2250 | &props); | ||
2247 | if (IS_ERR(bd)) { | 2251 | if (IS_ERR(bd)) { |
2248 | info->bl_dev = NULL; | 2252 | info->bl_dev = NULL; |
2249 | printk(KERN_WARNING "aty: Backlight registration failed\n"); | 2253 | printk(KERN_WARNING "aty: Backlight registration failed\n"); |
@@ -2255,7 +2259,6 @@ static void aty_bl_init(struct atyfb_par *par) | |||
2255 | 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, | 2259 | 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, |
2256 | 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); | 2260 | 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); |
2257 | 2261 | ||
2258 | bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | ||
2259 | bd->props.brightness = bd->props.max_brightness; | 2262 | bd->props.brightness = bd->props.max_brightness; |
2260 | bd->props.power = FB_BLANK_UNBLANK; | 2263 | bd->props.power = FB_BLANK_UNBLANK; |
2261 | backlight_update_status(bd); | 2264 | backlight_update_status(bd); |
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index fa1198c4ccc5..9fc8c66be3ce 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c | |||
@@ -134,6 +134,7 @@ static struct backlight_ops radeon_bl_data = { | |||
134 | 134 | ||
135 | void radeonfb_bl_init(struct radeonfb_info *rinfo) | 135 | void radeonfb_bl_init(struct radeonfb_info *rinfo) |
136 | { | 136 | { |
137 | struct backlight_properties props; | ||
137 | struct backlight_device *bd; | 138 | struct backlight_device *bd; |
138 | struct radeon_bl_privdata *pdata; | 139 | struct radeon_bl_privdata *pdata; |
139 | char name[12]; | 140 | char name[12]; |
@@ -155,7 +156,10 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) | |||
155 | 156 | ||
156 | snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node); | 157 | snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node); |
157 | 158 | ||
158 | bd = backlight_device_register(name, rinfo->info->dev, pdata, &radeon_bl_data); | 159 | memset(&props, 0, sizeof(struct backlight_properties)); |
160 | props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | ||
161 | bd = backlight_device_register(name, rinfo->info->dev, pdata, | ||
162 | &radeon_bl_data, &props); | ||
159 | if (IS_ERR(bd)) { | 163 | if (IS_ERR(bd)) { |
160 | rinfo->info->bl_dev = NULL; | 164 | rinfo->info->bl_dev = NULL; |
161 | printk("radeonfb: Backlight registration failed\n"); | 165 | printk("radeonfb: Backlight registration failed\n"); |
@@ -185,7 +189,6 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) | |||
185 | 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL, | 189 | 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL, |
186 | 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL); | 190 | 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL); |
187 | 191 | ||
188 | bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | ||
189 | bd->props.brightness = bd->props.max_brightness; | 192 | bd->props.brightness = bd->props.max_brightness; |
190 | bd->props.power = FB_BLANK_UNBLANK; | 193 | bd->props.power = FB_BLANK_UNBLANK; |
191 | backlight_update_status(bd); | 194 | backlight_update_status(bd); |
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index b8f705cca438..93e25c77aeb2 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c | |||
@@ -187,6 +187,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev) | |||
187 | struct pm860x_backlight_data *data; | 187 | struct pm860x_backlight_data *data; |
188 | struct backlight_device *bl; | 188 | struct backlight_device *bl; |
189 | struct resource *res; | 189 | struct resource *res; |
190 | struct backlight_properties props; | ||
190 | unsigned char value; | 191 | unsigned char value; |
191 | char name[MFD_NAME_SIZE]; | 192 | char name[MFD_NAME_SIZE]; |
192 | int ret; | 193 | int ret; |
@@ -223,14 +224,15 @@ static int pm860x_backlight_probe(struct platform_device *pdev) | |||
223 | return -EINVAL; | 224 | return -EINVAL; |
224 | } | 225 | } |
225 | 226 | ||
227 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
228 | props.max_brightness = MAX_BRIGHTNESS; | ||
226 | bl = backlight_device_register(name, &pdev->dev, data, | 229 | bl = backlight_device_register(name, &pdev->dev, data, |
227 | &pm860x_backlight_ops); | 230 | &pm860x_backlight_ops, &props); |
228 | if (IS_ERR(bl)) { | 231 | if (IS_ERR(bl)) { |
229 | dev_err(&pdev->dev, "failed to register backlight\n"); | 232 | dev_err(&pdev->dev, "failed to register backlight\n"); |
230 | kfree(data); | 233 | kfree(data); |
231 | return PTR_ERR(bl); | 234 | return PTR_ERR(bl); |
232 | } | 235 | } |
233 | bl->props.max_brightness = MAX_BRIGHTNESS; | ||
234 | bl->props.brightness = MAX_BRIGHTNESS; | 236 | bl->props.brightness = MAX_BRIGHTNESS; |
235 | 237 | ||
236 | platform_set_drvdata(pdev, bl); | 238 | platform_set_drvdata(pdev, bl); |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 0c77fc610212..c025c84601b0 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -31,6 +31,13 @@ config LCD_CORGI | |||
31 | Say y here to support the LCD panels usually found on SHARP | 31 | Say y here to support the LCD panels usually found on SHARP |
32 | corgi (C7x0) and spitz (Cxx00) models. | 32 | corgi (C7x0) and spitz (Cxx00) models. |
33 | 33 | ||
34 | config LCD_L4F00242T03 | ||
35 | tristate "Epson L4F00242T03 LCD" | ||
36 | depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO | ||
37 | help | ||
38 | SPI driver for Epson L4F00242T03. This provides basic support | ||
39 | for init and powering the LCD up/down through a sysfs interface. | ||
40 | |||
34 | config LCD_LMS283GF05 | 41 | config LCD_LMS283GF05 |
35 | tristate "Samsung LMS283GF05 LCD" | 42 | tristate "Samsung LMS283GF05 LCD" |
36 | depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO | 43 | depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO |
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 6c704d41462d..09d1f14d6257 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile | |||
@@ -3,6 +3,7 @@ | |||
3 | obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o | 3 | obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o |
4 | obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o | 4 | obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o |
5 | obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o | 5 | obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o |
6 | obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o | ||
6 | obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o | 7 | obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o |
7 | obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o | 8 | obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o |
8 | obj-$(CONFIG_LCD_ILI9320) += ili9320.o | 9 | obj-$(CONFIG_LCD_ILI9320) += ili9320.o |
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c index 86d95c228adb..5183f0e4d314 100644 --- a/drivers/video/backlight/adp5520_bl.c +++ b/drivers/video/backlight/adp5520_bl.c | |||
@@ -278,6 +278,7 @@ static const struct attribute_group adp5520_bl_attr_group = { | |||
278 | 278 | ||
279 | static int __devinit adp5520_bl_probe(struct platform_device *pdev) | 279 | static int __devinit adp5520_bl_probe(struct platform_device *pdev) |
280 | { | 280 | { |
281 | struct backlight_properties props; | ||
281 | struct backlight_device *bl; | 282 | struct backlight_device *bl; |
282 | struct adp5520_bl *data; | 283 | struct adp5520_bl *data; |
283 | int ret = 0; | 284 | int ret = 0; |
@@ -300,17 +301,17 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev) | |||
300 | 301 | ||
301 | mutex_init(&data->lock); | 302 | mutex_init(&data->lock); |
302 | 303 | ||
303 | bl = backlight_device_register(pdev->name, data->master, | 304 | memset(&props, 0, sizeof(struct backlight_properties)); |
304 | data, &adp5520_bl_ops); | 305 | props.max_brightness = ADP5020_MAX_BRIGHTNESS; |
306 | bl = backlight_device_register(pdev->name, data->master, data, | ||
307 | &adp5520_bl_ops, &props); | ||
305 | if (IS_ERR(bl)) { | 308 | if (IS_ERR(bl)) { |
306 | dev_err(&pdev->dev, "failed to register backlight\n"); | 309 | dev_err(&pdev->dev, "failed to register backlight\n"); |
307 | kfree(data); | 310 | kfree(data); |
308 | return PTR_ERR(bl); | 311 | return PTR_ERR(bl); |
309 | } | 312 | } |
310 | 313 | ||
311 | bl->props.max_brightness = | 314 | bl->props.brightness = ADP5020_MAX_BRIGHTNESS; |
312 | bl->props.brightness = ADP5020_MAX_BRIGHTNESS; | ||
313 | |||
314 | if (data->pdata->en_ambl_sens) | 315 | if (data->pdata->en_ambl_sens) |
315 | ret = sysfs_create_group(&bl->dev.kobj, | 316 | ret = sysfs_create_group(&bl->dev.kobj, |
316 | &adp5520_bl_attr_group); | 317 | &adp5520_bl_attr_group); |
diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c index d769b0bab21a..b0624b983889 100644 --- a/drivers/video/backlight/adx_bl.c +++ b/drivers/video/backlight/adx_bl.c | |||
@@ -56,7 +56,7 @@ static int adx_backlight_get_brightness(struct backlight_device *bldev) | |||
56 | return brightness & 0xff; | 56 | return brightness & 0xff; |
57 | } | 57 | } |
58 | 58 | ||
59 | static int adx_backlight_check_fb(struct fb_info *fb) | 59 | static int adx_backlight_check_fb(struct backlight_device *bldev, struct fb_info *fb) |
60 | { | 60 | { |
61 | return 1; | 61 | return 1; |
62 | } | 62 | } |
@@ -70,6 +70,7 @@ static const struct backlight_ops adx_backlight_ops = { | |||
70 | 70 | ||
71 | static int __devinit adx_backlight_probe(struct platform_device *pdev) | 71 | static int __devinit adx_backlight_probe(struct platform_device *pdev) |
72 | { | 72 | { |
73 | struct backlight_properties props; | ||
73 | struct backlight_device *bldev; | 74 | struct backlight_device *bldev; |
74 | struct resource *res; | 75 | struct resource *res; |
75 | struct adxbl *bl; | 76 | struct adxbl *bl; |
@@ -101,14 +102,15 @@ static int __devinit adx_backlight_probe(struct platform_device *pdev) | |||
101 | goto out; | 102 | goto out; |
102 | } | 103 | } |
103 | 104 | ||
104 | bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, bl, | 105 | memset(&props, 0, sizeof(struct backlight_properties)); |
105 | &adx_backlight_ops); | 106 | props.max_brightness = 0xff; |
107 | bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, | ||
108 | bl, &adx_backlight_ops, &props); | ||
106 | if (!bldev) { | 109 | if (!bldev) { |
107 | ret = -ENOMEM; | 110 | ret = -ENOMEM; |
108 | goto out; | 111 | goto out; |
109 | } | 112 | } |
110 | 113 | ||
111 | bldev->props.max_brightness = 0xff; | ||
112 | bldev->props.brightness = 0xff; | 114 | bldev->props.brightness = 0xff; |
113 | bldev->props.power = FB_BLANK_UNBLANK; | 115 | bldev->props.power = FB_BLANK_UNBLANK; |
114 | 116 | ||
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c index f625ffc69ad3..2d9760551a4b 100644 --- a/drivers/video/backlight/atmel-pwm-bl.c +++ b/drivers/video/backlight/atmel-pwm-bl.c | |||
@@ -120,6 +120,7 @@ static const struct backlight_ops atmel_pwm_bl_ops = { | |||
120 | 120 | ||
121 | static int atmel_pwm_bl_probe(struct platform_device *pdev) | 121 | static int atmel_pwm_bl_probe(struct platform_device *pdev) |
122 | { | 122 | { |
123 | struct backlight_properties props; | ||
123 | const struct atmel_pwm_bl_platform_data *pdata; | 124 | const struct atmel_pwm_bl_platform_data *pdata; |
124 | struct backlight_device *bldev; | 125 | struct backlight_device *bldev; |
125 | struct atmel_pwm_bl *pwmbl; | 126 | struct atmel_pwm_bl *pwmbl; |
@@ -165,8 +166,10 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) | |||
165 | goto err_free_gpio; | 166 | goto err_free_gpio; |
166 | } | 167 | } |
167 | 168 | ||
168 | bldev = backlight_device_register("atmel-pwm-bl", | 169 | memset(&props, 0, sizeof(struct backlight_properties)); |
169 | &pdev->dev, pwmbl, &atmel_pwm_bl_ops); | 170 | props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min; |
171 | bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl, | ||
172 | &atmel_pwm_bl_ops, &props); | ||
170 | if (IS_ERR(bldev)) { | 173 | if (IS_ERR(bldev)) { |
171 | retval = PTR_ERR(bldev); | 174 | retval = PTR_ERR(bldev); |
172 | goto err_free_gpio; | 175 | goto err_free_gpio; |
@@ -178,7 +181,6 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) | |||
178 | 181 | ||
179 | /* Power up the backlight by default at middle intesity. */ | 182 | /* Power up the backlight by default at middle intesity. */ |
180 | bldev->props.power = FB_BLANK_UNBLANK; | 183 | bldev->props.power = FB_BLANK_UNBLANK; |
181 | bldev->props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min; | ||
182 | bldev->props.brightness = bldev->props.max_brightness / 2; | 184 | bldev->props.brightness = bldev->props.max_brightness / 2; |
183 | 185 | ||
184 | retval = atmel_pwm_bl_init_pwm(pwmbl); | 186 | retval = atmel_pwm_bl_init_pwm(pwmbl); |
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 18829cf68b1b..68bb838b9f11 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -38,7 +38,7 @@ static int fb_notifier_callback(struct notifier_block *self, | |||
38 | mutex_lock(&bd->ops_lock); | 38 | mutex_lock(&bd->ops_lock); |
39 | if (bd->ops) | 39 | if (bd->ops) |
40 | if (!bd->ops->check_fb || | 40 | if (!bd->ops->check_fb || |
41 | bd->ops->check_fb(evdata->info)) { | 41 | bd->ops->check_fb(bd, evdata->info)) { |
42 | bd->props.fb_blank = *(int *)evdata->data; | 42 | bd->props.fb_blank = *(int *)evdata->data; |
43 | if (bd->props.fb_blank == FB_BLANK_UNBLANK) | 43 | if (bd->props.fb_blank == FB_BLANK_UNBLANK) |
44 | bd->props.state &= ~BL_CORE_FBBLANK; | 44 | bd->props.state &= ~BL_CORE_FBBLANK; |
@@ -269,7 +269,8 @@ EXPORT_SYMBOL(backlight_force_update); | |||
269 | * ERR_PTR() or a pointer to the newly allocated device. | 269 | * ERR_PTR() or a pointer to the newly allocated device. |
270 | */ | 270 | */ |
271 | struct backlight_device *backlight_device_register(const char *name, | 271 | struct backlight_device *backlight_device_register(const char *name, |
272 | struct device *parent, void *devdata, const struct backlight_ops *ops) | 272 | struct device *parent, void *devdata, const struct backlight_ops *ops, |
273 | const struct backlight_properties *props) | ||
273 | { | 274 | { |
274 | struct backlight_device *new_bd; | 275 | struct backlight_device *new_bd; |
275 | int rc; | 276 | int rc; |
@@ -289,6 +290,11 @@ struct backlight_device *backlight_device_register(const char *name, | |||
289 | dev_set_name(&new_bd->dev, name); | 290 | dev_set_name(&new_bd->dev, name); |
290 | dev_set_drvdata(&new_bd->dev, devdata); | 291 | dev_set_drvdata(&new_bd->dev, devdata); |
291 | 292 | ||
293 | /* Set default properties */ | ||
294 | if (props) | ||
295 | memcpy(&new_bd->props, props, | ||
296 | sizeof(struct backlight_properties)); | ||
297 | |||
292 | rc = device_register(&new_bd->dev); | 298 | rc = device_register(&new_bd->dev); |
293 | if (rc) { | 299 | if (rc) { |
294 | kfree(new_bd); | 300 | kfree(new_bd); |
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index b4bcf8043797..73bdd8454c94 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c | |||
@@ -533,6 +533,7 @@ err_free_backlight_on: | |||
533 | 533 | ||
534 | static int __devinit corgi_lcd_probe(struct spi_device *spi) | 534 | static int __devinit corgi_lcd_probe(struct spi_device *spi) |
535 | { | 535 | { |
536 | struct backlight_properties props; | ||
536 | struct corgi_lcd_platform_data *pdata = spi->dev.platform_data; | 537 | struct corgi_lcd_platform_data *pdata = spi->dev.platform_data; |
537 | struct corgi_lcd *lcd; | 538 | struct corgi_lcd *lcd; |
538 | int ret = 0; | 539 | int ret = 0; |
@@ -559,13 +560,14 @@ static int __devinit corgi_lcd_probe(struct spi_device *spi) | |||
559 | lcd->power = FB_BLANK_POWERDOWN; | 560 | lcd->power = FB_BLANK_POWERDOWN; |
560 | lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA; | 561 | lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA; |
561 | 562 | ||
562 | lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, | 563 | memset(&props, 0, sizeof(struct backlight_properties)); |
563 | lcd, &corgi_bl_ops); | 564 | props.max_brightness = pdata->max_intensity; |
565 | lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd, | ||
566 | &corgi_bl_ops, &props); | ||
564 | if (IS_ERR(lcd->bl_dev)) { | 567 | if (IS_ERR(lcd->bl_dev)) { |
565 | ret = PTR_ERR(lcd->bl_dev); | 568 | ret = PTR_ERR(lcd->bl_dev); |
566 | goto err_unregister_lcd; | 569 | goto err_unregister_lcd; |
567 | } | 570 | } |
568 | lcd->bl_dev->props.max_brightness = pdata->max_intensity; | ||
569 | lcd->bl_dev->props.brightness = pdata->default_intensity; | 571 | lcd->bl_dev->props.brightness = pdata->default_intensity; |
570 | lcd->bl_dev->props.power = FB_BLANK_UNBLANK; | 572 | lcd->bl_dev->props.power = FB_BLANK_UNBLANK; |
571 | 573 | ||
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c index da86db4374a0..1cce6031bff2 100644 --- a/drivers/video/backlight/cr_bllcd.c +++ b/drivers/video/backlight/cr_bllcd.c | |||
@@ -170,6 +170,7 @@ static struct lcd_ops cr_lcd_ops = { | |||
170 | 170 | ||
171 | static int cr_backlight_probe(struct platform_device *pdev) | 171 | static int cr_backlight_probe(struct platform_device *pdev) |
172 | { | 172 | { |
173 | struct backlight_properties props; | ||
173 | struct backlight_device *bdp; | 174 | struct backlight_device *bdp; |
174 | struct lcd_device *ldp; | 175 | struct lcd_device *ldp; |
175 | struct cr_panel *crp; | 176 | struct cr_panel *crp; |
@@ -190,8 +191,9 @@ static int cr_backlight_probe(struct platform_device *pdev) | |||
190 | return -ENODEV; | 191 | return -ENODEV; |
191 | } | 192 | } |
192 | 193 | ||
193 | bdp = backlight_device_register("cr-backlight", | 194 | memset(&props, 0, sizeof(struct backlight_properties)); |
194 | &pdev->dev, NULL, &cr_backlight_ops); | 195 | bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL, |
196 | &cr_backlight_ops, &props); | ||
195 | if (IS_ERR(bdp)) { | 197 | if (IS_ERR(bdp)) { |
196 | pci_dev_put(lpc_dev); | 198 | pci_dev_put(lpc_dev); |
197 | return PTR_ERR(bdp); | 199 | return PTR_ERR(bdp); |
@@ -220,9 +222,7 @@ static int cr_backlight_probe(struct platform_device *pdev) | |||
220 | crp->cr_lcd_device = ldp; | 222 | crp->cr_lcd_device = ldp; |
221 | crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK; | 223 | crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK; |
222 | crp->cr_backlight_device->props.brightness = 0; | 224 | crp->cr_backlight_device->props.brightness = 0; |
223 | crp->cr_backlight_device->props.max_brightness = 0; | ||
224 | cr_backlight_set_intensity(crp->cr_backlight_device); | 225 | cr_backlight_set_intensity(crp->cr_backlight_device); |
225 | |||
226 | cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK); | 226 | cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK); |
227 | 227 | ||
228 | platform_set_drvdata(pdev, crp); | 228 | platform_set_drvdata(pdev, crp); |
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c index 74cdc640173d..686e4a789238 100644 --- a/drivers/video/backlight/da903x_bl.c +++ b/drivers/video/backlight/da903x_bl.c | |||
@@ -105,6 +105,7 @@ static int da903x_backlight_probe(struct platform_device *pdev) | |||
105 | struct da9034_backlight_pdata *pdata = pdev->dev.platform_data; | 105 | struct da9034_backlight_pdata *pdata = pdev->dev.platform_data; |
106 | struct da903x_backlight_data *data; | 106 | struct da903x_backlight_data *data; |
107 | struct backlight_device *bl; | 107 | struct backlight_device *bl; |
108 | struct backlight_properties props; | ||
108 | int max_brightness; | 109 | int max_brightness; |
109 | 110 | ||
110 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 111 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
@@ -134,15 +135,15 @@ static int da903x_backlight_probe(struct platform_device *pdev) | |||
134 | da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2, | 135 | da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2, |
135 | DA9034_WLED_ISET(pdata->output_current)); | 136 | DA9034_WLED_ISET(pdata->output_current)); |
136 | 137 | ||
137 | bl = backlight_device_register(pdev->name, data->da903x_dev, | 138 | props.max_brightness = max_brightness; |
138 | data, &da903x_backlight_ops); | 139 | bl = backlight_device_register(pdev->name, data->da903x_dev, data, |
140 | &da903x_backlight_ops, &props); | ||
139 | if (IS_ERR(bl)) { | 141 | if (IS_ERR(bl)) { |
140 | dev_err(&pdev->dev, "failed to register backlight\n"); | 142 | dev_err(&pdev->dev, "failed to register backlight\n"); |
141 | kfree(data); | 143 | kfree(data); |
142 | return PTR_ERR(bl); | 144 | return PTR_ERR(bl); |
143 | } | 145 | } |
144 | 146 | ||
145 | bl->props.max_brightness = max_brightness; | ||
146 | bl->props.brightness = max_brightness; | 147 | bl->props.brightness = max_brightness; |
147 | 148 | ||
148 | platform_set_drvdata(pdev, bl); | 149 | platform_set_drvdata(pdev, bl); |
diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c index e6d348e63596..312ca619735d 100644 --- a/drivers/video/backlight/generic_bl.c +++ b/drivers/video/backlight/generic_bl.c | |||
@@ -78,6 +78,7 @@ static const struct backlight_ops genericbl_ops = { | |||
78 | 78 | ||
79 | static int genericbl_probe(struct platform_device *pdev) | 79 | static int genericbl_probe(struct platform_device *pdev) |
80 | { | 80 | { |
81 | struct backlight_properties props; | ||
81 | struct generic_bl_info *machinfo = pdev->dev.platform_data; | 82 | struct generic_bl_info *machinfo = pdev->dev.platform_data; |
82 | const char *name = "generic-bl"; | 83 | const char *name = "generic-bl"; |
83 | struct backlight_device *bd; | 84 | struct backlight_device *bd; |
@@ -89,14 +90,15 @@ static int genericbl_probe(struct platform_device *pdev) | |||
89 | if (machinfo->name) | 90 | if (machinfo->name) |
90 | name = machinfo->name; | 91 | name = machinfo->name; |
91 | 92 | ||
92 | bd = backlight_device_register (name, | 93 | memset(&props, 0, sizeof(struct backlight_properties)); |
93 | &pdev->dev, NULL, &genericbl_ops); | 94 | props.max_brightness = machinfo->max_intensity; |
95 | bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops, | ||
96 | &props); | ||
94 | if (IS_ERR (bd)) | 97 | if (IS_ERR (bd)) |
95 | return PTR_ERR (bd); | 98 | return PTR_ERR (bd); |
96 | 99 | ||
97 | platform_set_drvdata(pdev, bd); | 100 | platform_set_drvdata(pdev, bd); |
98 | 101 | ||
99 | bd->props.max_brightness = machinfo->max_intensity; | ||
100 | bd->props.power = FB_BLANK_UNBLANK; | 102 | bd->props.power = FB_BLANK_UNBLANK; |
101 | bd->props.brightness = machinfo->default_intensity; | 103 | bd->props.brightness = machinfo->default_intensity; |
102 | backlight_update_status(bd); | 104 | backlight_update_status(bd); |
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index f7cc528d5be7..267d23f8d645 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c | |||
@@ -105,16 +105,18 @@ static const struct backlight_ops hp680bl_ops = { | |||
105 | 105 | ||
106 | static int __devinit hp680bl_probe(struct platform_device *pdev) | 106 | static int __devinit hp680bl_probe(struct platform_device *pdev) |
107 | { | 107 | { |
108 | struct backlight_properties props; | ||
108 | struct backlight_device *bd; | 109 | struct backlight_device *bd; |
109 | 110 | ||
110 | bd = backlight_device_register ("hp680-bl", &pdev->dev, NULL, | 111 | memset(&props, 0, sizeof(struct backlight_properties)); |
111 | &hp680bl_ops); | 112 | props.max_brightness = HP680_MAX_INTENSITY; |
113 | bd = backlight_device_register("hp680-bl", &pdev->dev, NULL, | ||
114 | &hp680bl_ops, &props); | ||
112 | if (IS_ERR(bd)) | 115 | if (IS_ERR(bd)) |
113 | return PTR_ERR(bd); | 116 | return PTR_ERR(bd); |
114 | 117 | ||
115 | platform_set_drvdata(pdev, bd); | 118 | platform_set_drvdata(pdev, bd); |
116 | 119 | ||
117 | bd->props.max_brightness = HP680_MAX_INTENSITY; | ||
118 | bd->props.brightness = HP680_DEFAULT_INTENSITY; | 120 | bd->props.brightness = HP680_DEFAULT_INTENSITY; |
119 | hp680bl_send_intensity(bd); | 121 | hp680bl_send_intensity(bd); |
120 | 122 | ||
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c index db9071fc5665..2f177b3a4885 100644 --- a/drivers/video/backlight/jornada720_bl.c +++ b/drivers/video/backlight/jornada720_bl.c | |||
@@ -101,10 +101,14 @@ static const struct backlight_ops jornada_bl_ops = { | |||
101 | 101 | ||
102 | static int jornada_bl_probe(struct platform_device *pdev) | 102 | static int jornada_bl_probe(struct platform_device *pdev) |
103 | { | 103 | { |
104 | struct backlight_properties props; | ||
104 | int ret; | 105 | int ret; |
105 | struct backlight_device *bd; | 106 | struct backlight_device *bd; |
106 | 107 | ||
107 | bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_bl_ops); | 108 | memset(&props, 0, sizeof(struct backlight_properties)); |
109 | props.max_brightness = BL_MAX_BRIGHT; | ||
110 | bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, | ||
111 | &jornada_bl_ops, &props); | ||
108 | 112 | ||
109 | if (IS_ERR(bd)) { | 113 | if (IS_ERR(bd)) { |
110 | ret = PTR_ERR(bd); | 114 | ret = PTR_ERR(bd); |
@@ -117,7 +121,6 @@ static int jornada_bl_probe(struct platform_device *pdev) | |||
117 | /* note. make sure max brightness is set otherwise | 121 | /* note. make sure max brightness is set otherwise |
118 | you will get seemingly non-related errors when | 122 | you will get seemingly non-related errors when |
119 | trying to change brightness */ | 123 | trying to change brightness */ |
120 | bd->props.max_brightness = BL_MAX_BRIGHT; | ||
121 | jornada_bl_update_status(bd); | 124 | jornada_bl_update_status(bd); |
122 | 125 | ||
123 | platform_set_drvdata(pdev, bd); | 126 | platform_set_drvdata(pdev, bd); |
diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c index 939e7b830cf3..f439a8632287 100644 --- a/drivers/video/backlight/kb3886_bl.c +++ b/drivers/video/backlight/kb3886_bl.c | |||
@@ -141,20 +141,24 @@ static const struct backlight_ops kb3886bl_ops = { | |||
141 | 141 | ||
142 | static int kb3886bl_probe(struct platform_device *pdev) | 142 | static int kb3886bl_probe(struct platform_device *pdev) |
143 | { | 143 | { |
144 | struct backlight_properties props; | ||
144 | struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data; | 145 | struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data; |
145 | 146 | ||
146 | bl_machinfo = machinfo; | 147 | bl_machinfo = machinfo; |
147 | if (!machinfo->limit_mask) | 148 | if (!machinfo->limit_mask) |
148 | machinfo->limit_mask = -1; | 149 | machinfo->limit_mask = -1; |
149 | 150 | ||
151 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
152 | props.max_brightness = machinfo->max_intensity; | ||
150 | kb3886_backlight_device = backlight_device_register("kb3886-bl", | 153 | kb3886_backlight_device = backlight_device_register("kb3886-bl", |
151 | &pdev->dev, NULL, &kb3886bl_ops); | 154 | &pdev->dev, NULL, |
155 | &kb3886bl_ops, | ||
156 | &props); | ||
152 | if (IS_ERR(kb3886_backlight_device)) | 157 | if (IS_ERR(kb3886_backlight_device)) |
153 | return PTR_ERR(kb3886_backlight_device); | 158 | return PTR_ERR(kb3886_backlight_device); |
154 | 159 | ||
155 | platform_set_drvdata(pdev, kb3886_backlight_device); | 160 | platform_set_drvdata(pdev, kb3886_backlight_device); |
156 | 161 | ||
157 | kb3886_backlight_device->props.max_brightness = machinfo->max_intensity; | ||
158 | kb3886_backlight_device->props.power = FB_BLANK_UNBLANK; | 162 | kb3886_backlight_device->props.power = FB_BLANK_UNBLANK; |
159 | kb3886_backlight_device->props.brightness = machinfo->default_intensity; | 163 | kb3886_backlight_device->props.brightness = machinfo->default_intensity; |
160 | backlight_update_status(kb3886_backlight_device); | 164 | backlight_update_status(kb3886_backlight_device); |
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c new file mode 100644 index 000000000000..74abd6994b09 --- /dev/null +++ b/drivers/video/backlight/l4f00242t03.c | |||
@@ -0,0 +1,257 @@ | |||
1 | /* | ||
2 | * l4f00242t03.c -- support for Epson L4F00242T03 LCD | ||
3 | * | ||
4 | * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved. | ||
5 | * | ||
6 | * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> | ||
7 | * Inspired by Marek Vasut work in l4f00242t03.c | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/device.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/lcd.h> | ||
19 | #include <linux/regulator/consumer.h> | ||
20 | |||
21 | #include <linux/spi/spi.h> | ||
22 | #include <linux/spi/l4f00242t03.h> | ||
23 | |||
24 | struct l4f00242t03_priv { | ||
25 | struct spi_device *spi; | ||
26 | struct lcd_device *ld; | ||
27 | int lcd_on:1; | ||
28 | struct regulator *io_reg; | ||
29 | struct regulator *core_reg; | ||
30 | }; | ||
31 | |||
32 | |||
33 | static void l4f00242t03_reset(unsigned int gpio) | ||
34 | { | ||
35 | pr_debug("l4f00242t03_reset.\n"); | ||
36 | gpio_set_value(gpio, 1); | ||
37 | mdelay(100); | ||
38 | gpio_set_value(gpio, 0); | ||
39 | mdelay(10); /* tRES >= 100us */ | ||
40 | gpio_set_value(gpio, 1); | ||
41 | mdelay(20); | ||
42 | } | ||
43 | |||
44 | #define param(x) ((x) | 0x100) | ||
45 | |||
46 | static void l4f00242t03_lcd_init(struct spi_device *spi) | ||
47 | { | ||
48 | struct l4f00242t03_pdata *pdata = spi->dev.platform_data; | ||
49 | struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); | ||
50 | const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) }; | ||
51 | |||
52 | dev_dbg(&spi->dev, "initializing LCD\n"); | ||
53 | |||
54 | if (priv->io_reg) { | ||
55 | regulator_set_voltage(priv->io_reg, 1800000, 1800000); | ||
56 | regulator_enable(priv->io_reg); | ||
57 | } | ||
58 | |||
59 | if (priv->core_reg) { | ||
60 | regulator_set_voltage(priv->core_reg, 2800000, 2800000); | ||
61 | regulator_enable(priv->core_reg); | ||
62 | } | ||
63 | |||
64 | gpio_set_value(pdata->data_enable_gpio, 1); | ||
65 | msleep(60); | ||
66 | spi_write(spi, (const u8 *)cmd, ARRAY_SIZE(cmd) * sizeof(u16)); | ||
67 | } | ||
68 | |||
69 | static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power) | ||
70 | { | ||
71 | struct l4f00242t03_priv *priv = lcd_get_data(ld); | ||
72 | struct spi_device *spi = priv->spi; | ||
73 | |||
74 | const u16 slpout = 0x11; | ||
75 | const u16 dison = 0x29; | ||
76 | |||
77 | const u16 slpin = 0x10; | ||
78 | const u16 disoff = 0x28; | ||
79 | |||
80 | if (power) { | ||
81 | if (priv->lcd_on) | ||
82 | return 0; | ||
83 | |||
84 | dev_dbg(&spi->dev, "turning on LCD\n"); | ||
85 | |||
86 | spi_write(spi, (const u8 *)&slpout, sizeof(u16)); | ||
87 | msleep(60); | ||
88 | spi_write(spi, (const u8 *)&dison, sizeof(u16)); | ||
89 | |||
90 | priv->lcd_on = 1; | ||
91 | } else { | ||
92 | if (!priv->lcd_on) | ||
93 | return 0; | ||
94 | |||
95 | dev_dbg(&spi->dev, "turning off LCD\n"); | ||
96 | |||
97 | spi_write(spi, (const u8 *)&disoff, sizeof(u16)); | ||
98 | msleep(60); | ||
99 | spi_write(spi, (const u8 *)&slpin, sizeof(u16)); | ||
100 | |||
101 | priv->lcd_on = 0; | ||
102 | } | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static struct lcd_ops l4f_ops = { | ||
108 | .set_power = l4f00242t03_lcd_power_set, | ||
109 | .get_power = NULL, | ||
110 | }; | ||
111 | |||
112 | static int __devinit l4f00242t03_probe(struct spi_device *spi) | ||
113 | { | ||
114 | struct l4f00242t03_priv *priv; | ||
115 | struct l4f00242t03_pdata *pdata = spi->dev.platform_data; | ||
116 | int ret; | ||
117 | |||
118 | if (pdata == NULL) { | ||
119 | dev_err(&spi->dev, "Uninitialized platform data.\n"); | ||
120 | return -EINVAL; | ||
121 | } | ||
122 | |||
123 | priv = kzalloc(sizeof(struct l4f00242t03_priv), GFP_KERNEL); | ||
124 | |||
125 | if (priv == NULL) { | ||
126 | dev_err(&spi->dev, "No memory for this device.\n"); | ||
127 | ret = -ENOMEM; | ||
128 | goto err; | ||
129 | } | ||
130 | |||
131 | dev_set_drvdata(&spi->dev, priv); | ||
132 | spi->bits_per_word = 9; | ||
133 | spi_setup(spi); | ||
134 | |||
135 | priv->spi = spi; | ||
136 | |||
137 | ret = gpio_request(pdata->reset_gpio, "lcd l4f00242t03 reset"); | ||
138 | if (ret) { | ||
139 | dev_err(&spi->dev, | ||
140 | "Unable to get the lcd l4f00242t03 reset gpio.\n"); | ||
141 | return ret; | ||
142 | } | ||
143 | |||
144 | ret = gpio_direction_output(pdata->reset_gpio, 1); | ||
145 | if (ret) | ||
146 | goto err2; | ||
147 | |||
148 | ret = gpio_request(pdata->data_enable_gpio, | ||
149 | "lcd l4f00242t03 data enable"); | ||
150 | if (ret) { | ||
151 | dev_err(&spi->dev, | ||
152 | "Unable to get the lcd l4f00242t03 data en gpio.\n"); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | ret = gpio_direction_output(pdata->data_enable_gpio, 0); | ||
157 | if (ret) | ||
158 | goto err3; | ||
159 | |||
160 | if (pdata->io_supply) { | ||
161 | priv->io_reg = regulator_get(NULL, pdata->io_supply); | ||
162 | |||
163 | if (IS_ERR(priv->io_reg)) { | ||
164 | pr_err("%s: Unable to get the IO regulator\n", | ||
165 | __func__); | ||
166 | goto err3; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | if (pdata->core_supply) { | ||
171 | priv->core_reg = regulator_get(NULL, pdata->core_supply); | ||
172 | |||
173 | if (IS_ERR(priv->core_reg)) { | ||
174 | pr_err("%s: Unable to get the core regulator\n", | ||
175 | __func__); | ||
176 | goto err4; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | priv->ld = lcd_device_register("l4f00242t03", | ||
181 | &spi->dev, priv, &l4f_ops); | ||
182 | if (IS_ERR(priv->ld)) { | ||
183 | ret = PTR_ERR(priv->ld); | ||
184 | goto err5; | ||
185 | } | ||
186 | |||
187 | /* Init the LCD */ | ||
188 | l4f00242t03_reset(pdata->reset_gpio); | ||
189 | l4f00242t03_lcd_init(spi); | ||
190 | l4f00242t03_lcd_power_set(priv->ld, 1); | ||
191 | |||
192 | dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n"); | ||
193 | |||
194 | return 0; | ||
195 | |||
196 | err5: | ||
197 | if (priv->core_reg) | ||
198 | regulator_put(priv->core_reg); | ||
199 | err4: | ||
200 | if (priv->io_reg) | ||
201 | regulator_put(priv->io_reg); | ||
202 | err3: | ||
203 | gpio_free(pdata->data_enable_gpio); | ||
204 | err2: | ||
205 | gpio_free(pdata->reset_gpio); | ||
206 | err: | ||
207 | kfree(priv); | ||
208 | |||
209 | return ret; | ||
210 | } | ||
211 | |||
212 | static int __devexit l4f00242t03_remove(struct spi_device *spi) | ||
213 | { | ||
214 | struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); | ||
215 | struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data; | ||
216 | |||
217 | l4f00242t03_lcd_power_set(priv->ld, 0); | ||
218 | lcd_device_unregister(priv->ld); | ||
219 | |||
220 | gpio_free(pdata->data_enable_gpio); | ||
221 | gpio_free(pdata->reset_gpio); | ||
222 | |||
223 | if (priv->io_reg) | ||
224 | regulator_put(priv->core_reg); | ||
225 | if (priv->core_reg) | ||
226 | regulator_put(priv->io_reg); | ||
227 | |||
228 | kfree(priv); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static struct spi_driver l4f00242t03_driver = { | ||
234 | .driver = { | ||
235 | .name = "l4f00242t03", | ||
236 | .owner = THIS_MODULE, | ||
237 | }, | ||
238 | .probe = l4f00242t03_probe, | ||
239 | .remove = __devexit_p(l4f00242t03_remove), | ||
240 | }; | ||
241 | |||
242 | static __init int l4f00242t03_init(void) | ||
243 | { | ||
244 | return spi_register_driver(&l4f00242t03_driver); | ||
245 | } | ||
246 | |||
247 | static __exit void l4f00242t03_exit(void) | ||
248 | { | ||
249 | spi_unregister_driver(&l4f00242t03_driver); | ||
250 | } | ||
251 | |||
252 | module_init(l4f00242t03_init); | ||
253 | module_exit(l4f00242t03_exit); | ||
254 | |||
255 | MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>"); | ||
256 | MODULE_DESCRIPTION("EPSON L4F00242T03 LCD"); | ||
257 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c index 00a9591b0003..7571bc26071e 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c | |||
@@ -167,6 +167,7 @@ static int locomolcd_resume(struct locomo_dev *dev) | |||
167 | 167 | ||
168 | static int locomolcd_probe(struct locomo_dev *ldev) | 168 | static int locomolcd_probe(struct locomo_dev *ldev) |
169 | { | 169 | { |
170 | struct backlight_properties props; | ||
170 | unsigned long flags; | 171 | unsigned long flags; |
171 | 172 | ||
172 | local_irq_save(flags); | 173 | local_irq_save(flags); |
@@ -182,13 +183,16 @@ static int locomolcd_probe(struct locomo_dev *ldev) | |||
182 | 183 | ||
183 | local_irq_restore(flags); | 184 | local_irq_restore(flags); |
184 | 185 | ||
185 | locomolcd_bl_device = backlight_device_register("locomo-bl", &ldev->dev, NULL, &locomobl_data); | 186 | memset(&props, 0, sizeof(struct backlight_properties)); |
187 | props.max_brightness = 4; | ||
188 | locomolcd_bl_device = backlight_device_register("locomo-bl", | ||
189 | &ldev->dev, NULL, | ||
190 | &locomobl_data, &props); | ||
186 | 191 | ||
187 | if (IS_ERR (locomolcd_bl_device)) | 192 | if (IS_ERR (locomolcd_bl_device)) |
188 | return PTR_ERR (locomolcd_bl_device); | 193 | return PTR_ERR (locomolcd_bl_device); |
189 | 194 | ||
190 | /* Set up frontlight so that screen is readable */ | 195 | /* Set up frontlight so that screen is readable */ |
191 | locomolcd_bl_device->props.max_brightness = 4, | ||
192 | locomolcd_bl_device->props.brightness = 2; | 196 | locomolcd_bl_device->props.brightness = 2; |
193 | locomolcd_set_intensity(locomolcd_bl_device); | 197 | locomolcd_set_intensity(locomolcd_bl_device); |
194 | 198 | ||
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c index c267069a52a3..c91adaf492cf 100644 --- a/drivers/video/backlight/max8925_bl.c +++ b/drivers/video/backlight/max8925_bl.c | |||
@@ -104,6 +104,7 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev) | |||
104 | struct max8925_backlight_pdata *pdata = NULL; | 104 | struct max8925_backlight_pdata *pdata = NULL; |
105 | struct max8925_backlight_data *data; | 105 | struct max8925_backlight_data *data; |
106 | struct backlight_device *bl; | 106 | struct backlight_device *bl; |
107 | struct backlight_properties props; | ||
107 | struct resource *res; | 108 | struct resource *res; |
108 | char name[MAX8925_NAME_SIZE]; | 109 | char name[MAX8925_NAME_SIZE]; |
109 | unsigned char value; | 110 | unsigned char value; |
@@ -133,14 +134,15 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev) | |||
133 | data->chip = chip; | 134 | data->chip = chip; |
134 | data->current_brightness = 0; | 135 | data->current_brightness = 0; |
135 | 136 | ||
137 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
138 | props.max_brightness = MAX_BRIGHTNESS; | ||
136 | bl = backlight_device_register(name, &pdev->dev, data, | 139 | bl = backlight_device_register(name, &pdev->dev, data, |
137 | &max8925_backlight_ops); | 140 | &max8925_backlight_ops, &props); |
138 | if (IS_ERR(bl)) { | 141 | if (IS_ERR(bl)) { |
139 | dev_err(&pdev->dev, "failed to register backlight\n"); | 142 | dev_err(&pdev->dev, "failed to register backlight\n"); |
140 | kfree(data); | 143 | kfree(data); |
141 | return PTR_ERR(bl); | 144 | return PTR_ERR(bl); |
142 | } | 145 | } |
143 | bl->props.max_brightness = MAX_BRIGHTNESS; | ||
144 | bl->props.brightness = MAX_BRIGHTNESS; | 146 | bl->props.brightness = MAX_BRIGHTNESS; |
145 | 147 | ||
146 | platform_set_drvdata(pdev, bl); | 148 | platform_set_drvdata(pdev, bl); |
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 2e78b0784bdc..1b5d3fe6bbbc 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c | |||
@@ -139,6 +139,51 @@ static int mbp_dmi_match(const struct dmi_system_id *id) | |||
139 | static const struct dmi_system_id __initdata mbp_device_table[] = { | 139 | static const struct dmi_system_id __initdata mbp_device_table[] = { |
140 | { | 140 | { |
141 | .callback = mbp_dmi_match, | 141 | .callback = mbp_dmi_match, |
142 | .ident = "MacBook 1,1", | ||
143 | .matches = { | ||
144 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
145 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), | ||
146 | }, | ||
147 | .driver_data = (void *)&intel_chipset_data, | ||
148 | }, | ||
149 | { | ||
150 | .callback = mbp_dmi_match, | ||
151 | .ident = "MacBook 2,1", | ||
152 | .matches = { | ||
153 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
154 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"), | ||
155 | }, | ||
156 | .driver_data = (void *)&intel_chipset_data, | ||
157 | }, | ||
158 | { | ||
159 | .callback = mbp_dmi_match, | ||
160 | .ident = "MacBook 3,1", | ||
161 | .matches = { | ||
162 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
163 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook3,1"), | ||
164 | }, | ||
165 | .driver_data = (void *)&intel_chipset_data, | ||
166 | }, | ||
167 | { | ||
168 | .callback = mbp_dmi_match, | ||
169 | .ident = "MacBook 4,1", | ||
170 | .matches = { | ||
171 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
172 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,1"), | ||
173 | }, | ||
174 | .driver_data = (void *)&intel_chipset_data, | ||
175 | }, | ||
176 | { | ||
177 | .callback = mbp_dmi_match, | ||
178 | .ident = "MacBook 4,2", | ||
179 | .matches = { | ||
180 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
181 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,2"), | ||
182 | }, | ||
183 | .driver_data = (void *)&intel_chipset_data, | ||
184 | }, | ||
185 | { | ||
186 | .callback = mbp_dmi_match, | ||
142 | .ident = "MacBookPro 3,1", | 187 | .ident = "MacBookPro 3,1", |
143 | .matches = { | 188 | .matches = { |
144 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | 189 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), |
@@ -250,6 +295,7 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { | |||
250 | 295 | ||
251 | static int __init mbp_init(void) | 296 | static int __init mbp_init(void) |
252 | { | 297 | { |
298 | struct backlight_properties props; | ||
253 | if (!dmi_check_system(mbp_device_table)) | 299 | if (!dmi_check_system(mbp_device_table)) |
254 | return -ENODEV; | 300 | return -ENODEV; |
255 | 301 | ||
@@ -257,14 +303,17 @@ static int __init mbp_init(void) | |||
257 | "Macbook Pro backlight")) | 303 | "Macbook Pro backlight")) |
258 | return -ENXIO; | 304 | return -ENXIO; |
259 | 305 | ||
260 | mbp_backlight_device = backlight_device_register("mbp_backlight", | 306 | memset(&props, 0, sizeof(struct backlight_properties)); |
261 | NULL, NULL, &driver_data->backlight_ops); | 307 | props.max_brightness = 15; |
308 | mbp_backlight_device = backlight_device_register("mbp_backlight", NULL, | ||
309 | NULL, | ||
310 | &driver_data->backlight_ops, | ||
311 | &props); | ||
262 | if (IS_ERR(mbp_backlight_device)) { | 312 | if (IS_ERR(mbp_backlight_device)) { |
263 | release_region(driver_data->iostart, driver_data->iolen); | 313 | release_region(driver_data->iostart, driver_data->iolen); |
264 | return PTR_ERR(mbp_backlight_device); | 314 | return PTR_ERR(mbp_backlight_device); |
265 | } | 315 | } |
266 | 316 | ||
267 | mbp_backlight_device->props.max_brightness = 15; | ||
268 | mbp_backlight_device->props.brightness = | 317 | mbp_backlight_device->props.brightness = |
269 | driver_data->backlight_ops.get_brightness(mbp_backlight_device); | 318 | driver_data->backlight_ops.get_brightness(mbp_backlight_device); |
270 | backlight_update_status(mbp_backlight_device); | 319 | backlight_update_status(mbp_backlight_device); |
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c index a3a7f8938175..333d28e6b062 100644 --- a/drivers/video/backlight/omap1_bl.c +++ b/drivers/video/backlight/omap1_bl.c | |||
@@ -132,6 +132,7 @@ static const struct backlight_ops omapbl_ops = { | |||
132 | 132 | ||
133 | static int omapbl_probe(struct platform_device *pdev) | 133 | static int omapbl_probe(struct platform_device *pdev) |
134 | { | 134 | { |
135 | struct backlight_properties props; | ||
135 | struct backlight_device *dev; | 136 | struct backlight_device *dev; |
136 | struct omap_backlight *bl; | 137 | struct omap_backlight *bl; |
137 | struct omap_backlight_config *pdata = pdev->dev.platform_data; | 138 | struct omap_backlight_config *pdata = pdev->dev.platform_data; |
@@ -143,7 +144,10 @@ static int omapbl_probe(struct platform_device *pdev) | |||
143 | if (unlikely(!bl)) | 144 | if (unlikely(!bl)) |
144 | return -ENOMEM; | 145 | return -ENOMEM; |
145 | 146 | ||
146 | dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops); | 147 | memset(&props, 0, sizeof(struct backlight_properties)); |
148 | props.max_brightness = OMAPBL_MAX_INTENSITY; | ||
149 | dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops, | ||
150 | &props); | ||
147 | if (IS_ERR(dev)) { | 151 | if (IS_ERR(dev)) { |
148 | kfree(bl); | 152 | kfree(bl); |
149 | return PTR_ERR(dev); | 153 | return PTR_ERR(dev); |
@@ -160,7 +164,6 @@ static int omapbl_probe(struct platform_device *pdev) | |||
160 | omap_cfg_reg(PWL); /* Conflicts with UART3 */ | 164 | omap_cfg_reg(PWL); /* Conflicts with UART3 */ |
161 | 165 | ||
162 | dev->props.fb_blank = FB_BLANK_UNBLANK; | 166 | dev->props.fb_blank = FB_BLANK_UNBLANK; |
163 | dev->props.max_brightness = OMAPBL_MAX_INTENSITY; | ||
164 | dev->props.brightness = pdata->default_intensity; | 167 | dev->props.brightness = pdata->default_intensity; |
165 | omapbl_update_status(dev); | 168 | omapbl_update_status(dev); |
166 | 169 | ||
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c index 075786e05034..809278c90738 100644 --- a/drivers/video/backlight/progear_bl.c +++ b/drivers/video/backlight/progear_bl.c | |||
@@ -61,8 +61,10 @@ static const struct backlight_ops progearbl_ops = { | |||
61 | 61 | ||
62 | static int progearbl_probe(struct platform_device *pdev) | 62 | static int progearbl_probe(struct platform_device *pdev) |
63 | { | 63 | { |
64 | struct backlight_properties props; | ||
64 | u8 temp; | 65 | u8 temp; |
65 | struct backlight_device *progear_backlight_device; | 66 | struct backlight_device *progear_backlight_device; |
67 | int ret; | ||
66 | 68 | ||
67 | pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL); | 69 | pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL); |
68 | if (!pmu_dev) { | 70 | if (!pmu_dev) { |
@@ -73,28 +75,37 @@ static int progearbl_probe(struct platform_device *pdev) | |||
73 | sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); | 75 | sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); |
74 | if (!sb_dev) { | 76 | if (!sb_dev) { |
75 | printk("ALI 1533 SB not found.\n"); | 77 | printk("ALI 1533 SB not found.\n"); |
76 | pci_dev_put(pmu_dev); | 78 | ret = -ENODEV; |
77 | return -ENODEV; | 79 | goto put_pmu; |
78 | } | 80 | } |
79 | 81 | ||
80 | /* Set SB_MPS1 to enable brightness control. */ | 82 | /* Set SB_MPS1 to enable brightness control. */ |
81 | pci_read_config_byte(sb_dev, SB_MPS1, &temp); | 83 | pci_read_config_byte(sb_dev, SB_MPS1, &temp); |
82 | pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20); | 84 | pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20); |
83 | 85 | ||
86 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
87 | props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; | ||
84 | progear_backlight_device = backlight_device_register("progear-bl", | 88 | progear_backlight_device = backlight_device_register("progear-bl", |
85 | &pdev->dev, NULL, | 89 | &pdev->dev, NULL, |
86 | &progearbl_ops); | 90 | &progearbl_ops, |
87 | if (IS_ERR(progear_backlight_device)) | 91 | &props); |
88 | return PTR_ERR(progear_backlight_device); | 92 | if (IS_ERR(progear_backlight_device)) { |
93 | ret = PTR_ERR(progear_backlight_device); | ||
94 | goto put_sb; | ||
95 | } | ||
89 | 96 | ||
90 | platform_set_drvdata(pdev, progear_backlight_device); | 97 | platform_set_drvdata(pdev, progear_backlight_device); |
91 | 98 | ||
92 | progear_backlight_device->props.power = FB_BLANK_UNBLANK; | 99 | progear_backlight_device->props.power = FB_BLANK_UNBLANK; |
93 | progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; | 100 | progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; |
94 | progear_backlight_device->props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; | ||
95 | progearbl_set_intensity(progear_backlight_device); | 101 | progearbl_set_intensity(progear_backlight_device); |
96 | 102 | ||
97 | return 0; | 103 | return 0; |
104 | put_sb: | ||
105 | pci_dev_put(sb_dev); | ||
106 | put_pmu: | ||
107 | pci_dev_put(pmu_dev); | ||
108 | return ret; | ||
98 | } | 109 | } |
99 | 110 | ||
100 | static int progearbl_remove(struct platform_device *pdev) | 111 | static int progearbl_remove(struct platform_device *pdev) |
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 9d2ec2a1cce8..b89eebc3f77d 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c | |||
@@ -65,6 +65,7 @@ static const struct backlight_ops pwm_backlight_ops = { | |||
65 | 65 | ||
66 | static int pwm_backlight_probe(struct platform_device *pdev) | 66 | static int pwm_backlight_probe(struct platform_device *pdev) |
67 | { | 67 | { |
68 | struct backlight_properties props; | ||
68 | struct platform_pwm_backlight_data *data = pdev->dev.platform_data; | 69 | struct platform_pwm_backlight_data *data = pdev->dev.platform_data; |
69 | struct backlight_device *bl; | 70 | struct backlight_device *bl; |
70 | struct pwm_bl_data *pb; | 71 | struct pwm_bl_data *pb; |
@@ -100,15 +101,16 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
100 | } else | 101 | } else |
101 | dev_dbg(&pdev->dev, "got pwm for backlight\n"); | 102 | dev_dbg(&pdev->dev, "got pwm for backlight\n"); |
102 | 103 | ||
103 | bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, | 104 | memset(&props, 0, sizeof(struct backlight_properties)); |
104 | pb, &pwm_backlight_ops); | 105 | props.max_brightness = data->max_brightness; |
106 | bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb, | ||
107 | &pwm_backlight_ops, &props); | ||
105 | if (IS_ERR(bl)) { | 108 | if (IS_ERR(bl)) { |
106 | dev_err(&pdev->dev, "failed to register backlight\n"); | 109 | dev_err(&pdev->dev, "failed to register backlight\n"); |
107 | ret = PTR_ERR(bl); | 110 | ret = PTR_ERR(bl); |
108 | goto err_bl; | 111 | goto err_bl; |
109 | } | 112 | } |
110 | 113 | ||
111 | bl->props.max_brightness = data->max_brightness; | ||
112 | bl->props.brightness = data->dft_brightness; | 114 | bl->props.brightness = data->dft_brightness; |
113 | backlight_update_status(bl); | 115 | backlight_update_status(bl); |
114 | 116 | ||
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c index e14ce4d469f5..f57bbf170049 100644 --- a/drivers/video/backlight/tosa_bl.c +++ b/drivers/video/backlight/tosa_bl.c | |||
@@ -80,6 +80,7 @@ static const struct backlight_ops bl_ops = { | |||
80 | static int __devinit tosa_bl_probe(struct i2c_client *client, | 80 | static int __devinit tosa_bl_probe(struct i2c_client *client, |
81 | const struct i2c_device_id *id) | 81 | const struct i2c_device_id *id) |
82 | { | 82 | { |
83 | struct backlight_properties props; | ||
83 | struct tosa_bl_data *data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL); | 84 | struct tosa_bl_data *data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL); |
84 | int ret = 0; | 85 | int ret = 0; |
85 | if (!data) | 86 | if (!data) |
@@ -99,15 +100,16 @@ static int __devinit tosa_bl_probe(struct i2c_client *client, | |||
99 | i2c_set_clientdata(client, data); | 100 | i2c_set_clientdata(client, data); |
100 | data->i2c = client; | 101 | data->i2c = client; |
101 | 102 | ||
102 | data->bl = backlight_device_register("tosa-bl", &client->dev, | 103 | memset(&props, 0, sizeof(struct backlight_properties)); |
103 | data, &bl_ops); | 104 | props.max_brightness = 512 - 1; |
105 | data->bl = backlight_device_register("tosa-bl", &client->dev, data, | ||
106 | &bl_ops, &props); | ||
104 | if (IS_ERR(data->bl)) { | 107 | if (IS_ERR(data->bl)) { |
105 | ret = PTR_ERR(data->bl); | 108 | ret = PTR_ERR(data->bl); |
106 | goto err_reg; | 109 | goto err_reg; |
107 | } | 110 | } |
108 | 111 | ||
109 | data->bl->props.brightness = 69; | 112 | data->bl->props.brightness = 69; |
110 | data->bl->props.max_brightness = 512 - 1; | ||
111 | data->bl->props.power = FB_BLANK_UNBLANK; | 113 | data->bl->props.power = FB_BLANK_UNBLANK; |
112 | 114 | ||
113 | backlight_update_status(data->bl); | 115 | backlight_update_status(data->bl); |
diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c index e32add37a203..a4312709fb1b 100644 --- a/drivers/video/backlight/wm831x_bl.c +++ b/drivers/video/backlight/wm831x_bl.c | |||
@@ -125,6 +125,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev) | |||
125 | struct wm831x_backlight_pdata *pdata; | 125 | struct wm831x_backlight_pdata *pdata; |
126 | struct wm831x_backlight_data *data; | 126 | struct wm831x_backlight_data *data; |
127 | struct backlight_device *bl; | 127 | struct backlight_device *bl; |
128 | struct backlight_properties props; | ||
128 | int ret, i, max_isel, isink_reg, dcdc_cfg; | 129 | int ret, i, max_isel, isink_reg, dcdc_cfg; |
129 | 130 | ||
130 | /* We need platform data */ | 131 | /* We need platform data */ |
@@ -191,15 +192,15 @@ static int wm831x_backlight_probe(struct platform_device *pdev) | |||
191 | data->current_brightness = 0; | 192 | data->current_brightness = 0; |
192 | data->isink_reg = isink_reg; | 193 | data->isink_reg = isink_reg; |
193 | 194 | ||
194 | bl = backlight_device_register("wm831x", &pdev->dev, | 195 | props.max_brightness = max_isel; |
195 | data, &wm831x_backlight_ops); | 196 | bl = backlight_device_register("wm831x", &pdev->dev, data, |
197 | &wm831x_backlight_ops, &props); | ||
196 | if (IS_ERR(bl)) { | 198 | if (IS_ERR(bl)) { |
197 | dev_err(&pdev->dev, "failed to register backlight\n"); | 199 | dev_err(&pdev->dev, "failed to register backlight\n"); |
198 | kfree(data); | 200 | kfree(data); |
199 | return PTR_ERR(bl); | 201 | return PTR_ERR(bl); |
200 | } | 202 | } |
201 | 203 | ||
202 | bl->props.max_brightness = max_isel; | ||
203 | bl->props.brightness = max_isel; | 204 | bl->props.brightness = max_isel; |
204 | 205 | ||
205 | platform_set_drvdata(pdev, bl); | 206 | platform_set_drvdata(pdev, bl); |
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 814312a7452f..23b2a8c0dbfc 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c | |||
@@ -433,7 +433,7 @@ static int bl_get_brightness(struct backlight_device *bd) | |||
433 | return 0; | 433 | return 0; |
434 | } | 434 | } |
435 | 435 | ||
436 | static struct backlight_ops bfin_lq043fb_bl_ops = { | 436 | static const struct backlight_ops bfin_lq043fb_bl_ops = { |
437 | .get_brightness = bl_get_brightness, | 437 | .get_brightness = bl_get_brightness, |
438 | }; | 438 | }; |
439 | 439 | ||
@@ -501,6 +501,7 @@ static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id) | |||
501 | 501 | ||
502 | static int __devinit bfin_bf54x_probe(struct platform_device *pdev) | 502 | static int __devinit bfin_bf54x_probe(struct platform_device *pdev) |
503 | { | 503 | { |
504 | struct backlight_properties props; | ||
504 | struct bfin_bf54xfb_info *info; | 505 | struct bfin_bf54xfb_info *info; |
505 | struct fb_info *fbinfo; | 506 | struct fb_info *fbinfo; |
506 | int ret; | 507 | int ret; |
@@ -645,10 +646,16 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev) | |||
645 | goto out8; | 646 | goto out8; |
646 | } | 647 | } |
647 | #ifndef NO_BL_SUPPORT | 648 | #ifndef NO_BL_SUPPORT |
648 | bl_dev = | 649 | memset(&props, 0, sizeof(struct backlight_properties)); |
649 | backlight_device_register("bf54x-bl", NULL, NULL, | 650 | props.max_brightness = 255; |
650 | &bfin_lq043fb_bl_ops); | 651 | bl_dev = backlight_device_register("bf54x-bl", NULL, NULL, |
651 | bl_dev->props.max_brightness = 255; | 652 | &bfin_lq043fb_bl_ops, &props); |
653 | if (IS_ERR(bl_dev)) { | ||
654 | printk(KERN_ERR DRIVER_NAME | ||
655 | ": unable to register backlight.\n"); | ||
656 | ret = -EINVAL; | ||
657 | goto out9; | ||
658 | } | ||
652 | 659 | ||
653 | lcd_dev = lcd_device_register(DRIVER_NAME, &pdev->dev, NULL, &bfin_lcd_ops); | 660 | lcd_dev = lcd_device_register(DRIVER_NAME, &pdev->dev, NULL, &bfin_lcd_ops); |
654 | lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); | 661 | lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); |
@@ -656,6 +663,8 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev) | |||
656 | 663 | ||
657 | return 0; | 664 | return 0; |
658 | 665 | ||
666 | out9: | ||
667 | unregister_framebuffer(fbinfo); | ||
659 | out8: | 668 | out8: |
660 | free_irq(info->irq, info); | 669 | free_irq(info->irq, info); |
661 | out7: | 670 | out7: |
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c index 5653d083a983..31a2dec927bb 100644 --- a/drivers/video/bfin-t350mcqb-fb.c +++ b/drivers/video/bfin-t350mcqb-fb.c | |||
@@ -352,7 +352,7 @@ static int bl_get_brightness(struct backlight_device *bd) | |||
352 | return 0; | 352 | return 0; |
353 | } | 353 | } |
354 | 354 | ||
355 | static struct backlight_ops bfin_lq043fb_bl_ops = { | 355 | static const struct backlight_ops bfin_lq043fb_bl_ops = { |
356 | .get_brightness = bl_get_brightness, | 356 | .get_brightness = bl_get_brightness, |
357 | }; | 357 | }; |
358 | 358 | ||
@@ -419,6 +419,7 @@ static irqreturn_t bfin_t350mcqb_irq_error(int irq, void *dev_id) | |||
419 | 419 | ||
420 | static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) | 420 | static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) |
421 | { | 421 | { |
422 | struct backlight_properties props; | ||
422 | struct bfin_t350mcqbfb_info *info; | 423 | struct bfin_t350mcqbfb_info *info; |
423 | struct fb_info *fbinfo; | 424 | struct fb_info *fbinfo; |
424 | int ret; | 425 | int ret; |
@@ -540,10 +541,16 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) | |||
540 | goto out8; | 541 | goto out8; |
541 | } | 542 | } |
542 | #ifndef NO_BL_SUPPORT | 543 | #ifndef NO_BL_SUPPORT |
543 | bl_dev = | 544 | memset(&props, 0, sizeof(struct backlight_properties)); |
544 | backlight_device_register("bf52x-bl", NULL, NULL, | 545 | props.max_brightness = 255; |
545 | &bfin_lq043fb_bl_ops); | 546 | bl_dev = backlight_device_register("bf52x-bl", NULL, NULL, |
546 | bl_dev->props.max_brightness = 255; | 547 | &bfin_lq043fb_bl_ops, &props); |
548 | if (IS_ERR(bl_dev)) { | ||
549 | printk(KERN_ERR DRIVER_NAME | ||
550 | ": unable to register backlight.\n"); | ||
551 | ret = -EINVAL; | ||
552 | goto out9; | ||
553 | } | ||
547 | 554 | ||
548 | lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops); | 555 | lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops); |
549 | lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); | 556 | lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); |
@@ -551,6 +558,8 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) | |||
551 | 558 | ||
552 | return 0; | 559 | return 0; |
553 | 560 | ||
561 | out9: | ||
562 | unregister_framebuffer(fbinfo); | ||
554 | out8: | 563 | out8: |
555 | free_irq(info->irq, info); | 564 | free_irq(info->irq, info); |
556 | out7: | 565 | out7: |
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c index 443e3c85a9a0..2fb552a6f32c 100644 --- a/drivers/video/nvidia/nv_backlight.c +++ b/drivers/video/nvidia/nv_backlight.c | |||
@@ -94,6 +94,7 @@ static struct backlight_ops nvidia_bl_ops = { | |||
94 | 94 | ||
95 | void nvidia_bl_init(struct nvidia_par *par) | 95 | void nvidia_bl_init(struct nvidia_par *par) |
96 | { | 96 | { |
97 | struct backlight_properties props; | ||
97 | struct fb_info *info = pci_get_drvdata(par->pci_dev); | 98 | struct fb_info *info = pci_get_drvdata(par->pci_dev); |
98 | struct backlight_device *bd; | 99 | struct backlight_device *bd; |
99 | char name[12]; | 100 | char name[12]; |
@@ -109,7 +110,10 @@ void nvidia_bl_init(struct nvidia_par *par) | |||
109 | 110 | ||
110 | snprintf(name, sizeof(name), "nvidiabl%d", info->node); | 111 | snprintf(name, sizeof(name), "nvidiabl%d", info->node); |
111 | 112 | ||
112 | bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops); | 113 | memset(&props, 0, sizeof(struct backlight_properties)); |
114 | props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | ||
115 | bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops, | ||
116 | &props); | ||
113 | if (IS_ERR(bd)) { | 117 | if (IS_ERR(bd)) { |
114 | info->bl_dev = NULL; | 118 | info->bl_dev = NULL; |
115 | printk(KERN_WARNING "nvidia: Backlight registration failed\n"); | 119 | printk(KERN_WARNING "nvidia: Backlight registration failed\n"); |
@@ -121,7 +125,6 @@ void nvidia_bl_init(struct nvidia_par *par) | |||
121 | 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL, | 125 | 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL, |
122 | 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); | 126 | 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); |
123 | 127 | ||
124 | bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | ||
125 | bd->props.brightness = bd->props.max_brightness; | 128 | bd->props.brightness = bd->props.max_brightness; |
126 | bd->props.power = FB_BLANK_UNBLANK; | 129 | bd->props.power = FB_BLANK_UNBLANK; |
127 | backlight_update_status(bd); | 130 | backlight_update_status(bd); |
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index fcd6a61a91eb..59769e85d41c 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c | |||
@@ -486,6 +486,7 @@ static struct attribute_group taal_attr_group = { | |||
486 | 486 | ||
487 | static int taal_probe(struct omap_dss_device *dssdev) | 487 | static int taal_probe(struct omap_dss_device *dssdev) |
488 | { | 488 | { |
489 | struct backlight_properties props; | ||
489 | struct taal_data *td; | 490 | struct taal_data *td; |
490 | struct backlight_device *bldev; | 491 | struct backlight_device *bldev; |
491 | int r; | 492 | int r; |
@@ -520,11 +521,16 @@ static int taal_probe(struct omap_dss_device *dssdev) | |||
520 | 521 | ||
521 | /* if no platform set_backlight() defined, presume DSI backlight | 522 | /* if no platform set_backlight() defined, presume DSI backlight |
522 | * control */ | 523 | * control */ |
524 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
523 | if (!dssdev->set_backlight) | 525 | if (!dssdev->set_backlight) |
524 | td->use_dsi_bl = true; | 526 | td->use_dsi_bl = true; |
525 | 527 | ||
528 | if (td->use_dsi_bl) | ||
529 | props.max_brightness = 255; | ||
530 | else | ||
531 | props.max_brightness = 127; | ||
526 | bldev = backlight_device_register("taal", &dssdev->dev, dssdev, | 532 | bldev = backlight_device_register("taal", &dssdev->dev, dssdev, |
527 | &taal_bl_ops); | 533 | &taal_bl_ops, &props); |
528 | if (IS_ERR(bldev)) { | 534 | if (IS_ERR(bldev)) { |
529 | r = PTR_ERR(bldev); | 535 | r = PTR_ERR(bldev); |
530 | goto err2; | 536 | goto err2; |
@@ -534,13 +540,10 @@ static int taal_probe(struct omap_dss_device *dssdev) | |||
534 | 540 | ||
535 | bldev->props.fb_blank = FB_BLANK_UNBLANK; | 541 | bldev->props.fb_blank = FB_BLANK_UNBLANK; |
536 | bldev->props.power = FB_BLANK_UNBLANK; | 542 | bldev->props.power = FB_BLANK_UNBLANK; |
537 | if (td->use_dsi_bl) { | 543 | if (td->use_dsi_bl) |
538 | bldev->props.max_brightness = 255; | ||
539 | bldev->props.brightness = 255; | 544 | bldev->props.brightness = 255; |
540 | } else { | 545 | else |
541 | bldev->props.max_brightness = 127; | ||
542 | bldev->props.brightness = 127; | 546 | bldev->props.brightness = 127; |
543 | } | ||
544 | 547 | ||
545 | taal_bl_update_status(bldev); | 548 | taal_bl_update_status(bldev); |
546 | 549 | ||
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index d94c57ffbdb1..618f36bec10d 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c | |||
@@ -338,6 +338,7 @@ static struct backlight_ops riva_bl_ops = { | |||
338 | 338 | ||
339 | static void riva_bl_init(struct riva_par *par) | 339 | static void riva_bl_init(struct riva_par *par) |
340 | { | 340 | { |
341 | struct backlight_properties props; | ||
341 | struct fb_info *info = pci_get_drvdata(par->pdev); | 342 | struct fb_info *info = pci_get_drvdata(par->pdev); |
342 | struct backlight_device *bd; | 343 | struct backlight_device *bd; |
343 | char name[12]; | 344 | char name[12]; |
@@ -353,7 +354,10 @@ static void riva_bl_init(struct riva_par *par) | |||
353 | 354 | ||
354 | snprintf(name, sizeof(name), "rivabl%d", info->node); | 355 | snprintf(name, sizeof(name), "rivabl%d", info->node); |
355 | 356 | ||
356 | bd = backlight_device_register(name, info->dev, par, &riva_bl_ops); | 357 | memset(&props, 0, sizeof(struct backlight_properties)); |
358 | props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | ||
359 | bd = backlight_device_register(name, info->dev, par, &riva_bl_ops, | ||
360 | &props); | ||
357 | if (IS_ERR(bd)) { | 361 | if (IS_ERR(bd)) { |
358 | info->bl_dev = NULL; | 362 | info->bl_dev = NULL; |
359 | printk(KERN_WARNING "riva: Backlight registration failed\n"); | 363 | printk(KERN_WARNING "riva: Backlight registration failed\n"); |
@@ -365,7 +369,6 @@ static void riva_bl_init(struct riva_par *par) | |||
365 | MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL, | 369 | MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL, |
366 | FB_BACKLIGHT_MAX); | 370 | FB_BACKLIGHT_MAX); |
367 | 371 | ||
368 | bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; | ||
369 | bd->props.brightness = bd->props.max_brightness; | 372 | bd->props.brightness = bd->props.max_brightness; |
370 | bd->props.power = FB_BLANK_UNBLANK; | 373 | bd->props.power = FB_BLANK_UNBLANK; |
371 | backlight_update_status(bd); | 374 | backlight_update_status(bd); |