diff options
79 files changed, 1226 insertions, 584 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index c4e5b5dec154..bca09ed77029 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -752,11 +752,13 @@ W: http://atmelwlandriver.sourceforge.net/ | |||
| 752 | S: Maintained | 752 | S: Maintained |
| 753 | 753 | ||
| 754 | AUDIT SUBSYSTEM | 754 | AUDIT SUBSYSTEM |
| 755 | P: David Woodhouse | 755 | P: Al Viro |
| 756 | M: dwmw2@infradead.org | 756 | M: viro@zeniv.linux.org.uk |
| 757 | P: Eric Paris | ||
| 758 | M: eparis@redhat.com | ||
| 757 | L: linux-audit@redhat.com (subscribers-only) | 759 | L: linux-audit@redhat.com (subscribers-only) |
| 758 | W: http://people.redhat.com/sgrubb/audit/ | 760 | W: http://people.redhat.com/sgrubb/audit/ |
| 759 | T: git kernel.org:/pub/scm/linux/kernel/git/dwmw2/audit-2.6.git | 761 | T: git git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current.git |
| 760 | S: Maintained | 762 | S: Maintained |
| 761 | 763 | ||
| 762 | AUXILIARY DISPLAY DRIVERS | 764 | AUXILIARY DISPLAY DRIVERS |
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c index 7722466e052f..6342b0534f4d 100644 --- a/drivers/char/tty_audit.c +++ b/drivers/char/tty_audit.c | |||
| @@ -92,7 +92,7 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid, | |||
| 92 | get_task_comm(name, tsk); | 92 | get_task_comm(name, tsk); |
| 93 | audit_log_untrustedstring(ab, name); | 93 | audit_log_untrustedstring(ab, name); |
| 94 | audit_log_format(ab, " data="); | 94 | audit_log_format(ab, " data="); |
| 95 | audit_log_n_untrustedstring(ab, buf->valid, buf->data); | 95 | audit_log_n_untrustedstring(ab, buf->data, buf->valid); |
| 96 | audit_log_end(ab); | 96 | audit_log_end(ab); |
| 97 | } | 97 | } |
| 98 | buf->valid = 0; | 98 | buf->valid = 0; |
| @@ -151,14 +151,9 @@ void tty_audit_fork(struct signal_struct *sig) | |||
| 151 | /** | 151 | /** |
| 152 | * tty_audit_push_task - Flush task's pending audit data | 152 | * tty_audit_push_task - Flush task's pending audit data |
| 153 | */ | 153 | */ |
| 154 | void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid) | 154 | void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid) |
| 155 | { | 155 | { |
| 156 | struct tty_audit_buf *buf; | 156 | struct tty_audit_buf *buf; |
| 157 | /* FIXME I think this is correct. Check against netlink once that is | ||
| 158 | * I really need to read this code more closely. But that's for | ||
| 159 | * another patch. | ||
| 160 | */ | ||
| 161 | unsigned int sessionid = audit_get_sessionid(tsk); | ||
| 162 | 157 | ||
| 163 | spin_lock_irq(&tsk->sighand->siglock); | 158 | spin_lock_irq(&tsk->sighand->siglock); |
| 164 | buf = tsk->signal->tty_audit_buf; | 159 | buf = tsk->signal->tty_audit_buf; |
| @@ -238,6 +233,10 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, | |||
| 238 | if (unlikely(size == 0)) | 233 | if (unlikely(size == 0)) |
| 239 | return; | 234 | return; |
| 240 | 235 | ||
| 236 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY | ||
| 237 | && tty->driver->subtype == PTY_TYPE_MASTER) | ||
| 238 | return; | ||
| 239 | |||
| 241 | buf = tty_audit_buf_get(tty); | 240 | buf = tty_audit_buf_get(tty); |
| 242 | if (!buf) | 241 | if (!buf) |
| 243 | return; | 242 | return; |
| @@ -300,53 +299,3 @@ void tty_audit_push(struct tty_struct *tty) | |||
| 300 | tty_audit_buf_put(buf); | 299 | tty_audit_buf_put(buf); |
| 301 | } | 300 | } |
| 302 | } | 301 | } |
| 303 | |||
| 304 | /** | ||
| 305 | * tty_audit_opening - A TTY is being opened. | ||
| 306 | * | ||
| 307 | * As a special hack, tasks that close all their TTYs and open new ones | ||
| 308 | * are assumed to be system daemons (e.g. getty) and auditing is | ||
| 309 | * automatically disabled for them. | ||
| 310 | */ | ||
| 311 | void tty_audit_opening(void) | ||
| 312 | { | ||
| 313 | int disable; | ||
| 314 | |||
| 315 | disable = 1; | ||
| 316 | spin_lock_irq(¤t->sighand->siglock); | ||
| 317 | if (current->signal->audit_tty == 0) | ||
| 318 | disable = 0; | ||
| 319 | spin_unlock_irq(¤t->sighand->siglock); | ||
| 320 | if (!disable) | ||
| 321 | return; | ||
| 322 | |||
| 323 | task_lock(current); | ||
| 324 | if (current->files) { | ||
| 325 | struct fdtable *fdt; | ||
| 326 | unsigned i; | ||
| 327 | |||
| 328 | /* | ||
| 329 | * We don't take a ref to the file, so we must hold ->file_lock | ||
| 330 | * instead. | ||
| 331 | */ | ||
| 332 | spin_lock(¤t->files->file_lock); | ||
| 333 | fdt = files_fdtable(current->files); | ||
| 334 | for (i = 0; i < fdt->max_fds; i++) { | ||
| 335 | struct file *filp; | ||
| 336 | |||
| 337 | filp = fcheck_files(current->files, i); | ||
| 338 | if (filp && is_tty(filp)) { | ||
| 339 | disable = 0; | ||
| 340 | break; | ||
| 341 | } | ||
| 342 | } | ||
| 343 | spin_unlock(¤t->files->file_lock); | ||
| 344 | } | ||
| 345 | task_unlock(current); | ||
| 346 | if (!disable) | ||
| 347 | return; | ||
| 348 | |||
| 349 | spin_lock_irq(¤t->sighand->siglock); | ||
| 350 | current->signal->audit_tty = 0; | ||
| 351 | spin_unlock_irq(¤t->sighand->siglock); | ||
| 352 | } | ||
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 98b65a230994..2fa6856706ab 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
| @@ -2755,7 +2755,6 @@ got_driver: | |||
| 2755 | __proc_set_tty(current, tty); | 2755 | __proc_set_tty(current, tty); |
| 2756 | spin_unlock_irq(¤t->sighand->siglock); | 2756 | spin_unlock_irq(¤t->sighand->siglock); |
| 2757 | mutex_unlock(&tty_mutex); | 2757 | mutex_unlock(&tty_mutex); |
| 2758 | tty_audit_opening(); | ||
| 2759 | return 0; | 2758 | return 0; |
| 2760 | } | 2759 | } |
| 2761 | 2760 | ||
| @@ -2818,10 +2817,8 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
| 2818 | 2817 | ||
| 2819 | check_tty_count(tty, "tty_open"); | 2818 | check_tty_count(tty, "tty_open"); |
| 2820 | retval = ptm_driver->open(tty, filp); | 2819 | retval = ptm_driver->open(tty, filp); |
| 2821 | if (!retval) { | 2820 | if (!retval) |
| 2822 | tty_audit_opening(); | ||
| 2823 | return 0; | 2821 | return 0; |
| 2824 | } | ||
| 2825 | out1: | 2822 | out1: |
| 2826 | release_dev(filp); | 2823 | release_dev(filp); |
| 2827 | return retval; | 2824 | return retval; |
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index b36a22b8c213..c1922f9cfe80 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c | |||
| @@ -412,14 +412,14 @@ static u8 __devinit ali_cable_detect(ide_hwif_t *hwif) | |||
| 412 | return cbl; | 412 | return cbl; |
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | #ifndef CONFIG_SPARC64 | 415 | #if !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC) |
| 416 | /** | 416 | /** |
| 417 | * init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff | 417 | * init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff |
| 418 | * @hwif: interface to configure | 418 | * @hwif: interface to configure |
| 419 | * | 419 | * |
| 420 | * Obtain the IRQ tables for an ALi based IDE solution on the PC | 420 | * Obtain the IRQ tables for an ALi based IDE solution on the PC |
| 421 | * class platforms. This part of the code isn't applicable to the | 421 | * class platforms. This part of the code isn't applicable to the |
| 422 | * Sparc systems | 422 | * Sparc and PowerPC systems. |
| 423 | */ | 423 | */ |
| 424 | 424 | ||
| 425 | static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif) | 425 | static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif) |
| @@ -463,7 +463,9 @@ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif) | |||
| 463 | hwif->irq = irq; | 463 | hwif->irq = irq; |
| 464 | } | 464 | } |
| 465 | } | 465 | } |
| 466 | #endif | 466 | #else |
| 467 | #define init_hwif_ali15x3 NULL | ||
| 468 | #endif /* !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC) */ | ||
| 467 | 469 | ||
| 468 | /** | 470 | /** |
| 469 | * init_dma_ali15x3 - set up DMA on ALi15x3 | 471 | * init_dma_ali15x3 - set up DMA on ALi15x3 |
| @@ -517,9 +519,7 @@ static const struct ide_dma_ops ali_dma_ops = { | |||
| 517 | static const struct ide_port_info ali15x3_chipset __devinitdata = { | 519 | static const struct ide_port_info ali15x3_chipset __devinitdata = { |
| 518 | .name = "ALI15X3", | 520 | .name = "ALI15X3", |
| 519 | .init_chipset = init_chipset_ali15x3, | 521 | .init_chipset = init_chipset_ali15x3, |
| 520 | #ifndef CONFIG_SPARC64 | ||
| 521 | .init_hwif = init_hwif_ali15x3, | 522 | .init_hwif = init_hwif_ali15x3, |
| 522 | #endif | ||
| 523 | .init_dma = init_dma_ali15x3, | 523 | .init_dma = init_dma_ali15x3, |
| 524 | .port_ops = &ali_port_ops, | 524 | .port_ops = &ali_port_ops, |
| 525 | .pio_mask = ATA_PIO5, | 525 | .pio_mask = ATA_PIO5, |
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 4cf8fc54aa2a..0006b9e58567 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c | |||
| @@ -737,8 +737,15 @@ static const struct ide_port_ops sil_sata_port_ops = { | |||
| 737 | .cable_detect = sil_cable_detect, | 737 | .cable_detect = sil_cable_detect, |
| 738 | }; | 738 | }; |
| 739 | 739 | ||
| 740 | static struct ide_dma_ops sil_dma_ops = { | 740 | static const struct ide_dma_ops sil_dma_ops = { |
| 741 | .dma_host_set = ide_dma_host_set, | ||
| 742 | .dma_setup = ide_dma_setup, | ||
| 743 | .dma_exec_cmd = ide_dma_exec_cmd, | ||
| 744 | .dma_start = ide_dma_start, | ||
| 745 | .dma_end = __ide_dma_end, | ||
| 741 | .dma_test_irq = siimage_dma_test_irq, | 746 | .dma_test_irq = siimage_dma_test_irq, |
| 747 | .dma_timeout = ide_dma_timeout, | ||
| 748 | .dma_lost_irq = ide_dma_lost_irq, | ||
| 742 | }; | 749 | }; |
| 743 | 750 | ||
| 744 | #define DECLARE_SII_DEV(name_str, p_ops) \ | 751 | #define DECLARE_SII_DEV(name_str, p_ops) \ |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index 66eb7030aea8..ed2ee4ba4b7c 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c | |||
| @@ -456,7 +456,8 @@ void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count) | |||
| 456 | ptr = cq->sw_rptr; | 456 | ptr = cq->sw_rptr; |
| 457 | while (!Q_EMPTY(ptr, cq->sw_wptr)) { | 457 | while (!Q_EMPTY(ptr, cq->sw_wptr)) { |
| 458 | cqe = cq->sw_queue + (Q_PTR2IDX(ptr, cq->size_log2)); | 458 | cqe = cq->sw_queue + (Q_PTR2IDX(ptr, cq->size_log2)); |
| 459 | if ((SQ_TYPE(*cqe) || (CQE_OPCODE(*cqe) == T3_READ_RESP)) && | 459 | if ((SQ_TYPE(*cqe) || |
| 460 | ((CQE_OPCODE(*cqe) == T3_READ_RESP) && wq->oldest_read)) && | ||
| 460 | (CQE_QPID(*cqe) == wq->qpid)) | 461 | (CQE_QPID(*cqe) == wq->qpid)) |
| 461 | (*count)++; | 462 | (*count)++; |
| 462 | ptr++; | 463 | ptr++; |
| @@ -829,7 +830,8 @@ int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr) | |||
| 829 | wqe->mpaattrs = attr->mpaattrs; | 830 | wqe->mpaattrs = attr->mpaattrs; |
| 830 | wqe->qpcaps = attr->qpcaps; | 831 | wqe->qpcaps = attr->qpcaps; |
| 831 | wqe->ulpdu_size = cpu_to_be16(attr->tcp_emss); | 832 | wqe->ulpdu_size = cpu_to_be16(attr->tcp_emss); |
| 832 | wqe->flags = cpu_to_be32(attr->flags); | 833 | wqe->rqe_count = cpu_to_be16(attr->rqe_count); |
| 834 | wqe->flags_rtr_type = cpu_to_be16(attr->flags|V_RTR_TYPE(attr->rtr_type)); | ||
| 833 | wqe->ord = cpu_to_be32(attr->ord); | 835 | wqe->ord = cpu_to_be32(attr->ord); |
| 834 | wqe->ird = cpu_to_be32(attr->ird); | 836 | wqe->ird = cpu_to_be32(attr->ird); |
| 835 | wqe->qp_dma_addr = cpu_to_be64(attr->qp_dma_addr); | 837 | wqe->qp_dma_addr = cpu_to_be64(attr->qp_dma_addr); |
| @@ -1135,6 +1137,18 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe, | |||
| 1135 | if (RQ_TYPE(*hw_cqe) && (CQE_OPCODE(*hw_cqe) == T3_READ_RESP)) { | 1137 | if (RQ_TYPE(*hw_cqe) && (CQE_OPCODE(*hw_cqe) == T3_READ_RESP)) { |
| 1136 | 1138 | ||
| 1137 | /* | 1139 | /* |
| 1140 | * If this is an unsolicited read response, then the read | ||
| 1141 | * was generated by the kernel driver as part of peer-2-peer | ||
| 1142 | * connection setup. So ignore the completion. | ||
| 1143 | */ | ||
| 1144 | if (!wq->oldest_read) { | ||
| 1145 | if (CQE_STATUS(*hw_cqe)) | ||
| 1146 | wq->error = 1; | ||
| 1147 | ret = -1; | ||
| 1148 | goto skip_cqe; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | /* | ||
| 1138 | * Don't write to the HWCQ, so create a new read req CQE | 1152 | * Don't write to the HWCQ, so create a new read req CQE |
| 1139 | * in local memory. | 1153 | * in local memory. |
| 1140 | */ | 1154 | */ |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index 99543d634704..2bcff7f5046e 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h | |||
| @@ -53,6 +53,7 @@ | |||
| 53 | #define T3_MAX_PBL_SIZE 256 | 53 | #define T3_MAX_PBL_SIZE 256 |
| 54 | #define T3_MAX_RQ_SIZE 1024 | 54 | #define T3_MAX_RQ_SIZE 1024 |
| 55 | #define T3_MAX_NUM_STAG (1<<15) | 55 | #define T3_MAX_NUM_STAG (1<<15) |
| 56 | #define T3_MAX_MR_SIZE 0x100000000ULL | ||
| 56 | 57 | ||
| 57 | #define T3_STAG_UNSET 0xffffffff | 58 | #define T3_STAG_UNSET 0xffffffff |
| 58 | 59 | ||
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h index 969d4d928455..f1a25a821a45 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_wr.h +++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h | |||
| @@ -278,6 +278,17 @@ enum t3_qp_caps { | |||
| 278 | uP_RI_QP_STAG0_ENABLE = 0x10 | 278 | uP_RI_QP_STAG0_ENABLE = 0x10 |
| 279 | } __attribute__ ((packed)); | 279 | } __attribute__ ((packed)); |
| 280 | 280 | ||
| 281 | enum rdma_init_rtr_types { | ||
| 282 | RTR_READ = 1, | ||
| 283 | RTR_WRITE = 2, | ||
| 284 | RTR_SEND = 3, | ||
| 285 | }; | ||
| 286 | |||
| 287 | #define S_RTR_TYPE 2 | ||
| 288 | #define M_RTR_TYPE 0x3 | ||
| 289 | #define V_RTR_TYPE(x) ((x) << S_RTR_TYPE) | ||
| 290 | #define G_RTR_TYPE(x) ((((x) >> S_RTR_TYPE)) & M_RTR_TYPE) | ||
| 291 | |||
| 281 | struct t3_rdma_init_attr { | 292 | struct t3_rdma_init_attr { |
| 282 | u32 tid; | 293 | u32 tid; |
| 283 | u32 qpid; | 294 | u32 qpid; |
| @@ -293,7 +304,9 @@ struct t3_rdma_init_attr { | |||
| 293 | u32 ird; | 304 | u32 ird; |
| 294 | u64 qp_dma_addr; | 305 | u64 qp_dma_addr; |
| 295 | u32 qp_dma_size; | 306 | u32 qp_dma_size; |
| 296 | u32 flags; | 307 | enum rdma_init_rtr_types rtr_type; |
| 308 | u16 flags; | ||
| 309 | u16 rqe_count; | ||
| 297 | u32 irs; | 310 | u32 irs; |
| 298 | }; | 311 | }; |
| 299 | 312 | ||
| @@ -309,8 +322,8 @@ struct t3_rdma_init_wr { | |||
| 309 | u8 mpaattrs; /* 5 */ | 322 | u8 mpaattrs; /* 5 */ |
| 310 | u8 qpcaps; | 323 | u8 qpcaps; |
| 311 | __be16 ulpdu_size; | 324 | __be16 ulpdu_size; |
| 312 | __be32 flags; /* bits 31-1 - reservered */ | 325 | __be16 flags_rtr_type; |
| 313 | /* bit 0 - set if RECV posted */ | 326 | __be16 rqe_count; |
| 314 | __be32 ord; /* 6 */ | 327 | __be32 ord; /* 6 */ |
| 315 | __be32 ird; | 328 | __be32 ird; |
| 316 | __be64 qp_dma_addr; /* 7 */ | 329 | __be64 qp_dma_addr; /* 7 */ |
| @@ -324,7 +337,7 @@ struct t3_genbit { | |||
| 324 | }; | 337 | }; |
| 325 | 338 | ||
| 326 | enum rdma_init_wr_flags { | 339 | enum rdma_init_wr_flags { |
| 327 | RECVS_POSTED = (1<<0), | 340 | MPA_INITIATOR = (1<<0), |
| 328 | PRIV_QP = (1<<1), | 341 | PRIV_QP = (1<<1), |
| 329 | }; | 342 | }; |
| 330 | 343 | ||
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c index 6ba4138c8ec3..71554eacb13c 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.c +++ b/drivers/infiniband/hw/cxgb3/iwch.c | |||
| @@ -83,6 +83,7 @@ static void rnic_init(struct iwch_dev *rnicp) | |||
| 83 | rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE; | 83 | rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE; |
| 84 | rnicp->attr.max_pds = T3_MAX_NUM_PD - 1; | 84 | rnicp->attr.max_pds = T3_MAX_NUM_PD - 1; |
| 85 | rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */ | 85 | rnicp->attr.mem_pgsizes_bitmask = 0x7FFF; /* 4KB-128MB */ |
| 86 | rnicp->attr.max_mr_size = T3_MAX_MR_SIZE; | ||
| 86 | rnicp->attr.can_resize_wq = 0; | 87 | rnicp->attr.can_resize_wq = 0; |
| 87 | rnicp->attr.max_rdma_reads_per_qp = 8; | 88 | rnicp->attr.max_rdma_reads_per_qp = 8; |
| 88 | rnicp->attr.max_rdma_read_resources = | 89 | rnicp->attr.max_rdma_read_resources = |
diff --git a/drivers/infiniband/hw/cxgb3/iwch.h b/drivers/infiniband/hw/cxgb3/iwch.h index 9ad9b1e7c8c1..d2409a505e8d 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.h +++ b/drivers/infiniband/hw/cxgb3/iwch.h | |||
| @@ -66,6 +66,7 @@ struct iwch_rnic_attributes { | |||
| 66 | * size (4k)^i. Phys block list mode unsupported. | 66 | * size (4k)^i. Phys block list mode unsupported. |
| 67 | */ | 67 | */ |
| 68 | u32 mem_pgsizes_bitmask; | 68 | u32 mem_pgsizes_bitmask; |
| 69 | u64 max_mr_size; | ||
| 69 | u8 can_resize_wq; | 70 | u8 can_resize_wq; |
| 70 | 71 | ||
| 71 | /* | 72 | /* |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 72ca360c3dbc..d44a6df9ad8c 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
| @@ -63,6 +63,10 @@ static char *states[] = { | |||
| 63 | NULL, | 63 | NULL, |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | int peer2peer = 0; | ||
| 67 | module_param(peer2peer, int, 0644); | ||
| 68 | MODULE_PARM_DESC(peer2peer, "Support peer2peer ULPs (default=0)"); | ||
| 69 | |||
| 66 | static int ep_timeout_secs = 10; | 70 | static int ep_timeout_secs = 10; |
| 67 | module_param(ep_timeout_secs, int, 0644); | 71 | module_param(ep_timeout_secs, int, 0644); |
| 68 | MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout " | 72 | MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout " |
| @@ -125,6 +129,12 @@ static void start_ep_timer(struct iwch_ep *ep) | |||
| 125 | static void stop_ep_timer(struct iwch_ep *ep) | 129 | static void stop_ep_timer(struct iwch_ep *ep) |
| 126 | { | 130 | { |
| 127 | PDBG("%s ep %p\n", __func__, ep); | 131 | PDBG("%s ep %p\n", __func__, ep); |
| 132 | if (!timer_pending(&ep->timer)) { | ||
| 133 | printk(KERN_ERR "%s timer stopped when its not running! ep %p state %u\n", | ||
| 134 | __func__, ep, ep->com.state); | ||
| 135 | WARN_ON(1); | ||
| 136 | return; | ||
| 137 | } | ||
| 128 | del_timer_sync(&ep->timer); | 138 | del_timer_sync(&ep->timer); |
| 129 | put_ep(&ep->com); | 139 | put_ep(&ep->com); |
| 130 | } | 140 | } |
| @@ -508,7 +518,7 @@ static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb) | |||
| 508 | skb_reset_transport_header(skb); | 518 | skb_reset_transport_header(skb); |
| 509 | len = skb->len; | 519 | len = skb->len; |
| 510 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); | 520 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); |
| 511 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); | 521 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)|F_WR_COMPL); |
| 512 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); | 522 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); |
| 513 | req->len = htonl(len); | 523 | req->len = htonl(len); |
| 514 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | | 524 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | |
| @@ -559,7 +569,7 @@ static int send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen) | |||
| 559 | set_arp_failure_handler(skb, arp_failure_discard); | 569 | set_arp_failure_handler(skb, arp_failure_discard); |
| 560 | skb_reset_transport_header(skb); | 570 | skb_reset_transport_header(skb); |
| 561 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); | 571 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); |
| 562 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); | 572 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)|F_WR_COMPL); |
| 563 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); | 573 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); |
| 564 | req->len = htonl(mpalen); | 574 | req->len = htonl(mpalen); |
| 565 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | | 575 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | |
| @@ -611,7 +621,7 @@ static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen) | |||
| 611 | skb_reset_transport_header(skb); | 621 | skb_reset_transport_header(skb); |
| 612 | len = skb->len; | 622 | len = skb->len; |
| 613 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); | 623 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); |
| 614 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); | 624 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)|F_WR_COMPL); |
| 615 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); | 625 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); |
| 616 | req->len = htonl(len); | 626 | req->len = htonl(len); |
| 617 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | | 627 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | |
| @@ -879,6 +889,7 @@ static void process_mpa_reply(struct iwch_ep *ep, struct sk_buff *skb) | |||
| 879 | * the MPA header is valid. | 889 | * the MPA header is valid. |
| 880 | */ | 890 | */ |
| 881 | state_set(&ep->com, FPDU_MODE); | 891 | state_set(&ep->com, FPDU_MODE); |
| 892 | ep->mpa_attr.initiator = 1; | ||
| 882 | ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; | 893 | ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; |
| 883 | ep->mpa_attr.recv_marker_enabled = markers_enabled; | 894 | ep->mpa_attr.recv_marker_enabled = markers_enabled; |
| 884 | ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; | 895 | ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; |
| @@ -901,8 +912,14 @@ static void process_mpa_reply(struct iwch_ep *ep, struct sk_buff *skb) | |||
| 901 | /* bind QP and TID with INIT_WR */ | 912 | /* bind QP and TID with INIT_WR */ |
| 902 | err = iwch_modify_qp(ep->com.qp->rhp, | 913 | err = iwch_modify_qp(ep->com.qp->rhp, |
| 903 | ep->com.qp, mask, &attrs, 1); | 914 | ep->com.qp, mask, &attrs, 1); |
| 904 | if (!err) | 915 | if (err) |
| 905 | goto out; | 916 | goto err; |
| 917 | |||
| 918 | if (peer2peer && iwch_rqes_posted(ep->com.qp) == 0) { | ||
| 919 | iwch_post_zb_read(ep->com.qp); | ||
| 920 | } | ||
| 921 | |||
| 922 | goto out; | ||
| 906 | err: | 923 | err: |
| 907 | abort_connection(ep, skb, GFP_KERNEL); | 924 | abort_connection(ep, skb, GFP_KERNEL); |
| 908 | out: | 925 | out: |
| @@ -995,6 +1012,7 @@ static void process_mpa_request(struct iwch_ep *ep, struct sk_buff *skb) | |||
| 995 | * If we get here we have accumulated the entire mpa | 1012 | * If we get here we have accumulated the entire mpa |
| 996 | * start reply message including private data. | 1013 | * start reply message including private data. |
| 997 | */ | 1014 | */ |
| 1015 | ep->mpa_attr.initiator = 0; | ||
| 998 | ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; | 1016 | ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; |
| 999 | ep->mpa_attr.recv_marker_enabled = markers_enabled; | 1017 | ep->mpa_attr.recv_marker_enabled = markers_enabled; |
| 1000 | ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; | 1018 | ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; |
| @@ -1065,17 +1083,33 @@ static int tx_ack(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1065 | 1083 | ||
| 1066 | PDBG("%s ep %p credits %u\n", __func__, ep, credits); | 1084 | PDBG("%s ep %p credits %u\n", __func__, ep, credits); |
| 1067 | 1085 | ||
| 1068 | if (credits == 0) | 1086 | if (credits == 0) { |
| 1087 | PDBG(KERN_ERR "%s 0 credit ack ep %p state %u\n", | ||
| 1088 | __func__, ep, state_read(&ep->com)); | ||
| 1069 | return CPL_RET_BUF_DONE; | 1089 | return CPL_RET_BUF_DONE; |
| 1090 | } | ||
| 1091 | |||
| 1070 | BUG_ON(credits != 1); | 1092 | BUG_ON(credits != 1); |
| 1071 | BUG_ON(ep->mpa_skb == NULL); | ||
| 1072 | kfree_skb(ep->mpa_skb); | ||
| 1073 | ep->mpa_skb = NULL; | ||
| 1074 | dst_confirm(ep->dst); | 1093 | dst_confirm(ep->dst); |
| 1075 | if (state_read(&ep->com) == MPA_REP_SENT) { | 1094 | if (!ep->mpa_skb) { |
| 1076 | ep->com.rpl_done = 1; | 1095 | PDBG("%s rdma_init wr_ack ep %p state %u\n", |
| 1077 | PDBG("waking up ep %p\n", ep); | 1096 | __func__, ep, state_read(&ep->com)); |
| 1078 | wake_up(&ep->com.waitq); | 1097 | if (ep->mpa_attr.initiator) { |
| 1098 | PDBG("%s initiator ep %p state %u\n", | ||
| 1099 | __func__, ep, state_read(&ep->com)); | ||
| 1100 | if (peer2peer) | ||
| 1101 | iwch_post_zb_read(ep->com.qp); | ||
| 1102 | } else { | ||
| 1103 | PDBG("%s responder ep %p state %u\n", | ||
| 1104 | __func__, ep, state_read(&ep->com)); | ||
| 1105 | ep->com.rpl_done = 1; | ||
| 1106 | wake_up(&ep->com.waitq); | ||
| 1107 | } | ||
| 1108 | } else { | ||
| 1109 | PDBG("%s lsm ack ep %p state %u freeing skb\n", | ||
| 1110 | __func__, ep, state_read(&ep->com)); | ||
| 1111 | kfree_skb(ep->mpa_skb); | ||
| 1112 | ep->mpa_skb = NULL; | ||
| 1079 | } | 1113 | } |
| 1080 | return CPL_RET_BUF_DONE; | 1114 | return CPL_RET_BUF_DONE; |
| 1081 | } | 1115 | } |
| @@ -1083,8 +1117,11 @@ static int tx_ack(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1083 | static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | 1117 | static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) |
| 1084 | { | 1118 | { |
| 1085 | struct iwch_ep *ep = ctx; | 1119 | struct iwch_ep *ep = ctx; |
| 1120 | unsigned long flags; | ||
| 1121 | int release = 0; | ||
| 1086 | 1122 | ||
| 1087 | PDBG("%s ep %p\n", __func__, ep); | 1123 | PDBG("%s ep %p\n", __func__, ep); |
| 1124 | BUG_ON(!ep); | ||
| 1088 | 1125 | ||
| 1089 | /* | 1126 | /* |
| 1090 | * We get 2 abort replies from the HW. The first one must | 1127 | * We get 2 abort replies from the HW. The first one must |
| @@ -1095,9 +1132,22 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1095 | return CPL_RET_BUF_DONE; | 1132 | return CPL_RET_BUF_DONE; |
| 1096 | } | 1133 | } |
| 1097 | 1134 | ||
| 1098 | close_complete_upcall(ep); | 1135 | spin_lock_irqsave(&ep->com.lock, flags); |
| 1099 | state_set(&ep->com, DEAD); | 1136 | switch (ep->com.state) { |
| 1100 | release_ep_resources(ep); | 1137 | case ABORTING: |
| 1138 | close_complete_upcall(ep); | ||
| 1139 | __state_set(&ep->com, DEAD); | ||
| 1140 | release = 1; | ||
| 1141 | break; | ||
| 1142 | default: | ||
| 1143 | printk(KERN_ERR "%s ep %p state %d\n", | ||
| 1144 | __func__, ep, ep->com.state); | ||
| 1145 | break; | ||
| 1146 | } | ||
| 1147 | spin_unlock_irqrestore(&ep->com.lock, flags); | ||
| 1148 | |||
| 1149 | if (release) | ||
| 1150 | release_ep_resources(ep); | ||
| 1101 | return CPL_RET_BUF_DONE; | 1151 | return CPL_RET_BUF_DONE; |
| 1102 | } | 1152 | } |
| 1103 | 1153 | ||
| @@ -1470,7 +1520,8 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1470 | struct sk_buff *rpl_skb; | 1520 | struct sk_buff *rpl_skb; |
| 1471 | struct iwch_qp_attributes attrs; | 1521 | struct iwch_qp_attributes attrs; |
| 1472 | int ret; | 1522 | int ret; |
| 1473 | int state; | 1523 | int release = 0; |
| 1524 | unsigned long flags; | ||
| 1474 | 1525 | ||
| 1475 | if (is_neg_adv_abort(req->status)) { | 1526 | if (is_neg_adv_abort(req->status)) { |
| 1476 | PDBG("%s neg_adv_abort ep %p tid %d\n", __func__, ep, | 1527 | PDBG("%s neg_adv_abort ep %p tid %d\n", __func__, ep, |
| @@ -1488,9 +1539,9 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1488 | return CPL_RET_BUF_DONE; | 1539 | return CPL_RET_BUF_DONE; |
| 1489 | } | 1540 | } |
| 1490 | 1541 | ||
| 1491 | state = state_read(&ep->com); | 1542 | spin_lock_irqsave(&ep->com.lock, flags); |
| 1492 | PDBG("%s ep %p state %u\n", __func__, ep, state); | 1543 | PDBG("%s ep %p state %u\n", __func__, ep, ep->com.state); |
| 1493 | switch (state) { | 1544 | switch (ep->com.state) { |
| 1494 | case CONNECTING: | 1545 | case CONNECTING: |
| 1495 | break; | 1546 | break; |
| 1496 | case MPA_REQ_WAIT: | 1547 | case MPA_REQ_WAIT: |
| @@ -1536,21 +1587,25 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1536 | break; | 1587 | break; |
| 1537 | case DEAD: | 1588 | case DEAD: |
| 1538 | PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__); | 1589 | PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__); |
| 1590 | spin_unlock_irqrestore(&ep->com.lock, flags); | ||
| 1539 | return CPL_RET_BUF_DONE; | 1591 | return CPL_RET_BUF_DONE; |
| 1540 | default: | 1592 | default: |
| 1541 | BUG_ON(1); | 1593 | BUG_ON(1); |
| 1542 | break; | 1594 | break; |
| 1543 | } | 1595 | } |
| 1544 | dst_confirm(ep->dst); | 1596 | dst_confirm(ep->dst); |
| 1597 | if (ep->com.state != ABORTING) { | ||
| 1598 | __state_set(&ep->com, DEAD); | ||
| 1599 | release = 1; | ||
| 1600 | } | ||
| 1601 | spin_unlock_irqrestore(&ep->com.lock, flags); | ||
| 1545 | 1602 | ||
| 1546 | rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL); | 1603 | rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL); |
| 1547 | if (!rpl_skb) { | 1604 | if (!rpl_skb) { |
| 1548 | printk(KERN_ERR MOD "%s - cannot allocate skb!\n", | 1605 | printk(KERN_ERR MOD "%s - cannot allocate skb!\n", |
| 1549 | __func__); | 1606 | __func__); |
| 1550 | dst_release(ep->dst); | 1607 | release = 1; |
| 1551 | l2t_release(L2DATA(ep->com.tdev), ep->l2t); | 1608 | goto out; |
| 1552 | put_ep(&ep->com); | ||
| 1553 | return CPL_RET_BUF_DONE; | ||
| 1554 | } | 1609 | } |
| 1555 | rpl_skb->priority = CPL_PRIORITY_DATA; | 1610 | rpl_skb->priority = CPL_PRIORITY_DATA; |
| 1556 | rpl = (struct cpl_abort_rpl *) skb_put(rpl_skb, sizeof(*rpl)); | 1611 | rpl = (struct cpl_abort_rpl *) skb_put(rpl_skb, sizeof(*rpl)); |
| @@ -1559,10 +1614,9 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
| 1559 | OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); | 1614 | OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); |
| 1560 | rpl->cmd = CPL_ABORT_NO_RST; | 1615 | rpl->cmd = CPL_ABORT_NO_RST; |
| 1561 | cxgb3_ofld_send(ep->com.tdev, rpl_skb); | 1616 | cxgb3_ofld_send(ep->com.tdev, rpl_skb); |
| 1562 | if (state != ABORTING) { | 1617 | out: |
| 1563 | state_set(&ep->com, DEAD); | 1618 | if (release) |
| 1564 | release_ep_resources(ep); | 1619 | release_ep_resources(ep); |
| 1565 | } | ||
| 1566 | return CPL_RET_BUF_DONE; | 1620 | return CPL_RET_BUF_DONE; |
| 1567 | } | 1621 | } |
| 1568 | 1622 | ||
| @@ -1661,15 +1715,18 @@ static void ep_timeout(unsigned long arg) | |||
| 1661 | struct iwch_ep *ep = (struct iwch_ep *)arg; | 1715 | struct iwch_ep *ep = (struct iwch_ep *)arg; |
| 1662 | struct iwch_qp_attributes attrs; | 1716 | struct iwch_qp_attributes attrs; |
| 1663 | unsigned long flags; | 1717 | unsigned long flags; |
| 1718 | int abort = 1; | ||
| 1664 | 1719 | ||
| 1665 | spin_lock_irqsave(&ep->com.lock, flags); | 1720 | spin_lock_irqsave(&ep->com.lock, flags); |
| 1666 | PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid, | 1721 | PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid, |
| 1667 | ep->com.state); | 1722 | ep->com.state); |
| 1668 | switch (ep->com.state) { | 1723 | switch (ep->com.state) { |
| 1669 | case MPA_REQ_SENT: | 1724 | case MPA_REQ_SENT: |
| 1725 | __state_set(&ep->com, ABORTING); | ||
| 1670 | connect_reply_upcall(ep, -ETIMEDOUT); | 1726 | connect_reply_upcall(ep, -ETIMEDOUT); |
| 1671 | break; | 1727 | break; |
| 1672 | case MPA_REQ_WAIT: | 1728 | case MPA_REQ_WAIT: |
| 1729 | __state_set(&ep->com, ABORTING); | ||
| 1673 | break; | 1730 | break; |
| 1674 | case CLOSING: | 1731 | case CLOSING: |
| 1675 | case MORIBUND: | 1732 | case MORIBUND: |
| @@ -1679,13 +1736,17 @@ static void ep_timeout(unsigned long arg) | |||
| 1679 | ep->com.qp, IWCH_QP_ATTR_NEXT_STATE, | 1736 | ep->com.qp, IWCH_QP_ATTR_NEXT_STATE, |
| 1680 | &attrs, 1); | 1737 | &attrs, 1); |
| 1681 | } | 1738 | } |
| 1739 | __state_set(&ep->com, ABORTING); | ||
| 1682 | break; | 1740 | break; |
| 1683 | default: | 1741 | default: |
| 1684 | BUG(); | 1742 | printk(KERN_ERR "%s unexpected state ep %p state %u\n", |
| 1743 | __func__, ep, ep->com.state); | ||
| 1744 | WARN_ON(1); | ||
| 1745 | abort = 0; | ||
| 1685 | } | 1746 | } |
| 1686 | __state_set(&ep->com, CLOSING); | ||
| 1687 | spin_unlock_irqrestore(&ep->com.lock, flags); | 1747 | spin_unlock_irqrestore(&ep->com.lock, flags); |
| 1688 | abort_connection(ep, NULL, GFP_ATOMIC); | 1748 | if (abort) |
| 1749 | abort_connection(ep, NULL, GFP_ATOMIC); | ||
| 1689 | put_ep(&ep->com); | 1750 | put_ep(&ep->com); |
| 1690 | } | 1751 | } |
| 1691 | 1752 | ||
| @@ -1762,16 +1823,19 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
| 1762 | if (err) | 1823 | if (err) |
| 1763 | goto err; | 1824 | goto err; |
| 1764 | 1825 | ||
| 1826 | /* if needed, wait for wr_ack */ | ||
| 1827 | if (iwch_rqes_posted(qp)) { | ||
| 1828 | wait_event(ep->com.waitq, ep->com.rpl_done); | ||
| 1829 | err = ep->com.rpl_err; | ||
| 1830 | if (err) | ||
| 1831 | goto err; | ||
| 1832 | } | ||
| 1833 | |||
| 1765 | err = send_mpa_reply(ep, conn_param->private_data, | 1834 | err = send_mpa_reply(ep, conn_param->private_data, |
| 1766 | conn_param->private_data_len); | 1835 | conn_param->private_data_len); |
| 1767 | if (err) | 1836 | if (err) |
| 1768 | goto err; | 1837 | goto err; |
| 1769 | 1838 | ||
| 1770 | /* wait for wr_ack */ | ||
| 1771 | wait_event(ep->com.waitq, ep->com.rpl_done); | ||
| 1772 | err = ep->com.rpl_err; | ||
| 1773 | if (err) | ||
| 1774 | goto err; | ||
| 1775 | 1839 | ||
| 1776 | state_set(&ep->com, FPDU_MODE); | 1840 | state_set(&ep->com, FPDU_MODE); |
| 1777 | established_upcall(ep); | 1841 | established_upcall(ep); |
| @@ -1968,40 +2032,39 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp) | |||
| 1968 | PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, | 2032 | PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, |
| 1969 | states[ep->com.state], abrupt); | 2033 | states[ep->com.state], abrupt); |
| 1970 | 2034 | ||
| 1971 | if (ep->com.state == DEAD) { | ||
| 1972 | PDBG("%s already dead ep %p\n", __func__, ep); | ||
| 1973 | goto out; | ||
| 1974 | } | ||
| 1975 | |||
| 1976 | if (abrupt) { | ||
| 1977 | if (ep->com.state != ABORTING) { | ||
| 1978 | ep->com.state = ABORTING; | ||
| 1979 | close = 1; | ||
| 1980 | } | ||
| 1981 | goto out; | ||
| 1982 | } | ||
| 1983 | |||
| 1984 | switch (ep->com.state) { | 2035 | switch (ep->com.state) { |
| 1985 | case MPA_REQ_WAIT: | 2036 | case MPA_REQ_WAIT: |
| 1986 | case MPA_REQ_SENT: | 2037 | case MPA_REQ_SENT: |
| 1987 | case MPA_REQ_RCVD: | 2038 | case MPA_REQ_RCVD: |
| 1988 | case MPA_REP_SENT: | 2039 | case MPA_REP_SENT: |
| 1989 | case FPDU_MODE: | 2040 | case FPDU_MODE: |
| 1990 | start_ep_timer(ep); | ||
| 1991 | ep->com.state = CLOSING; | ||
| 1992 | close = 1; | 2041 | close = 1; |
| 2042 | if (abrupt) | ||
| 2043 | ep->com.state = ABORTING; | ||
| 2044 | else { | ||
| 2045 | ep->com.state = CLOSING; | ||
| 2046 | start_ep_timer(ep); | ||
| 2047 | } | ||
| 1993 | break; | 2048 | break; |
| 1994 | case CLOSING: | 2049 | case CLOSING: |
| 1995 | ep->com.state = MORIBUND; | ||
| 1996 | close = 1; | 2050 | close = 1; |
| 2051 | if (abrupt) { | ||
| 2052 | stop_ep_timer(ep); | ||
| 2053 | ep->com.state = ABORTING; | ||
| 2054 | } else | ||
| 2055 | ep->com.state = MORIBUND; | ||
| 1997 | break; | 2056 | break; |
| 1998 | case MORIBUND: | 2057 | case MORIBUND: |
| 2058 | case ABORTING: | ||
| 2059 | case DEAD: | ||
| 2060 | PDBG("%s ignoring disconnect ep %p state %u\n", | ||
| 2061 | __func__, ep, ep->com.state); | ||
| 1999 | break; | 2062 | break; |
| 2000 | default: | 2063 | default: |
| 2001 | BUG(); | 2064 | BUG(); |
| 2002 | break; | 2065 | break; |
| 2003 | } | 2066 | } |
| 2004 | out: | 2067 | |
| 2005 | spin_unlock_irqrestore(&ep->com.lock, flags); | 2068 | spin_unlock_irqrestore(&ep->com.lock, flags); |
| 2006 | if (close) { | 2069 | if (close) { |
| 2007 | if (abrupt) | 2070 | if (abrupt) |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.h b/drivers/infiniband/hw/cxgb3/iwch_cm.h index 2bb7fbdb3ff4..d7c7e09f0996 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.h +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.h | |||
| @@ -56,6 +56,7 @@ | |||
| 56 | #define put_ep(ep) { \ | 56 | #define put_ep(ep) { \ |
| 57 | PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \ | 57 | PDBG("put_ep (via %s:%u) ep %p refcnt %d\n", __func__, __LINE__, \ |
| 58 | ep, atomic_read(&((ep)->kref.refcount))); \ | 58 | ep, atomic_read(&((ep)->kref.refcount))); \ |
| 59 | WARN_ON(atomic_read(&((ep)->kref.refcount)) < 1); \ | ||
| 59 | kref_put(&((ep)->kref), __free_ep); \ | 60 | kref_put(&((ep)->kref), __free_ep); \ |
| 60 | } | 61 | } |
| 61 | 62 | ||
| @@ -225,5 +226,6 @@ int iwch_ep_redirect(void *ctx, struct dst_entry *old, struct dst_entry *new, st | |||
| 225 | 226 | ||
| 226 | int __init iwch_cm_init(void); | 227 | int __init iwch_cm_init(void); |
| 227 | void __exit iwch_cm_term(void); | 228 | void __exit iwch_cm_term(void); |
| 229 | extern int peer2peer; | ||
| 228 | 230 | ||
| 229 | #endif /* _IWCH_CM_H_ */ | 231 | #endif /* _IWCH_CM_H_ */ |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index e343e9e64844..d07d3a377b5f 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c | |||
| @@ -998,7 +998,7 @@ static int iwch_query_device(struct ib_device *ibdev, | |||
| 998 | props->device_cap_flags = dev->device_cap_flags; | 998 | props->device_cap_flags = dev->device_cap_flags; |
| 999 | props->vendor_id = (u32)dev->rdev.rnic_info.pdev->vendor; | 999 | props->vendor_id = (u32)dev->rdev.rnic_info.pdev->vendor; |
| 1000 | props->vendor_part_id = (u32)dev->rdev.rnic_info.pdev->device; | 1000 | props->vendor_part_id = (u32)dev->rdev.rnic_info.pdev->device; |
| 1001 | props->max_mr_size = ~0ull; | 1001 | props->max_mr_size = dev->attr.max_mr_size; |
| 1002 | props->max_qp = dev->attr.max_qps; | 1002 | props->max_qp = dev->attr.max_qps; |
| 1003 | props->max_qp_wr = dev->attr.max_wrs; | 1003 | props->max_qp_wr = dev->attr.max_wrs; |
| 1004 | props->max_sge = dev->attr.max_sge_per_wr; | 1004 | props->max_sge = dev->attr.max_sge_per_wr; |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.h b/drivers/infiniband/hw/cxgb3/iwch_provider.h index 61356f91109d..db5100d27ca2 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.h +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.h | |||
| @@ -118,6 +118,7 @@ enum IWCH_QP_FLAGS { | |||
| 118 | }; | 118 | }; |
| 119 | 119 | ||
| 120 | struct iwch_mpa_attributes { | 120 | struct iwch_mpa_attributes { |
| 121 | u8 initiator; | ||
| 121 | u8 recv_marker_enabled; | 122 | u8 recv_marker_enabled; |
| 122 | u8 xmit_marker_enabled; /* iWARP: enable inbound Read Resp. */ | 123 | u8 xmit_marker_enabled; /* iWARP: enable inbound Read Resp. */ |
| 123 | u8 crc_enabled; | 124 | u8 crc_enabled; |
| @@ -322,6 +323,7 @@ enum iwch_qp_query_flags { | |||
| 322 | IWCH_QP_QUERY_TEST_USERWRITE = 0x32 /* Test special */ | 323 | IWCH_QP_QUERY_TEST_USERWRITE = 0x32 /* Test special */ |
| 323 | }; | 324 | }; |
| 324 | 325 | ||
| 326 | u16 iwch_rqes_posted(struct iwch_qp *qhp); | ||
| 325 | int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | 327 | int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, |
| 326 | struct ib_send_wr **bad_wr); | 328 | struct ib_send_wr **bad_wr); |
| 327 | int iwch_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | 329 | int iwch_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, |
| @@ -331,6 +333,7 @@ int iwch_bind_mw(struct ib_qp *qp, | |||
| 331 | struct ib_mw_bind *mw_bind); | 333 | struct ib_mw_bind *mw_bind); |
| 332 | int iwch_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc); | 334 | int iwch_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc); |
| 333 | int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg); | 335 | int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg); |
| 336 | int iwch_post_zb_read(struct iwch_qp *qhp); | ||
| 334 | int iwch_register_device(struct iwch_dev *dev); | 337 | int iwch_register_device(struct iwch_dev *dev); |
| 335 | void iwch_unregister_device(struct iwch_dev *dev); | 338 | void iwch_unregister_device(struct iwch_dev *dev); |
| 336 | int iwch_quiesce_qps(struct iwch_cq *chp); | 339 | int iwch_quiesce_qps(struct iwch_cq *chp); |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index 8891c3b0a3d5..9b4be889c58e 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
| @@ -586,6 +586,36 @@ static inline void build_term_codes(struct respQ_msg_t *rsp_msg, | |||
| 586 | } | 586 | } |
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | int iwch_post_zb_read(struct iwch_qp *qhp) | ||
| 590 | { | ||
| 591 | union t3_wr *wqe; | ||
| 592 | struct sk_buff *skb; | ||
| 593 | u8 flit_cnt = sizeof(struct t3_rdma_read_wr) >> 3; | ||
| 594 | |||
| 595 | PDBG("%s enter\n", __func__); | ||
| 596 | skb = alloc_skb(40, GFP_KERNEL); | ||
| 597 | if (!skb) { | ||
| 598 | printk(KERN_ERR "%s cannot send zb_read!!\n", __func__); | ||
| 599 | return -ENOMEM; | ||
| 600 | } | ||
| 601 | wqe = (union t3_wr *)skb_put(skb, sizeof(struct t3_rdma_read_wr)); | ||
| 602 | memset(wqe, 0, sizeof(struct t3_rdma_read_wr)); | ||
| 603 | wqe->read.rdmaop = T3_READ_REQ; | ||
| 604 | wqe->read.reserved[0] = 0; | ||
| 605 | wqe->read.reserved[1] = 0; | ||
| 606 | wqe->read.reserved[2] = 0; | ||
| 607 | wqe->read.rem_stag = cpu_to_be32(1); | ||
| 608 | wqe->read.rem_to = cpu_to_be64(1); | ||
| 609 | wqe->read.local_stag = cpu_to_be32(1); | ||
| 610 | wqe->read.local_len = cpu_to_be32(0); | ||
| 611 | wqe->read.local_to = cpu_to_be64(1); | ||
| 612 | wqe->send.wrh.op_seop_flags = cpu_to_be32(V_FW_RIWR_OP(T3_WR_READ)); | ||
| 613 | wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)| | ||
| 614 | V_FW_RIWR_LEN(flit_cnt)); | ||
| 615 | skb->priority = CPL_PRIORITY_DATA; | ||
| 616 | return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb); | ||
| 617 | } | ||
| 618 | |||
| 589 | /* | 619 | /* |
| 590 | * This posts a TERMINATE with layer=RDMA, type=catastrophic. | 620 | * This posts a TERMINATE with layer=RDMA, type=catastrophic. |
| 591 | */ | 621 | */ |
| @@ -671,11 +701,18 @@ static void flush_qp(struct iwch_qp *qhp, unsigned long *flag) | |||
| 671 | 701 | ||
| 672 | 702 | ||
| 673 | /* | 703 | /* |
| 674 | * Return non zero if at least one RECV was pre-posted. | 704 | * Return count of RECV WRs posted |
| 675 | */ | 705 | */ |
| 676 | static int rqes_posted(struct iwch_qp *qhp) | 706 | u16 iwch_rqes_posted(struct iwch_qp *qhp) |
| 677 | { | 707 | { |
| 678 | return fw_riwrh_opcode((struct fw_riwrh *)qhp->wq.queue) == T3_WR_RCV; | 708 | union t3_wr *wqe = qhp->wq.queue; |
| 709 | u16 count = 0; | ||
| 710 | while ((count+1) != 0 && fw_riwrh_opcode((struct fw_riwrh *)wqe) == T3_WR_RCV) { | ||
| 711 | count++; | ||
| 712 | wqe++; | ||
| 713 | } | ||
| 714 | PDBG("%s qhp %p count %u\n", __func__, qhp, count); | ||
| 715 | return count; | ||
| 679 | } | 716 | } |
| 680 | 717 | ||
| 681 | static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp, | 718 | static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp, |
| @@ -716,8 +753,17 @@ static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp, | |||
| 716 | init_attr.ird = qhp->attr.max_ird; | 753 | init_attr.ird = qhp->attr.max_ird; |
| 717 | init_attr.qp_dma_addr = qhp->wq.dma_addr; | 754 | init_attr.qp_dma_addr = qhp->wq.dma_addr; |
| 718 | init_attr.qp_dma_size = (1UL << qhp->wq.size_log2); | 755 | init_attr.qp_dma_size = (1UL << qhp->wq.size_log2); |
| 719 | init_attr.flags = rqes_posted(qhp) ? RECVS_POSTED : 0; | 756 | init_attr.rqe_count = iwch_rqes_posted(qhp); |
| 757 | init_attr.flags = qhp->attr.mpa_attr.initiator ? MPA_INITIATOR : 0; | ||
| 720 | init_attr.flags |= capable(CAP_NET_BIND_SERVICE) ? PRIV_QP : 0; | 758 | init_attr.flags |= capable(CAP_NET_BIND_SERVICE) ? PRIV_QP : 0; |
| 759 | if (peer2peer) { | ||
| 760 | init_attr.rtr_type = RTR_READ; | ||
| 761 | if (init_attr.ord == 0 && qhp->attr.mpa_attr.initiator) | ||
| 762 | init_attr.ord = 1; | ||
| 763 | if (init_attr.ird == 0 && !qhp->attr.mpa_attr.initiator) | ||
| 764 | init_attr.ird = 1; | ||
| 765 | } else | ||
| 766 | init_attr.rtr_type = 0; | ||
| 721 | init_attr.irs = qhp->ep->rcv_seq; | 767 | init_attr.irs = qhp->ep->rcv_seq; |
| 722 | PDBG("%s init_attr.rq_addr 0x%x init_attr.rq_size = %d " | 768 | PDBG("%s init_attr.rq_addr 0x%x init_attr.rq_size = %d " |
| 723 | "flags 0x%x qpcaps 0x%x\n", __func__, | 769 | "flags 0x%x qpcaps 0x%x\n", __func__, |
| @@ -832,6 +878,7 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp, | |||
| 832 | abort=0; | 878 | abort=0; |
| 833 | disconnect = 1; | 879 | disconnect = 1; |
| 834 | ep = qhp->ep; | 880 | ep = qhp->ep; |
| 881 | get_ep(&ep->com); | ||
| 835 | } | 882 | } |
| 836 | flush_qp(qhp, &flag); | 883 | flush_qp(qhp, &flag); |
| 837 | break; | 884 | break; |
| @@ -848,6 +895,7 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp, | |||
| 848 | abort=1; | 895 | abort=1; |
| 849 | disconnect = 1; | 896 | disconnect = 1; |
| 850 | ep = qhp->ep; | 897 | ep = qhp->ep; |
| 898 | get_ep(&ep->com); | ||
| 851 | } | 899 | } |
| 852 | goto err; | 900 | goto err; |
| 853 | break; | 901 | break; |
| @@ -929,8 +977,10 @@ out: | |||
| 929 | * on the EP. This can be a normal close (RTS->CLOSING) or | 977 | * on the EP. This can be a normal close (RTS->CLOSING) or |
| 930 | * an abnormal close (RTS/CLOSING->ERROR). | 978 | * an abnormal close (RTS/CLOSING->ERROR). |
| 931 | */ | 979 | */ |
| 932 | if (disconnect) | 980 | if (disconnect) { |
| 933 | iwch_ep_disconnect(ep, abort, GFP_KERNEL); | 981 | iwch_ep_disconnect(ep, abort, GFP_KERNEL); |
| 982 | put_ep(&ep->com); | ||
| 983 | } | ||
| 934 | 984 | ||
| 935 | /* | 985 | /* |
| 936 | * If free is 1, then we've disassociated the EP from the QP | 986 | * If free is 1, then we've disassociated the EP from the QP |
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 3d6d9461c31d..00bab60f6de4 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h | |||
| @@ -66,6 +66,7 @@ struct ehca_av; | |||
| 66 | #include "ehca_irq.h" | 66 | #include "ehca_irq.h" |
| 67 | 67 | ||
| 68 | #define EHCA_EQE_CACHE_SIZE 20 | 68 | #define EHCA_EQE_CACHE_SIZE 20 |
| 69 | #define EHCA_MAX_NUM_QUEUES 0xffff | ||
| 69 | 70 | ||
| 70 | struct ehca_eqe_cache_entry { | 71 | struct ehca_eqe_cache_entry { |
| 71 | struct ehca_eqe *eqe; | 72 | struct ehca_eqe *eqe; |
| @@ -127,6 +128,8 @@ struct ehca_shca { | |||
| 127 | /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */ | 128 | /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */ |
| 128 | u32 hca_cap_mr_pgsize; | 129 | u32 hca_cap_mr_pgsize; |
| 129 | int max_mtu; | 130 | int max_mtu; |
| 131 | atomic_t num_cqs; | ||
| 132 | atomic_t num_qps; | ||
| 130 | }; | 133 | }; |
| 131 | 134 | ||
| 132 | struct ehca_pd { | 135 | struct ehca_pd { |
| @@ -344,6 +347,8 @@ extern int ehca_use_hp_mr; | |||
| 344 | extern int ehca_scaling_code; | 347 | extern int ehca_scaling_code; |
| 345 | extern int ehca_lock_hcalls; | 348 | extern int ehca_lock_hcalls; |
| 346 | extern int ehca_nr_ports; | 349 | extern int ehca_nr_ports; |
| 350 | extern int ehca_max_cq; | ||
| 351 | extern int ehca_max_qp; | ||
| 347 | 352 | ||
| 348 | struct ipzu_queue_resp { | 353 | struct ipzu_queue_resp { |
| 349 | u32 qe_size; /* queue entry size */ | 354 | u32 qe_size; /* queue entry size */ |
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index ec0cfcf3073f..5540b276a33c 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c | |||
| @@ -132,10 +132,19 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, | |||
| 132 | if (cqe >= 0xFFFFFFFF - 64 - additional_cqe) | 132 | if (cqe >= 0xFFFFFFFF - 64 - additional_cqe) |
| 133 | return ERR_PTR(-EINVAL); | 133 | return ERR_PTR(-EINVAL); |
| 134 | 134 | ||
| 135 | if (!atomic_add_unless(&shca->num_cqs, 1, ehca_max_cq)) { | ||
| 136 | ehca_err(device, "Unable to create CQ, max number of %i " | ||
| 137 | "CQs reached.", ehca_max_cq); | ||
| 138 | ehca_err(device, "To increase the maximum number of CQs " | ||
| 139 | "use the number_of_cqs module parameter.\n"); | ||
| 140 | return ERR_PTR(-ENOSPC); | ||
| 141 | } | ||
| 142 | |||
| 135 | my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL); | 143 | my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL); |
| 136 | if (!my_cq) { | 144 | if (!my_cq) { |
| 137 | ehca_err(device, "Out of memory for ehca_cq struct device=%p", | 145 | ehca_err(device, "Out of memory for ehca_cq struct device=%p", |
| 138 | device); | 146 | device); |
| 147 | atomic_dec(&shca->num_cqs); | ||
| 139 | return ERR_PTR(-ENOMEM); | 148 | return ERR_PTR(-ENOMEM); |
| 140 | } | 149 | } |
| 141 | 150 | ||
| @@ -305,6 +314,7 @@ create_cq_exit2: | |||
| 305 | create_cq_exit1: | 314 | create_cq_exit1: |
| 306 | kmem_cache_free(cq_cache, my_cq); | 315 | kmem_cache_free(cq_cache, my_cq); |
| 307 | 316 | ||
| 317 | atomic_dec(&shca->num_cqs); | ||
| 308 | return cq; | 318 | return cq; |
| 309 | } | 319 | } |
| 310 | 320 | ||
| @@ -359,6 +369,7 @@ int ehca_destroy_cq(struct ib_cq *cq) | |||
| 359 | ipz_queue_dtor(NULL, &my_cq->ipz_queue); | 369 | ipz_queue_dtor(NULL, &my_cq->ipz_queue); |
| 360 | kmem_cache_free(cq_cache, my_cq); | 370 | kmem_cache_free(cq_cache, my_cq); |
| 361 | 371 | ||
| 372 | atomic_dec(&shca->num_cqs); | ||
| 362 | return 0; | 373 | return 0; |
| 363 | } | 374 | } |
| 364 | 375 | ||
diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c index b4ac617a70e6..49660dfa1867 100644 --- a/drivers/infiniband/hw/ehca/ehca_eq.c +++ b/drivers/infiniband/hw/ehca/ehca_eq.c | |||
| @@ -54,7 +54,8 @@ int ehca_create_eq(struct ehca_shca *shca, | |||
| 54 | struct ehca_eq *eq, | 54 | struct ehca_eq *eq, |
| 55 | const enum ehca_eq_type type, const u32 length) | 55 | const enum ehca_eq_type type, const u32 length) |
| 56 | { | 56 | { |
| 57 | u64 ret; | 57 | int ret; |
| 58 | u64 h_ret; | ||
| 58 | u32 nr_pages; | 59 | u32 nr_pages; |
| 59 | u32 i; | 60 | u32 i; |
| 60 | void *vpage; | 61 | void *vpage; |
| @@ -73,15 +74,15 @@ int ehca_create_eq(struct ehca_shca *shca, | |||
| 73 | return -EINVAL; | 74 | return -EINVAL; |
| 74 | } | 75 | } |
| 75 | 76 | ||
| 76 | ret = hipz_h_alloc_resource_eq(shca->ipz_hca_handle, | 77 | h_ret = hipz_h_alloc_resource_eq(shca->ipz_hca_handle, |
| 77 | &eq->pf, | 78 | &eq->pf, |
| 78 | type, | 79 | type, |
| 79 | length, | 80 | length, |
| 80 | &eq->ipz_eq_handle, | 81 | &eq->ipz_eq_handle, |
| 81 | &eq->length, | 82 | &eq->length, |
| 82 | &nr_pages, &eq->ist); | 83 | &nr_pages, &eq->ist); |
| 83 | 84 | ||
| 84 | if (ret != H_SUCCESS) { | 85 | if (h_ret != H_SUCCESS) { |
| 85 | ehca_err(ib_dev, "Can't allocate EQ/NEQ. eq=%p", eq); | 86 | ehca_err(ib_dev, "Can't allocate EQ/NEQ. eq=%p", eq); |
| 86 | return -EINVAL; | 87 | return -EINVAL; |
| 87 | } | 88 | } |
| @@ -97,24 +98,22 @@ int ehca_create_eq(struct ehca_shca *shca, | |||
| 97 | u64 rpage; | 98 | u64 rpage; |
| 98 | 99 | ||
| 99 | vpage = ipz_qpageit_get_inc(&eq->ipz_queue); | 100 | vpage = ipz_qpageit_get_inc(&eq->ipz_queue); |
| 100 | if (!vpage) { | 101 | if (!vpage) |
| 101 | ret = H_RESOURCE; | ||
| 102 | goto create_eq_exit2; | 102 | goto create_eq_exit2; |
| 103 | } | ||
| 104 | 103 | ||
| 105 | rpage = virt_to_abs(vpage); | 104 | rpage = virt_to_abs(vpage); |
| 106 | ret = hipz_h_register_rpage_eq(shca->ipz_hca_handle, | 105 | h_ret = hipz_h_register_rpage_eq(shca->ipz_hca_handle, |
| 107 | eq->ipz_eq_handle, | 106 | eq->ipz_eq_handle, |
| 108 | &eq->pf, | 107 | &eq->pf, |
| 109 | 0, 0, rpage, 1); | 108 | 0, 0, rpage, 1); |
| 110 | 109 | ||
| 111 | if (i == (nr_pages - 1)) { | 110 | if (i == (nr_pages - 1)) { |
| 112 | /* last page */ | 111 | /* last page */ |
| 113 | vpage = ipz_qpageit_get_inc(&eq->ipz_queue); | 112 | vpage = ipz_qpageit_get_inc(&eq->ipz_queue); |
| 114 | if (ret != H_SUCCESS || vpage) | 113 | if (h_ret != H_SUCCESS || vpage) |
| 115 | goto create_eq_exit2; | 114 | goto create_eq_exit2; |
| 116 | } else { | 115 | } else { |
| 117 | if (ret != H_PAGE_REGISTERED || !vpage) | 116 | if (h_ret != H_PAGE_REGISTERED || !vpage) |
| 118 | goto create_eq_exit2; | 117 | goto create_eq_exit2; |
| 119 | } | 118 | } |
| 120 | } | 119 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 65048976198c..482103eb6eac 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
| @@ -68,6 +68,8 @@ int ehca_port_act_time = 30; | |||
| 68 | int ehca_static_rate = -1; | 68 | int ehca_static_rate = -1; |
| 69 | int ehca_scaling_code = 0; | 69 | int ehca_scaling_code = 0; |
| 70 | int ehca_lock_hcalls = -1; | 70 | int ehca_lock_hcalls = -1; |
| 71 | int ehca_max_cq = -1; | ||
| 72 | int ehca_max_qp = -1; | ||
| 71 | 73 | ||
| 72 | module_param_named(open_aqp1, ehca_open_aqp1, bool, S_IRUGO); | 74 | module_param_named(open_aqp1, ehca_open_aqp1, bool, S_IRUGO); |
| 73 | module_param_named(debug_level, ehca_debug_level, int, S_IRUGO); | 75 | module_param_named(debug_level, ehca_debug_level, int, S_IRUGO); |
| @@ -79,6 +81,8 @@ module_param_named(poll_all_eqs, ehca_poll_all_eqs, bool, S_IRUGO); | |||
| 79 | module_param_named(static_rate, ehca_static_rate, int, S_IRUGO); | 81 | module_param_named(static_rate, ehca_static_rate, int, S_IRUGO); |
| 80 | module_param_named(scaling_code, ehca_scaling_code, bool, S_IRUGO); | 82 | module_param_named(scaling_code, ehca_scaling_code, bool, S_IRUGO); |
| 81 | module_param_named(lock_hcalls, ehca_lock_hcalls, bool, S_IRUGO); | 83 | module_param_named(lock_hcalls, ehca_lock_hcalls, bool, S_IRUGO); |
| 84 | module_param_named(number_of_cqs, ehca_max_cq, int, S_IRUGO); | ||
| 85 | module_param_named(number_of_qps, ehca_max_qp, int, S_IRUGO); | ||
| 82 | 86 | ||
| 83 | MODULE_PARM_DESC(open_aqp1, | 87 | MODULE_PARM_DESC(open_aqp1, |
| 84 | "Open AQP1 on startup (default: no)"); | 88 | "Open AQP1 on startup (default: no)"); |
| @@ -104,6 +108,12 @@ MODULE_PARM_DESC(scaling_code, | |||
| 104 | MODULE_PARM_DESC(lock_hcalls, | 108 | MODULE_PARM_DESC(lock_hcalls, |
| 105 | "Serialize all hCalls made by the driver " | 109 | "Serialize all hCalls made by the driver " |
| 106 | "(default: autodetect)"); | 110 | "(default: autodetect)"); |
| 111 | MODULE_PARM_DESC(number_of_cqs, | ||
| 112 | "Max number of CQs which can be allocated " | ||
| 113 | "(default: autodetect)"); | ||
| 114 | MODULE_PARM_DESC(number_of_qps, | ||
| 115 | "Max number of QPs which can be allocated " | ||
| 116 | "(default: autodetect)"); | ||
| 107 | 117 | ||
| 108 | DEFINE_RWLOCK(ehca_qp_idr_lock); | 118 | DEFINE_RWLOCK(ehca_qp_idr_lock); |
| 109 | DEFINE_RWLOCK(ehca_cq_idr_lock); | 119 | DEFINE_RWLOCK(ehca_cq_idr_lock); |
| @@ -355,6 +365,25 @@ static int ehca_sense_attributes(struct ehca_shca *shca) | |||
| 355 | if (rblock->memory_page_size_supported & pgsize_map[i]) | 365 | if (rblock->memory_page_size_supported & pgsize_map[i]) |
| 356 | shca->hca_cap_mr_pgsize |= pgsize_map[i + 1]; | 366 | shca->hca_cap_mr_pgsize |= pgsize_map[i + 1]; |
| 357 | 367 | ||
| 368 | /* Set maximum number of CQs and QPs to calculate EQ size */ | ||
| 369 | if (ehca_max_qp == -1) | ||
| 370 | ehca_max_qp = min_t(int, rblock->max_qp, EHCA_MAX_NUM_QUEUES); | ||
| 371 | else if (ehca_max_qp < 1 || ehca_max_qp > rblock->max_qp) { | ||
| 372 | ehca_gen_err("Requested number of QPs is out of range (1 - %i) " | ||
| 373 | "specified by HW", rblock->max_qp); | ||
| 374 | ret = -EINVAL; | ||
| 375 | goto sense_attributes1; | ||
| 376 | } | ||
| 377 | |||
| 378 | if (ehca_max_cq == -1) | ||
| 379 | ehca_max_cq = min_t(int, rblock->max_cq, EHCA_MAX_NUM_QUEUES); | ||
| 380 | else if (ehca_max_cq < 1 || ehca_max_cq > rblock->max_cq) { | ||
| 381 | ehca_gen_err("Requested number of CQs is out of range (1 - %i) " | ||
| 382 | "specified by HW", rblock->max_cq); | ||
| 383 | ret = -EINVAL; | ||
| 384 | goto sense_attributes1; | ||
| 385 | } | ||
| 386 | |||
| 358 | /* query max MTU from first port -- it's the same for all ports */ | 387 | /* query max MTU from first port -- it's the same for all ports */ |
| 359 | port = (struct hipz_query_port *)rblock; | 388 | port = (struct hipz_query_port *)rblock; |
| 360 | h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); | 389 | h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); |
| @@ -684,7 +713,7 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
| 684 | struct ehca_shca *shca; | 713 | struct ehca_shca *shca; |
| 685 | const u64 *handle; | 714 | const u64 *handle; |
| 686 | struct ib_pd *ibpd; | 715 | struct ib_pd *ibpd; |
| 687 | int ret, i; | 716 | int ret, i, eq_size; |
| 688 | 717 | ||
| 689 | handle = of_get_property(dev->node, "ibm,hca-handle", NULL); | 718 | handle = of_get_property(dev->node, "ibm,hca-handle", NULL); |
| 690 | if (!handle) { | 719 | if (!handle) { |
| @@ -705,6 +734,8 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
| 705 | return -ENOMEM; | 734 | return -ENOMEM; |
| 706 | } | 735 | } |
| 707 | mutex_init(&shca->modify_mutex); | 736 | mutex_init(&shca->modify_mutex); |
| 737 | atomic_set(&shca->num_cqs, 0); | ||
| 738 | atomic_set(&shca->num_qps, 0); | ||
| 708 | for (i = 0; i < ARRAY_SIZE(shca->sport); i++) | 739 | for (i = 0; i < ARRAY_SIZE(shca->sport); i++) |
| 709 | spin_lock_init(&shca->sport[i].mod_sqp_lock); | 740 | spin_lock_init(&shca->sport[i].mod_sqp_lock); |
| 710 | 741 | ||
| @@ -724,8 +755,9 @@ static int __devinit ehca_probe(struct of_device *dev, | |||
| 724 | goto probe1; | 755 | goto probe1; |
| 725 | } | 756 | } |
| 726 | 757 | ||
| 758 | eq_size = 2 * ehca_max_cq + 4 * ehca_max_qp; | ||
| 727 | /* create event queues */ | 759 | /* create event queues */ |
| 728 | ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048); | 760 | ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size); |
| 729 | if (ret) { | 761 | if (ret) { |
| 730 | ehca_err(&shca->ib_device, "Cannot create EQ."); | 762 | ehca_err(&shca->ib_device, "Cannot create EQ."); |
| 731 | goto probe1; | 763 | goto probe1; |
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 57bef1152cc2..18fba92fa7ae 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
| @@ -421,8 +421,18 @@ static struct ehca_qp *internal_create_qp( | |||
| 421 | u32 swqe_size = 0, rwqe_size = 0, ib_qp_num; | 421 | u32 swqe_size = 0, rwqe_size = 0, ib_qp_num; |
| 422 | unsigned long flags; | 422 | unsigned long flags; |
| 423 | 423 | ||
| 424 | if (init_attr->create_flags) | 424 | if (!atomic_add_unless(&shca->num_qps, 1, ehca_max_qp)) { |
| 425 | ehca_err(pd->device, "Unable to create QP, max number of %i " | ||
| 426 | "QPs reached.", ehca_max_qp); | ||
| 427 | ehca_err(pd->device, "To increase the maximum number of QPs " | ||
| 428 | "use the number_of_qps module parameter.\n"); | ||
| 429 | return ERR_PTR(-ENOSPC); | ||
| 430 | } | ||
| 431 | |||
| 432 | if (init_attr->create_flags) { | ||
| 433 | atomic_dec(&shca->num_qps); | ||
| 425 | return ERR_PTR(-EINVAL); | 434 | return ERR_PTR(-EINVAL); |
| 435 | } | ||
| 426 | 436 | ||
| 427 | memset(&parms, 0, sizeof(parms)); | 437 | memset(&parms, 0, sizeof(parms)); |
| 428 | qp_type = init_attr->qp_type; | 438 | qp_type = init_attr->qp_type; |
| @@ -431,6 +441,7 @@ static struct ehca_qp *internal_create_qp( | |||
| 431 | init_attr->sq_sig_type != IB_SIGNAL_ALL_WR) { | 441 | init_attr->sq_sig_type != IB_SIGNAL_ALL_WR) { |
| 432 | ehca_err(pd->device, "init_attr->sg_sig_type=%x not allowed", | 442 | ehca_err(pd->device, "init_attr->sg_sig_type=%x not allowed", |
| 433 | init_attr->sq_sig_type); | 443 | init_attr->sq_sig_type); |
| 444 | atomic_dec(&shca->num_qps); | ||
| 434 | return ERR_PTR(-EINVAL); | 445 | return ERR_PTR(-EINVAL); |
| 435 | } | 446 | } |
| 436 | 447 | ||
| @@ -455,6 +466,7 @@ static struct ehca_qp *internal_create_qp( | |||
| 455 | 466 | ||
| 456 | if (is_llqp && has_srq) { | 467 | if (is_llqp && has_srq) { |
| 457 | ehca_err(pd->device, "LLQPs can't have an SRQ"); | 468 | ehca_err(pd->device, "LLQPs can't have an SRQ"); |
| 469 | atomic_dec(&shca->num_qps); | ||
| 458 | return ERR_PTR(-EINVAL); | 470 | return ERR_PTR(-EINVAL); |
| 459 | } | 471 | } |
| 460 | 472 | ||
| @@ -466,6 +478,7 @@ static struct ehca_qp *internal_create_qp( | |||
| 466 | ehca_err(pd->device, "no more than three SGEs " | 478 | ehca_err(pd->device, "no more than three SGEs " |
| 467 | "supported for SRQ pd=%p max_sge=%x", | 479 | "supported for SRQ pd=%p max_sge=%x", |
| 468 | pd, init_attr->cap.max_recv_sge); | 480 | pd, init_attr->cap.max_recv_sge); |
| 481 | atomic_dec(&shca->num_qps); | ||
| 469 | return ERR_PTR(-EINVAL); | 482 | return ERR_PTR(-EINVAL); |
| 470 | } | 483 | } |
| 471 | } | 484 | } |
| @@ -477,6 +490,7 @@ static struct ehca_qp *internal_create_qp( | |||
| 477 | qp_type != IB_QPT_SMI && | 490 | qp_type != IB_QPT_SMI && |
| 478 | qp_type != IB_QPT_GSI) { | 491 | qp_type != IB_QPT_GSI) { |
| 479 | ehca_err(pd->device, "wrong QP Type=%x", qp_type); | 492 | ehca_err(pd->device, "wrong QP Type=%x", qp_type); |
| 493 | atomic_dec(&shca->num_qps); | ||
| 480 | return ERR_PTR(-EINVAL); | 494 | return ERR_PTR(-EINVAL); |
| 481 | } | 495 | } |
| 482 | 496 | ||
| @@ -490,6 +504,7 @@ static struct ehca_qp *internal_create_qp( | |||
| 490 | "or max_rq_wr=%x for RC LLQP", | 504 | "or max_rq_wr=%x for RC LLQP", |
| 491 | init_attr->cap.max_send_wr, | 505 | init_attr->cap.max_send_wr, |
| 492 | init_attr->cap.max_recv_wr); | 506 | init_attr->cap.max_recv_wr); |
| 507 | atomic_dec(&shca->num_qps); | ||
| 493 | return ERR_PTR(-EINVAL); | 508 | return ERR_PTR(-EINVAL); |
| 494 | } | 509 | } |
| 495 | break; | 510 | break; |
| @@ -497,6 +512,7 @@ static struct ehca_qp *internal_create_qp( | |||
| 497 | if (!EHCA_BMASK_GET(HCA_CAP_UD_LL_QP, shca->hca_cap)) { | 512 | if (!EHCA_BMASK_GET(HCA_CAP_UD_LL_QP, shca->hca_cap)) { |
| 498 | ehca_err(pd->device, "UD LLQP not supported " | 513 | ehca_err(pd->device, "UD LLQP not supported " |
| 499 | "by this adapter"); | 514 | "by this adapter"); |
| 515 | atomic_dec(&shca->num_qps); | ||
| 500 | return ERR_PTR(-ENOSYS); | 516 | return ERR_PTR(-ENOSYS); |
| 501 | } | 517 | } |
| 502 | if (!(init_attr->cap.max_send_sge <= 5 | 518 | if (!(init_attr->cap.max_send_sge <= 5 |
| @@ -508,20 +524,22 @@ static struct ehca_qp *internal_create_qp( | |||
| 508 | "or max_recv_sge=%x for UD LLQP", | 524 | "or max_recv_sge=%x for UD LLQP", |
| 509 | init_attr->cap.max_send_sge, | 525 | init_attr->cap.max_send_sge, |
| 510 | init_attr->cap.max_recv_sge); | 526 | init_attr->cap.max_recv_sge); |
| 527 | atomic_dec(&shca->num_qps); | ||
| 511 | return ERR_PTR(-EINVAL); | 528 | return ERR_PTR(-EINVAL); |
| 512 | } else if (init_attr->cap.max_send_wr > 255) { | 529 | } else if (init_attr->cap.max_send_wr > 255) { |
| 513 | ehca_err(pd->device, | 530 | ehca_err(pd->device, |
| 514 | "Invalid Number of " | 531 | "Invalid Number of " |
| 515 | "max_send_wr=%x for UD QP_TYPE=%x", | 532 | "max_send_wr=%x for UD QP_TYPE=%x", |
| 516 | init_attr->cap.max_send_wr, qp_type); | 533 | init_attr->cap.max_send_wr, qp_type); |
| 534 | atomic_dec(&shca->num_qps); | ||
| 517 | return ERR_PTR(-EINVAL); | 535 | return ERR_PTR(-EINVAL); |
| 518 | } | 536 | } |
| 519 | break; | 537 | break; |
| 520 | default: | 538 | default: |
| 521 | ehca_err(pd->device, "unsupported LL QP Type=%x", | 539 | ehca_err(pd->device, "unsupported LL QP Type=%x", |
| 522 | qp_type); | 540 | qp_type); |
| 541 | atomic_dec(&shca->num_qps); | ||
| 523 | return ERR_PTR(-EINVAL); | 542 | return ERR_PTR(-EINVAL); |
| 524 | break; | ||
| 525 | } | 543 | } |
| 526 | } else { | 544 | } else { |
| 527 | int max_sge = (qp_type == IB_QPT_UD || qp_type == IB_QPT_SMI | 545 | int max_sge = (qp_type == IB_QPT_UD || qp_type == IB_QPT_SMI |
| @@ -533,6 +551,7 @@ static struct ehca_qp *internal_create_qp( | |||
| 533 | "send_sge=%x recv_sge=%x max_sge=%x", | 551 | "send_sge=%x recv_sge=%x max_sge=%x", |
| 534 | init_attr->cap.max_send_sge, | 552 | init_attr->cap.max_send_sge, |
| 535 | init_attr->cap.max_recv_sge, max_sge); | 553 | init_attr->cap.max_recv_sge, max_sge); |
| 554 | atomic_dec(&shca->num_qps); | ||
| 536 | return ERR_PTR(-EINVAL); | 555 | return ERR_PTR(-EINVAL); |
| 537 | } | 556 | } |
| 538 | } | 557 | } |
| @@ -543,6 +562,7 @@ static struct ehca_qp *internal_create_qp( | |||
| 543 | my_qp = kmem_cache_zalloc(qp_cache, GFP_KERNEL); | 562 | my_qp = kmem_cache_zalloc(qp_cache, GFP_KERNEL); |
| 544 | if (!my_qp) { | 563 | if (!my_qp) { |
| 545 | ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd); | 564 | ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd); |
| 565 | atomic_dec(&shca->num_qps); | ||
| 546 | return ERR_PTR(-ENOMEM); | 566 | return ERR_PTR(-ENOMEM); |
| 547 | } | 567 | } |
| 548 | 568 | ||
| @@ -823,6 +843,7 @@ create_qp_exit1: | |||
| 823 | 843 | ||
| 824 | create_qp_exit0: | 844 | create_qp_exit0: |
| 825 | kmem_cache_free(qp_cache, my_qp); | 845 | kmem_cache_free(qp_cache, my_qp); |
| 846 | atomic_dec(&shca->num_qps); | ||
| 826 | return ERR_PTR(ret); | 847 | return ERR_PTR(ret); |
| 827 | } | 848 | } |
| 828 | 849 | ||
| @@ -1948,6 +1969,7 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, | |||
| 1948 | if (HAS_SQ(my_qp)) | 1969 | if (HAS_SQ(my_qp)) |
| 1949 | ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); | 1970 | ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); |
| 1950 | kmem_cache_free(qp_cache, my_qp); | 1971 | kmem_cache_free(qp_cache, my_qp); |
| 1972 | atomic_dec(&shca->num_qps); | ||
| 1951 | return 0; | 1973 | return 0; |
| 1952 | } | 1974 | } |
| 1953 | 1975 | ||
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index e3dddfc687f9..2f199c5c4a72 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c | |||
| @@ -221,7 +221,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector | |||
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | err = mlx4_cq_alloc(dev->dev, entries, &cq->buf.mtt, uar, | 223 | err = mlx4_cq_alloc(dev->dev, entries, &cq->buf.mtt, uar, |
| 224 | cq->db.dma, &cq->mcq); | 224 | cq->db.dma, &cq->mcq, 0); |
| 225 | if (err) | 225 | if (err) |
| 226 | goto err_dbmap; | 226 | goto err_dbmap; |
| 227 | 227 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c index 3538da16e3fe..820205dec560 100644 --- a/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/drivers/infiniband/hw/mthca/mthca_mr.c | |||
| @@ -818,15 +818,9 @@ int mthca_arbel_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list, | |||
| 818 | 818 | ||
| 819 | void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) | 819 | void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) |
| 820 | { | 820 | { |
| 821 | u32 key; | ||
| 822 | |||
| 823 | if (!fmr->maps) | 821 | if (!fmr->maps) |
| 824 | return; | 822 | return; |
| 825 | 823 | ||
| 826 | key = tavor_key_to_hw_index(fmr->ibmr.lkey); | ||
| 827 | key &= dev->limits.num_mpts - 1; | ||
| 828 | fmr->ibmr.lkey = fmr->ibmr.rkey = tavor_hw_index_to_key(key); | ||
| 829 | |||
| 830 | fmr->maps = 0; | 824 | fmr->maps = 0; |
| 831 | 825 | ||
| 832 | writeb(MTHCA_MPT_STATUS_SW, fmr->mem.tavor.mpt); | 826 | writeb(MTHCA_MPT_STATUS_SW, fmr->mem.tavor.mpt); |
| @@ -834,16 +828,9 @@ void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) | |||
| 834 | 828 | ||
| 835 | void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) | 829 | void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) |
| 836 | { | 830 | { |
| 837 | u32 key; | ||
| 838 | |||
| 839 | if (!fmr->maps) | 831 | if (!fmr->maps) |
| 840 | return; | 832 | return; |
| 841 | 833 | ||
| 842 | key = arbel_key_to_hw_index(fmr->ibmr.lkey); | ||
| 843 | key &= dev->limits.num_mpts - 1; | ||
| 844 | key = adjust_key(dev, key); | ||
| 845 | fmr->ibmr.lkey = fmr->ibmr.rkey = arbel_hw_index_to_key(key); | ||
| 846 | |||
| 847 | fmr->maps = 0; | 834 | fmr->maps = 0; |
| 848 | 835 | ||
| 849 | *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_SW; | 836 | *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_SW; |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 2a9f460cf061..be34f99ca625 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c | |||
| @@ -39,6 +39,8 @@ | |||
| 39 | #include <rdma/ib_smi.h> | 39 | #include <rdma/ib_smi.h> |
| 40 | #include <rdma/ib_umem.h> | 40 | #include <rdma/ib_umem.h> |
| 41 | #include <rdma/ib_user_verbs.h> | 41 | #include <rdma/ib_user_verbs.h> |
| 42 | |||
| 43 | #include <linux/sched.h> | ||
| 42 | #include <linux/mm.h> | 44 | #include <linux/mm.h> |
| 43 | 45 | ||
| 44 | #include "mthca_dev.h" | 46 | #include "mthca_dev.h" |
| @@ -367,6 +369,8 @@ static struct ib_ucontext *mthca_alloc_ucontext(struct ib_device *ibdev, | |||
| 367 | return ERR_PTR(-EFAULT); | 369 | return ERR_PTR(-EFAULT); |
| 368 | } | 370 | } |
| 369 | 371 | ||
| 372 | context->reg_mr_warned = 0; | ||
| 373 | |||
| 370 | return &context->ibucontext; | 374 | return &context->ibucontext; |
| 371 | } | 375 | } |
| 372 | 376 | ||
| @@ -1013,7 +1017,15 @@ static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
| 1013 | int err = 0; | 1017 | int err = 0; |
| 1014 | int write_mtt_size; | 1018 | int write_mtt_size; |
| 1015 | 1019 | ||
| 1016 | if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) | 1020 | if (udata->inlen - sizeof (struct ib_uverbs_cmd_hdr) < sizeof ucmd) { |
| 1021 | if (!to_mucontext(pd->uobject->context)->reg_mr_warned) { | ||
| 1022 | mthca_warn(dev, "Process '%s' did not pass in MR attrs.\n", | ||
| 1023 | current->comm); | ||
| 1024 | mthca_warn(dev, " Update libmthca to fix this.\n"); | ||
| 1025 | } | ||
| 1026 | ++to_mucontext(pd->uobject->context)->reg_mr_warned; | ||
| 1027 | ucmd.mr_attrs = 0; | ||
| 1028 | } else if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) | ||
| 1017 | return ERR_PTR(-EFAULT); | 1029 | return ERR_PTR(-EFAULT); |
| 1018 | 1030 | ||
| 1019 | mr = kmalloc(sizeof *mr, GFP_KERNEL); | 1031 | mr = kmalloc(sizeof *mr, GFP_KERNEL); |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h index 262616c8ebb6..934bf9544037 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.h +++ b/drivers/infiniband/hw/mthca/mthca_provider.h | |||
| @@ -67,6 +67,7 @@ struct mthca_ucontext { | |||
| 67 | struct ib_ucontext ibucontext; | 67 | struct ib_ucontext ibucontext; |
| 68 | struct mthca_uar uar; | 68 | struct mthca_uar uar; |
| 69 | struct mthca_user_db_table *db_tab; | 69 | struct mthca_user_db_table *db_tab; |
| 70 | int reg_mr_warned; | ||
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 72 | struct mthca_mtt; | 73 | struct mthca_mtt; |
diff --git a/drivers/infiniband/hw/mthca/mthca_user.h b/drivers/infiniband/hw/mthca/mthca_user.h index f8cb3b664d37..e1262c942db8 100644 --- a/drivers/infiniband/hw/mthca/mthca_user.h +++ b/drivers/infiniband/hw/mthca/mthca_user.h | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | * Increment this value if any changes that break userspace ABI | 41 | * Increment this value if any changes that break userspace ABI |
| 42 | * compatibility are made. | 42 | * compatibility are made. |
| 43 | */ | 43 | */ |
| 44 | #define MTHCA_UVERBS_ABI_VERSION 2 | 44 | #define MTHCA_UVERBS_ABI_VERSION 1 |
| 45 | 45 | ||
| 46 | /* | 46 | /* |
| 47 | * Make sure that all structs defined in this file remain laid out so | 47 | * Make sure that all structs defined in this file remain laid out so |
| @@ -62,10 +62,12 @@ struct mthca_alloc_pd_resp { | |||
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | struct mthca_reg_mr { | 64 | struct mthca_reg_mr { |
| 65 | /* | ||
| 66 | * Mark the memory region with a DMA attribute that causes | ||
| 67 | * in-flight DMA to be flushed when the region is written to: | ||
| 68 | */ | ||
| 69 | #define MTHCA_MR_DMASYNC 0x1 | ||
| 65 | __u32 mr_attrs; | 70 | __u32 mr_attrs; |
| 66 | #define MTHCA_MR_DMASYNC 0x1 | ||
| 67 | /* mark the memory region with a DMA attribute that causes | ||
| 68 | * in-flight DMA to be flushed when the region is written to */ | ||
| 69 | __u32 reserved; | 71 | __u32 reserved; |
| 70 | }; | 72 | }; |
| 71 | 73 | ||
diff --git a/drivers/infiniband/hw/nes/Kconfig b/drivers/infiniband/hw/nes/Kconfig index 2aeb7ac972a9..d449eb6ec78e 100644 --- a/drivers/infiniband/hw/nes/Kconfig +++ b/drivers/infiniband/hw/nes/Kconfig | |||
| @@ -2,6 +2,7 @@ config INFINIBAND_NES | |||
| 2 | tristate "NetEffect RNIC Driver" | 2 | tristate "NetEffect RNIC Driver" |
| 3 | depends on PCI && INET && INFINIBAND | 3 | depends on PCI && INET && INFINIBAND |
| 4 | select LIBCRC32C | 4 | select LIBCRC32C |
| 5 | select INET_LRO | ||
| 5 | ---help--- | 6 | ---help--- |
| 6 | This is a low-level driver for NetEffect RDMA enabled | 7 | This is a low-level driver for NetEffect RDMA enabled |
| 7 | Network Interface Cards (RNIC). | 8 | Network Interface Cards (RNIC). |
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index a4e9269a29bd..9f7364a9096d 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c | |||
| @@ -91,6 +91,10 @@ unsigned int nes_debug_level = 0; | |||
| 91 | module_param_named(debug_level, nes_debug_level, uint, 0644); | 91 | module_param_named(debug_level, nes_debug_level, uint, 0644); |
| 92 | MODULE_PARM_DESC(debug_level, "Enable debug output level"); | 92 | MODULE_PARM_DESC(debug_level, "Enable debug output level"); |
| 93 | 93 | ||
| 94 | unsigned int nes_lro_max_aggr = NES_LRO_MAX_AGGR; | ||
| 95 | module_param(nes_lro_max_aggr, int, NES_LRO_MAX_AGGR); | ||
| 96 | MODULE_PARM_DESC(nes_mro_max_aggr, " nic LRO MAX packet aggregation"); | ||
| 97 | |||
| 94 | LIST_HEAD(nes_adapter_list); | 98 | LIST_HEAD(nes_adapter_list); |
| 95 | static LIST_HEAD(nes_dev_list); | 99 | static LIST_HEAD(nes_dev_list); |
| 96 | 100 | ||
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index cdf2e9ad62f7..1f9f7bf73862 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h | |||
| @@ -173,6 +173,7 @@ extern int disable_mpa_crc; | |||
| 173 | extern unsigned int send_first; | 173 | extern unsigned int send_first; |
| 174 | extern unsigned int nes_drv_opt; | 174 | extern unsigned int nes_drv_opt; |
| 175 | extern unsigned int nes_debug_level; | 175 | extern unsigned int nes_debug_level; |
| 176 | extern unsigned int nes_lro_max_aggr; | ||
| 176 | 177 | ||
| 177 | extern struct list_head nes_adapter_list; | 178 | extern struct list_head nes_adapter_list; |
| 178 | 179 | ||
| @@ -535,8 +536,8 @@ int nes_register_ofa_device(struct nes_ib_device *); | |||
| 535 | int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *); | 536 | int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *); |
| 536 | void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16); | 537 | void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16); |
| 537 | void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *); | 538 | void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *); |
| 538 | void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16); | 539 | void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16, u16); |
| 539 | void nes_read_10G_phy_reg(struct nes_device *, u16, u8); | 540 | void nes_read_10G_phy_reg(struct nes_device *, u8, u8, u16); |
| 540 | struct nes_cqp_request *nes_get_cqp_request(struct nes_device *); | 541 | struct nes_cqp_request *nes_get_cqp_request(struct nes_device *); |
| 541 | void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int); | 542 | void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int); |
| 542 | int nes_arp_table(struct nes_device *, u32, u8 *, u32); | 543 | int nes_arp_table(struct nes_device *, u32, u8 *, u32); |
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index d940fc27129a..9a4b40fae40d 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
| @@ -594,7 +594,7 @@ static void nes_cm_timer_tick(unsigned long pass) | |||
| 594 | continue; | 594 | continue; |
| 595 | } | 595 | } |
| 596 | /* this seems like the correct place, but leave send entry unprotected */ | 596 | /* this seems like the correct place, but leave send entry unprotected */ |
| 597 | // spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); | 597 | /* spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); */ |
| 598 | atomic_inc(&send_entry->skb->users); | 598 | atomic_inc(&send_entry->skb->users); |
| 599 | cm_packets_retrans++; | 599 | cm_packets_retrans++; |
| 600 | nes_debug(NES_DBG_CM, "Retransmitting send_entry %p for node %p," | 600 | nes_debug(NES_DBG_CM, "Retransmitting send_entry %p for node %p," |
| @@ -1335,7 +1335,7 @@ static int process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
| 1335 | cm_node->loc_addr, cm_node->loc_port, | 1335 | cm_node->loc_addr, cm_node->loc_port, |
| 1336 | cm_node->rem_addr, cm_node->rem_port, | 1336 | cm_node->rem_addr, cm_node->rem_port, |
| 1337 | cm_node->state, atomic_read(&cm_node->ref_count)); | 1337 | cm_node->state, atomic_read(&cm_node->ref_count)); |
| 1338 | // create event | 1338 | /* create event */ |
| 1339 | cm_node->state = NES_CM_STATE_CLOSED; | 1339 | cm_node->state = NES_CM_STATE_CLOSED; |
| 1340 | 1340 | ||
| 1341 | create_event(cm_node, NES_CM_EVENT_ABORTED); | 1341 | create_event(cm_node, NES_CM_EVENT_ABORTED); |
| @@ -1669,7 +1669,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, | |||
| 1669 | if (!cm_node) | 1669 | if (!cm_node) |
| 1670 | return NULL; | 1670 | return NULL; |
| 1671 | 1671 | ||
| 1672 | // set our node side to client (active) side | 1672 | /* set our node side to client (active) side */ |
| 1673 | cm_node->tcp_cntxt.client = 1; | 1673 | cm_node->tcp_cntxt.client = 1; |
| 1674 | cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE; | 1674 | cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE; |
| 1675 | 1675 | ||
| @@ -1694,7 +1694,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, | |||
| 1694 | loopbackremotenode->mpa_frame_size = mpa_frame_size - | 1694 | loopbackremotenode->mpa_frame_size = mpa_frame_size - |
| 1695 | sizeof(struct ietf_mpa_frame); | 1695 | sizeof(struct ietf_mpa_frame); |
| 1696 | 1696 | ||
| 1697 | // we are done handling this state, set node to a TSA state | 1697 | /* we are done handling this state, set node to a TSA state */ |
| 1698 | cm_node->state = NES_CM_STATE_TSA; | 1698 | cm_node->state = NES_CM_STATE_TSA; |
| 1699 | cm_node->tcp_cntxt.rcv_nxt = loopbackremotenode->tcp_cntxt.loc_seq_num; | 1699 | cm_node->tcp_cntxt.rcv_nxt = loopbackremotenode->tcp_cntxt.loc_seq_num; |
| 1700 | loopbackremotenode->tcp_cntxt.rcv_nxt = cm_node->tcp_cntxt.loc_seq_num; | 1700 | loopbackremotenode->tcp_cntxt.rcv_nxt = cm_node->tcp_cntxt.loc_seq_num; |
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 08964cc7e98a..8dc70f9bad2f 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/ip.h> | 38 | #include <linux/ip.h> |
| 39 | #include <linux/tcp.h> | 39 | #include <linux/tcp.h> |
| 40 | #include <linux/if_vlan.h> | 40 | #include <linux/if_vlan.h> |
| 41 | #include <linux/inet_lro.h> | ||
| 41 | 42 | ||
| 42 | #include "nes.h" | 43 | #include "nes.h" |
| 43 | 44 | ||
| @@ -832,7 +833,7 @@ static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_cou | |||
| 832 | nes_write_indexed(nesdev, 0x00000900, 0x20000001); | 833 | nes_write_indexed(nesdev, 0x00000900, 0x20000001); |
| 833 | nes_write_indexed(nesdev, 0x000060C0, 0x0000028e); | 834 | nes_write_indexed(nesdev, 0x000060C0, 0x0000028e); |
| 834 | nes_write_indexed(nesdev, 0x000060C8, 0x00000020); | 835 | nes_write_indexed(nesdev, 0x000060C8, 0x00000020); |
| 835 | // | 836 | |
| 836 | nes_write_indexed(nesdev, 0x000001EC, 0x7b2625a0); | 837 | nes_write_indexed(nesdev, 0x000001EC, 0x7b2625a0); |
| 837 | /* nes_write_indexed(nesdev, 0x000001EC, 0x5f2625a0); */ | 838 | /* nes_write_indexed(nesdev, 0x000001EC, 0x5f2625a0); */ |
| 838 | 839 | ||
| @@ -1207,11 +1208,16 @@ int nes_init_phy(struct nes_device *nesdev) | |||
| 1207 | { | 1208 | { |
| 1208 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1209 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
| 1209 | u32 counter = 0; | 1210 | u32 counter = 0; |
| 1211 | u32 sds_common_control0; | ||
| 1210 | u32 mac_index = nesdev->mac_index; | 1212 | u32 mac_index = nesdev->mac_index; |
| 1211 | u32 tx_config; | 1213 | u32 tx_config = 0; |
| 1212 | u16 phy_data; | 1214 | u16 phy_data; |
| 1215 | u32 temp_phy_data = 0; | ||
| 1216 | u32 temp_phy_data2 = 0; | ||
| 1217 | u32 i = 0; | ||
| 1213 | 1218 | ||
| 1214 | if (nesadapter->OneG_Mode) { | 1219 | if ((nesadapter->OneG_Mode) && |
| 1220 | (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) { | ||
| 1215 | nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); | 1221 | nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); |
| 1216 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) { | 1222 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) { |
| 1217 | printk(PFX "%s: Programming mdc config for 1G\n", __func__); | 1223 | printk(PFX "%s: Programming mdc config for 1G\n", __func__); |
| @@ -1223,7 +1229,7 @@ int nes_init_phy(struct nes_device *nesdev) | |||
| 1223 | nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data); | 1229 | nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data); |
| 1224 | nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n", | 1230 | nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n", |
| 1225 | nesadapter->phy_index[mac_index], phy_data); | 1231 | nesadapter->phy_index[mac_index], phy_data); |
| 1226 | nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000); | 1232 | nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000); |
| 1227 | 1233 | ||
| 1228 | /* Reset the PHY */ | 1234 | /* Reset the PHY */ |
| 1229 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000); | 1235 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000); |
| @@ -1277,12 +1283,126 @@ int nes_init_phy(struct nes_device *nesdev) | |||
| 1277 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); | 1283 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); |
| 1278 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300); | 1284 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300); |
| 1279 | } else { | 1285 | } else { |
| 1280 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) { | 1286 | if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) || |
| 1287 | (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) { | ||
| 1281 | /* setup 10G MDIO operation */ | 1288 | /* setup 10G MDIO operation */ |
| 1282 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); | 1289 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); |
| 1283 | tx_config |= 0x14; | 1290 | tx_config |= 0x14; |
| 1284 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); | 1291 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); |
| 1285 | } | 1292 | } |
| 1293 | if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) { | ||
| 1294 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
| 1295 | |||
| 1296 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
| 1297 | mdelay(10); | ||
| 1298 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
| 1299 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
| 1300 | |||
| 1301 | /* | ||
| 1302 | * if firmware is already running (like from a | ||
| 1303 | * driver un-load/load, don't do anything. | ||
| 1304 | */ | ||
| 1305 | if (temp_phy_data == temp_phy_data2) { | ||
| 1306 | /* configure QT2505 AMCC PHY */ | ||
| 1307 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0x0000, 0x8000); | ||
| 1308 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0000); | ||
| 1309 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc302, 0x0044); | ||
| 1310 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc318, 0x0052); | ||
| 1311 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008); | ||
| 1312 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098); | ||
| 1313 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00); | ||
| 1314 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0000); | ||
| 1315 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528); | ||
| 1316 | |||
| 1317 | /* | ||
| 1318 | * remove micro from reset; chip boots from ROM, | ||
| 1319 | * uploads EEPROM f/w image, uC executes f/w | ||
| 1320 | */ | ||
| 1321 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0002); | ||
| 1322 | |||
| 1323 | /* | ||
| 1324 | * wait for heart beat to start to | ||
| 1325 | * know loading is done | ||
| 1326 | */ | ||
| 1327 | counter = 0; | ||
| 1328 | do { | ||
| 1329 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
| 1330 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
| 1331 | if (counter++ > 1000) { | ||
| 1332 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n"); | ||
| 1333 | break; | ||
| 1334 | } | ||
| 1335 | mdelay(100); | ||
| 1336 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
| 1337 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
| 1338 | } while ((temp_phy_data2 == temp_phy_data)); | ||
| 1339 | |||
| 1340 | /* | ||
| 1341 | * wait for tracking to start to know | ||
| 1342 | * f/w is good to go | ||
| 1343 | */ | ||
| 1344 | counter = 0; | ||
| 1345 | do { | ||
| 1346 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7fd); | ||
| 1347 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
| 1348 | if (counter++ > 1000) { | ||
| 1349 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from status check <this is bad!!!> \n"); | ||
| 1350 | break; | ||
| 1351 | } | ||
| 1352 | mdelay(1000); | ||
| 1353 | /* | ||
| 1354 | * nes_debug(NES_DBG_PHY, "AMCC PHY- phy_status not ready yet = 0x%02X\n", | ||
| 1355 | * temp_phy_data); | ||
| 1356 | */ | ||
| 1357 | } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70)); | ||
| 1358 | |||
| 1359 | /* set LOS Control invert RXLOSB_I_PADINV */ | ||
| 1360 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd003, 0x0000); | ||
| 1361 | /* set LOS Control to mask of RXLOSB_I */ | ||
| 1362 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc314, 0x0042); | ||
| 1363 | /* set LED1 to input mode (LED1 and LED2 share same LED) */ | ||
| 1364 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd006, 0x0007); | ||
| 1365 | /* set LED2 to RX link_status and activity */ | ||
| 1366 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd007, 0x000A); | ||
| 1367 | /* set LED3 to RX link_status */ | ||
| 1368 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd008, 0x0009); | ||
| 1369 | |||
| 1370 | /* | ||
| 1371 | * reset the res-calibration on t2 | ||
| 1372 | * serdes; ensures it is stable after | ||
| 1373 | * the amcc phy is stable | ||
| 1374 | */ | ||
| 1375 | |||
| 1376 | sds_common_control0 = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0); | ||
| 1377 | sds_common_control0 |= 0x1; | ||
| 1378 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0); | ||
| 1379 | |||
| 1380 | /* release the res-calibration reset */ | ||
| 1381 | sds_common_control0 &= 0xfffffffe; | ||
| 1382 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0); | ||
| 1383 | |||
| 1384 | i = 0; | ||
| 1385 | while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040) | ||
| 1386 | && (i++ < 5000)) { | ||
| 1387 | /* mdelay(1); */ | ||
| 1388 | } | ||
| 1389 | |||
| 1390 | /* | ||
| 1391 | * wait for link train done before moving on, | ||
| 1392 | * or will get an interupt storm | ||
| 1393 | */ | ||
| 1394 | counter = 0; | ||
| 1395 | do { | ||
| 1396 | temp_phy_data = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | ||
| 1397 | (0x200 * (nesdev->mac_index & 1))); | ||
| 1398 | if (counter++ > 1000) { | ||
| 1399 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from link train wait <this is bad, link didnt train!!!>\n"); | ||
| 1400 | break; | ||
| 1401 | } | ||
| 1402 | mdelay(1); | ||
| 1403 | } while (((temp_phy_data & 0x0f1f0000) != 0x0f0f0000)); | ||
| 1404 | } | ||
| 1405 | } | ||
| 1286 | } | 1406 | } |
| 1287 | return 0; | 1407 | return 0; |
| 1288 | } | 1408 | } |
| @@ -1375,6 +1495,25 @@ static void nes_rq_wqes_timeout(unsigned long parm) | |||
| 1375 | } | 1495 | } |
| 1376 | 1496 | ||
| 1377 | 1497 | ||
| 1498 | static int nes_lro_get_skb_hdr(struct sk_buff *skb, void **iphdr, | ||
| 1499 | void **tcph, u64 *hdr_flags, void *priv) | ||
| 1500 | { | ||
| 1501 | unsigned int ip_len; | ||
| 1502 | struct iphdr *iph; | ||
| 1503 | skb_reset_network_header(skb); | ||
| 1504 | iph = ip_hdr(skb); | ||
| 1505 | if (iph->protocol != IPPROTO_TCP) | ||
| 1506 | return -1; | ||
| 1507 | ip_len = ip_hdrlen(skb); | ||
| 1508 | skb_set_transport_header(skb, ip_len); | ||
| 1509 | *tcph = tcp_hdr(skb); | ||
| 1510 | |||
| 1511 | *hdr_flags = LRO_IPV4 | LRO_TCP; | ||
| 1512 | *iphdr = iph; | ||
| 1513 | return 0; | ||
| 1514 | } | ||
| 1515 | |||
| 1516 | |||
| 1378 | /** | 1517 | /** |
| 1379 | * nes_init_nic_qp | 1518 | * nes_init_nic_qp |
| 1380 | */ | 1519 | */ |
| @@ -1520,10 +1659,10 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev) | |||
| 1520 | } | 1659 | } |
| 1521 | 1660 | ||
| 1522 | u64temp = (u64)nesvnic->nic.sq_pbase; | 1661 | u64temp = (u64)nesvnic->nic.sq_pbase; |
| 1523 | nic_context->context_words[NES_NIC_CTX_SQ_LOW_IDX] = cpu_to_le32((u32)u64temp); | 1662 | nic_context->context_words[NES_NIC_CTX_SQ_LOW_IDX] = cpu_to_le32((u32)u64temp); |
| 1524 | nic_context->context_words[NES_NIC_CTX_SQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32)); | 1663 | nic_context->context_words[NES_NIC_CTX_SQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32)); |
| 1525 | u64temp = (u64)nesvnic->nic.rq_pbase; | 1664 | u64temp = (u64)nesvnic->nic.rq_pbase; |
| 1526 | nic_context->context_words[NES_NIC_CTX_RQ_LOW_IDX] = cpu_to_le32((u32)u64temp); | 1665 | nic_context->context_words[NES_NIC_CTX_RQ_LOW_IDX] = cpu_to_le32((u32)u64temp); |
| 1527 | nic_context->context_words[NES_NIC_CTX_RQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32)); | 1666 | nic_context->context_words[NES_NIC_CTX_RQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32)); |
| 1528 | 1667 | ||
| 1529 | cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_CREATE_QP | | 1668 | cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_CREATE_QP | |
| @@ -1575,7 +1714,7 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev) | |||
| 1575 | nic_rqe = &nesvnic->nic.rq_vbase[counter]; | 1714 | nic_rqe = &nesvnic->nic.rq_vbase[counter]; |
| 1576 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_1_0_IDX] = cpu_to_le32(nesvnic->max_frame_size); | 1715 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_1_0_IDX] = cpu_to_le32(nesvnic->max_frame_size); |
| 1577 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_3_2_IDX] = 0; | 1716 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_3_2_IDX] = 0; |
| 1578 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX] = cpu_to_le32((u32)pmem); | 1717 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX] = cpu_to_le32((u32)pmem); |
| 1579 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX] = cpu_to_le32((u32)((u64)pmem >> 32)); | 1718 | nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX] = cpu_to_le32((u32)((u64)pmem >> 32)); |
| 1580 | nesvnic->nic.rx_skb[counter] = skb; | 1719 | nesvnic->nic.rx_skb[counter] = skb; |
| 1581 | } | 1720 | } |
| @@ -1592,15 +1731,21 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev) | |||
| 1592 | nesvnic->rq_wqes_timer.function = nes_rq_wqes_timeout; | 1731 | nesvnic->rq_wqes_timer.function = nes_rq_wqes_timeout; |
| 1593 | nesvnic->rq_wqes_timer.data = (unsigned long)nesvnic; | 1732 | nesvnic->rq_wqes_timer.data = (unsigned long)nesvnic; |
| 1594 | nes_debug(NES_DBG_INIT, "NAPI support Enabled\n"); | 1733 | nes_debug(NES_DBG_INIT, "NAPI support Enabled\n"); |
| 1595 | |||
| 1596 | if (nesdev->nesadapter->et_use_adaptive_rx_coalesce) | 1734 | if (nesdev->nesadapter->et_use_adaptive_rx_coalesce) |
| 1597 | { | 1735 | { |
| 1598 | nes_nic_init_timer(nesdev); | 1736 | nes_nic_init_timer(nesdev); |
| 1599 | if (netdev->mtu > 1500) | 1737 | if (netdev->mtu > 1500) |
| 1600 | jumbomode = 1; | 1738 | jumbomode = 1; |
| 1601 | nes_nic_init_timer_defaults(nesdev, jumbomode); | 1739 | nes_nic_init_timer_defaults(nesdev, jumbomode); |
| 1602 | } | 1740 | } |
| 1603 | 1741 | nesvnic->lro_mgr.max_aggr = NES_LRO_MAX_AGGR; | |
| 1742 | nesvnic->lro_mgr.max_desc = NES_MAX_LRO_DESCRIPTORS; | ||
| 1743 | nesvnic->lro_mgr.lro_arr = nesvnic->lro_desc; | ||
| 1744 | nesvnic->lro_mgr.get_skb_header = nes_lro_get_skb_hdr; | ||
| 1745 | nesvnic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID; | ||
| 1746 | nesvnic->lro_mgr.dev = netdev; | ||
| 1747 | nesvnic->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY; | ||
| 1748 | nesvnic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY; | ||
| 1604 | return 0; | 1749 | return 0; |
| 1605 | } | 1750 | } |
| 1606 | 1751 | ||
| @@ -1620,8 +1765,8 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic) | |||
| 1620 | 1765 | ||
| 1621 | /* Free remaining NIC receive buffers */ | 1766 | /* Free remaining NIC receive buffers */ |
| 1622 | while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { | 1767 | while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { |
| 1623 | nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; | 1768 | nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; |
| 1624 | wqe_frag = (u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]); | 1769 | wqe_frag = (u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]); |
| 1625 | wqe_frag |= ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32; | 1770 | wqe_frag |= ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32; |
| 1626 | pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag, | 1771 | pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag, |
| 1627 | nesvnic->max_frame_size, PCI_DMA_FROMDEVICE); | 1772 | nesvnic->max_frame_size, PCI_DMA_FROMDEVICE); |
| @@ -1704,17 +1849,17 @@ int nes_napi_isr(struct nes_device *nesdev) | |||
| 1704 | /* iff NIC, process here, else wait for DPC */ | 1849 | /* iff NIC, process here, else wait for DPC */ |
| 1705 | if ((int_stat) && ((int_stat & 0x0000ff00) == int_stat)) { | 1850 | if ((int_stat) && ((int_stat & 0x0000ff00) == int_stat)) { |
| 1706 | nesdev->napi_isr_ran = 0; | 1851 | nesdev->napi_isr_ran = 0; |
| 1707 | nes_write32(nesdev->regs+NES_INT_STAT, | 1852 | nes_write32(nesdev->regs + NES_INT_STAT, |
| 1708 | (int_stat & | 1853 | (int_stat & |
| 1709 | ~(NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0|NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3))); | 1854 | ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0 | NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3))); |
| 1710 | 1855 | ||
| 1711 | /* Process the CEQs */ | 1856 | /* Process the CEQs */ |
| 1712 | nes_process_ceq(nesdev, &nesdev->nesadapter->ceq[nesdev->nic_ceq_index]); | 1857 | nes_process_ceq(nesdev, &nesdev->nesadapter->ceq[nesdev->nic_ceq_index]); |
| 1713 | 1858 | ||
| 1714 | if (unlikely((((nesadapter->et_rx_coalesce_usecs_irq) && | 1859 | if (unlikely((((nesadapter->et_rx_coalesce_usecs_irq) && |
| 1715 | (!nesadapter->et_use_adaptive_rx_coalesce)) || | 1860 | (!nesadapter->et_use_adaptive_rx_coalesce)) || |
| 1716 | ((nesadapter->et_use_adaptive_rx_coalesce) && | 1861 | ((nesadapter->et_use_adaptive_rx_coalesce) && |
| 1717 | (nesdev->deepcq_count > nesadapter->et_pkt_rate_low)))) ) { | 1862 | (nesdev->deepcq_count > nesadapter->et_pkt_rate_low))))) { |
| 1718 | if ((nesdev->int_req & NES_INT_TIMER) == 0) { | 1863 | if ((nesdev->int_req & NES_INT_TIMER) == 0) { |
| 1719 | /* Enable Periodic timer interrupts */ | 1864 | /* Enable Periodic timer interrupts */ |
| 1720 | nesdev->int_req |= NES_INT_TIMER; | 1865 | nesdev->int_req |= NES_INT_TIMER; |
| @@ -1792,12 +1937,12 @@ void nes_dpc(unsigned long param) | |||
| 1792 | } | 1937 | } |
| 1793 | 1938 | ||
| 1794 | if (int_stat) { | 1939 | if (int_stat) { |
| 1795 | if (int_stat & ~(NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0| | 1940 | if (int_stat & ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0| |
| 1796 | NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3)) { | 1941 | NES_INT_MAC1|NES_INT_MAC2 | NES_INT_MAC3)) { |
| 1797 | /* Ack the interrupts */ | 1942 | /* Ack the interrupts */ |
| 1798 | nes_write32(nesdev->regs+NES_INT_STAT, | 1943 | nes_write32(nesdev->regs+NES_INT_STAT, |
| 1799 | (int_stat & ~(NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0| | 1944 | (int_stat & ~(NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0| |
| 1800 | NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3))); | 1945 | NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3))); |
| 1801 | } | 1946 | } |
| 1802 | 1947 | ||
| 1803 | temp_int_stat = int_stat; | 1948 | temp_int_stat = int_stat; |
| @@ -1862,8 +2007,8 @@ void nes_dpc(unsigned long param) | |||
| 1862 | } | 2007 | } |
| 1863 | } | 2008 | } |
| 1864 | /* Don't use the interface interrupt bit stay in loop */ | 2009 | /* Don't use the interface interrupt bit stay in loop */ |
| 1865 | int_stat &= ~NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0| | 2010 | int_stat &= ~NES_INT_INTF | NES_INT_TIMER | NES_INT_MAC0 | |
| 1866 | NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3; | 2011 | NES_INT_MAC1 | NES_INT_MAC2 | NES_INT_MAC3; |
| 1867 | } while ((int_stat != 0) && (loop_counter++ < MAX_DPC_ITERATIONS)); | 2012 | } while ((int_stat != 0) && (loop_counter++ < MAX_DPC_ITERATIONS)); |
| 1868 | 2013 | ||
| 1869 | if (timer_ints == 1) { | 2014 | if (timer_ints == 1) { |
| @@ -1874,9 +2019,9 @@ void nes_dpc(unsigned long param) | |||
| 1874 | nesdev->timer_only_int_count = 0; | 2019 | nesdev->timer_only_int_count = 0; |
| 1875 | nesdev->int_req &= ~NES_INT_TIMER; | 2020 | nesdev->int_req &= ~NES_INT_TIMER; |
| 1876 | nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); | 2021 | nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); |
| 1877 | nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); | 2022 | nes_write32(nesdev->regs + NES_INT_MASK, ~nesdev->int_req); |
| 1878 | } else { | 2023 | } else { |
| 1879 | nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req)); | 2024 | nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req)); |
| 1880 | } | 2025 | } |
| 1881 | } else { | 2026 | } else { |
| 1882 | if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) | 2027 | if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) |
| @@ -1884,7 +2029,7 @@ void nes_dpc(unsigned long param) | |||
| 1884 | nes_nic_init_timer(nesdev); | 2029 | nes_nic_init_timer(nesdev); |
| 1885 | } | 2030 | } |
| 1886 | nesdev->timer_only_int_count = 0; | 2031 | nesdev->timer_only_int_count = 0; |
| 1887 | nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req)); | 2032 | nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req)); |
| 1888 | } | 2033 | } |
| 1889 | } else { | 2034 | } else { |
| 1890 | nesdev->timer_only_int_count = 0; | 2035 | nesdev->timer_only_int_count = 0; |
| @@ -1933,7 +2078,7 @@ static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq) | |||
| 1933 | do { | 2078 | do { |
| 1934 | if (le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]) & | 2079 | if (le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]) & |
| 1935 | NES_CEQE_VALID) { | 2080 | NES_CEQE_VALID) { |
| 1936 | u64temp = (((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX])))<<32) | | 2081 | u64temp = (((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]))) << 32) | |
| 1937 | ((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_LOW_IDX]))); | 2082 | ((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_LOW_IDX]))); |
| 1938 | u64temp <<= 1; | 2083 | u64temp <<= 1; |
| 1939 | cq = *((struct nes_hw_cq **)&u64temp); | 2084 | cq = *((struct nes_hw_cq **)&u64temp); |
| @@ -1961,7 +2106,7 @@ static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq) | |||
| 1961 | */ | 2106 | */ |
| 1962 | static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq) | 2107 | static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq) |
| 1963 | { | 2108 | { |
| 1964 | // u64 u64temp; | 2109 | /* u64 u64temp; */ |
| 1965 | u32 head; | 2110 | u32 head; |
| 1966 | u32 aeq_size; | 2111 | u32 aeq_size; |
| 1967 | u32 aeqe_misc; | 2112 | u32 aeqe_misc; |
| @@ -1980,8 +2125,10 @@ static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq) | |||
| 1980 | if (aeqe_misc & (NES_AEQE_QP|NES_AEQE_CQ)) { | 2125 | if (aeqe_misc & (NES_AEQE_QP|NES_AEQE_CQ)) { |
| 1981 | if (aeqe_cq_id >= NES_FIRST_QPN) { | 2126 | if (aeqe_cq_id >= NES_FIRST_QPN) { |
| 1982 | /* dealing with an accelerated QP related AE */ | 2127 | /* dealing with an accelerated QP related AE */ |
| 1983 | // u64temp = (((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])))<<32) | | 2128 | /* |
| 1984 | // ((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]))); | 2129 | * u64temp = (((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX]))) << 32) | |
| 2130 | * ((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]))); | ||
| 2131 | */ | ||
| 1985 | nes_process_iwarp_aeqe(nesdev, (struct nes_hw_aeqe *)aeqe); | 2132 | nes_process_iwarp_aeqe(nesdev, (struct nes_hw_aeqe *)aeqe); |
| 1986 | } else { | 2133 | } else { |
| 1987 | /* TODO: dealing with a CQP related AE */ | 2134 | /* TODO: dealing with a CQP related AE */ |
| @@ -2081,6 +2228,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
| 2081 | u32 u32temp; | 2228 | u32 u32temp; |
| 2082 | u16 phy_data; | 2229 | u16 phy_data; |
| 2083 | u16 temp_phy_data; | 2230 | u16 temp_phy_data; |
| 2231 | u32 pcs_val = 0x0f0f0000; | ||
| 2232 | u32 pcs_mask = 0x0f1f0000; | ||
| 2084 | 2233 | ||
| 2085 | spin_lock_irqsave(&nesadapter->phy_lock, flags); | 2234 | spin_lock_irqsave(&nesadapter->phy_lock, flags); |
| 2086 | if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { | 2235 | if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { |
| @@ -2144,13 +2293,30 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
| 2144 | nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n", | 2293 | nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n", |
| 2145 | nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0), | 2294 | nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0), |
| 2146 | nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200)); | 2295 | nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200)); |
| 2147 | pcs_control_status = nes_read_indexed(nesdev, | 2296 | |
| 2148 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index&1)*0x200)); | 2297 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_PUMA_1G) { |
| 2149 | pcs_control_status = nes_read_indexed(nesdev, | 2298 | switch (mac_index) { |
| 2150 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index&1)*0x200)); | 2299 | case 1: |
| 2300 | case 3: | ||
| 2301 | pcs_control_status = nes_read_indexed(nesdev, | ||
| 2302 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200); | ||
| 2303 | break; | ||
| 2304 | default: | ||
| 2305 | pcs_control_status = nes_read_indexed(nesdev, | ||
| 2306 | NES_IDX_PHY_PCS_CONTROL_STATUS0); | ||
| 2307 | break; | ||
| 2308 | } | ||
| 2309 | } else { | ||
| 2310 | pcs_control_status = nes_read_indexed(nesdev, | ||
| 2311 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200)); | ||
| 2312 | pcs_control_status = nes_read_indexed(nesdev, | ||
| 2313 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200)); | ||
| 2314 | } | ||
| 2315 | |||
| 2151 | nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n", | 2316 | nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n", |
| 2152 | mac_index, pcs_control_status); | 2317 | mac_index, pcs_control_status); |
| 2153 | if (nesadapter->OneG_Mode) { | 2318 | if ((nesadapter->OneG_Mode) && |
| 2319 | (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) { | ||
| 2154 | u32temp = 0x01010000; | 2320 | u32temp = 0x01010000; |
| 2155 | if (nesadapter->port_count > 2) { | 2321 | if (nesadapter->port_count > 2) { |
| 2156 | u32temp |= 0x02020000; | 2322 | u32temp |= 0x02020000; |
| @@ -2159,24 +2325,59 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
| 2159 | phy_data = 0; | 2325 | phy_data = 0; |
| 2160 | nes_debug(NES_DBG_PHY, "PCS says the link is down\n"); | 2326 | nes_debug(NES_DBG_PHY, "PCS says the link is down\n"); |
| 2161 | } | 2327 | } |
| 2162 | } else if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) { | ||
| 2163 | nes_read_10G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index]); | ||
| 2164 | temp_phy_data = (u16)nes_read_indexed(nesdev, | ||
| 2165 | NES_IDX_MAC_MDIO_CONTROL); | ||
| 2166 | u32temp = 20; | ||
| 2167 | do { | ||
| 2168 | nes_read_10G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index]); | ||
| 2169 | phy_data = (u16)nes_read_indexed(nesdev, | ||
| 2170 | NES_IDX_MAC_MDIO_CONTROL); | ||
| 2171 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||
| 2172 | break; | ||
| 2173 | temp_phy_data = phy_data; | ||
| 2174 | } while (1); | ||
| 2175 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | ||
| 2176 | __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP"); | ||
| 2177 | |||
| 2178 | } else { | 2328 | } else { |
| 2179 | phy_data = (0x0f0f0000 == (pcs_control_status & 0x0f1f0000)) ? 4 : 0; | 2329 | switch (nesadapter->phy_type[mac_index]) { |
| 2330 | case NES_PHY_TYPE_IRIS: | ||
| 2331 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
| 2332 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
| 2333 | u32temp = 20; | ||
| 2334 | do { | ||
| 2335 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
| 2336 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
| 2337 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||
| 2338 | break; | ||
| 2339 | temp_phy_data = phy_data; | ||
| 2340 | } while (1); | ||
| 2341 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | ||
| 2342 | __func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP"); | ||
| 2343 | break; | ||
| 2344 | |||
| 2345 | case NES_PHY_TYPE_ARGUS: | ||
| 2346 | /* clear the alarms */ | ||
| 2347 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008); | ||
| 2348 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001); | ||
| 2349 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc002); | ||
| 2350 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc005); | ||
| 2351 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc006); | ||
| 2352 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003); | ||
| 2353 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004); | ||
| 2354 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005); | ||
| 2355 | /* check link status */ | ||
| 2356 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
| 2357 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
| 2358 | u32temp = 100; | ||
| 2359 | do { | ||
| 2360 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
| 2361 | |||
| 2362 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
| 2363 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||
| 2364 | break; | ||
| 2365 | temp_phy_data = phy_data; | ||
| 2366 | } while (1); | ||
| 2367 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | ||
| 2368 | __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP"); | ||
| 2369 | break; | ||
| 2370 | |||
| 2371 | case NES_PHY_TYPE_PUMA_1G: | ||
| 2372 | if (mac_index < 2) | ||
| 2373 | pcs_val = pcs_mask = 0x01010000; | ||
| 2374 | else | ||
| 2375 | pcs_val = pcs_mask = 0x02020000; | ||
| 2376 | /* fall through */ | ||
| 2377 | default: | ||
| 2378 | phy_data = (pcs_val == (pcs_control_status & pcs_mask)) ? 0x4 : 0x0; | ||
| 2379 | break; | ||
| 2380 | } | ||
| 2180 | } | 2381 | } |
| 2181 | 2382 | ||
| 2182 | if (phy_data & 0x0004) { | 2383 | if (phy_data & 0x0004) { |
| @@ -2185,8 +2386,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
| 2185 | nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n", | 2386 | nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n", |
| 2186 | nesvnic->linkup); | 2387 | nesvnic->linkup); |
| 2187 | if (nesvnic->linkup == 0) { | 2388 | if (nesvnic->linkup == 0) { |
| 2188 | printk(PFX "The Link is now up for port %u, netdev %p.\n", | 2389 | printk(PFX "The Link is now up for port %s, netdev %p.\n", |
| 2189 | mac_index, nesvnic->netdev); | 2390 | nesvnic->netdev->name, nesvnic->netdev); |
| 2190 | if (netif_queue_stopped(nesvnic->netdev)) | 2391 | if (netif_queue_stopped(nesvnic->netdev)) |
| 2191 | netif_start_queue(nesvnic->netdev); | 2392 | netif_start_queue(nesvnic->netdev); |
| 2192 | nesvnic->linkup = 1; | 2393 | nesvnic->linkup = 1; |
| @@ -2199,8 +2400,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
| 2199 | nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n", | 2400 | nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n", |
| 2200 | nesvnic->linkup); | 2401 | nesvnic->linkup); |
| 2201 | if (nesvnic->linkup == 1) { | 2402 | if (nesvnic->linkup == 1) { |
| 2202 | printk(PFX "The Link is now down for port %u, netdev %p.\n", | 2403 | printk(PFX "The Link is now down for port %s, netdev %p.\n", |
| 2203 | mac_index, nesvnic->netdev); | 2404 | nesvnic->netdev->name, nesvnic->netdev); |
| 2204 | if (!(netif_queue_stopped(nesvnic->netdev))) | 2405 | if (!(netif_queue_stopped(nesvnic->netdev))) |
| 2205 | netif_stop_queue(nesvnic->netdev); | 2406 | netif_stop_queue(nesvnic->netdev); |
| 2206 | nesvnic->linkup = 0; | 2407 | nesvnic->linkup = 0; |
| @@ -2254,10 +2455,13 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
| 2254 | u16 pkt_type; | 2455 | u16 pkt_type; |
| 2255 | u16 rqes_processed = 0; | 2456 | u16 rqes_processed = 0; |
| 2256 | u8 sq_cqes = 0; | 2457 | u8 sq_cqes = 0; |
| 2458 | u8 nes_use_lro = 0; | ||
| 2257 | 2459 | ||
| 2258 | head = cq->cq_head; | 2460 | head = cq->cq_head; |
| 2259 | cq_size = cq->cq_size; | 2461 | cq_size = cq->cq_size; |
| 2260 | cq->cqes_pending = 1; | 2462 | cq->cqes_pending = 1; |
| 2463 | if (nesvnic->netdev->features & NETIF_F_LRO) | ||
| 2464 | nes_use_lro = 1; | ||
| 2261 | do { | 2465 | do { |
| 2262 | if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) & | 2466 | if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) & |
| 2263 | NES_NIC_CQE_VALID) { | 2467 | NES_NIC_CQE_VALID) { |
| @@ -2272,8 +2476,10 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
| 2272 | /* bump past the vlan tag */ | 2476 | /* bump past the vlan tag */ |
| 2273 | wqe_fragment_length++; | 2477 | wqe_fragment_length++; |
| 2274 | if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) { | 2478 | if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) { |
| 2275 | u64temp = (u64) le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+wqe_fragment_index*2]); | 2479 | u64temp = (u64) le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX + |
| 2276 | u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX+wqe_fragment_index*2]))<<32; | 2480 | wqe_fragment_index * 2]); |
| 2481 | u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX + | ||
| 2482 | wqe_fragment_index * 2])) << 32; | ||
| 2277 | bus_address = (dma_addr_t)u64temp; | 2483 | bus_address = (dma_addr_t)u64temp; |
| 2278 | if (test_and_clear_bit(nesnic->sq_tail, nesnic->first_frag_overflow)) { | 2484 | if (test_and_clear_bit(nesnic->sq_tail, nesnic->first_frag_overflow)) { |
| 2279 | pci_unmap_single(nesdev->pcidev, | 2485 | pci_unmap_single(nesdev->pcidev, |
| @@ -2283,8 +2489,10 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
| 2283 | } | 2489 | } |
| 2284 | for (; wqe_fragment_index < 5; wqe_fragment_index++) { | 2490 | for (; wqe_fragment_index < 5; wqe_fragment_index++) { |
| 2285 | if (wqe_fragment_length[wqe_fragment_index]) { | 2491 | if (wqe_fragment_length[wqe_fragment_index]) { |
| 2286 | u64temp = le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+wqe_fragment_index*2]); | 2492 | u64temp = le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX + |
| 2287 | u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX+wqe_fragment_index*2]))<<32; | 2493 | wqe_fragment_index * 2]); |
| 2494 | u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX | ||
| 2495 | + wqe_fragment_index * 2])) <<32; | ||
| 2288 | bus_address = (dma_addr_t)u64temp; | 2496 | bus_address = (dma_addr_t)u64temp; |
| 2289 | pci_unmap_page(nesdev->pcidev, | 2497 | pci_unmap_page(nesdev->pcidev, |
| 2290 | bus_address, | 2498 | bus_address, |
| @@ -2331,7 +2539,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
| 2331 | if (atomic_read(&nesvnic->rx_skbs_needed) > (nesvnic->nic.rq_size>>1)) { | 2539 | if (atomic_read(&nesvnic->rx_skbs_needed) > (nesvnic->nic.rq_size>>1)) { |
| 2332 | nes_write32(nesdev->regs+NES_CQE_ALLOC, | 2540 | nes_write32(nesdev->regs+NES_CQE_ALLOC, |
| 2333 | cq->cq_number | (cqe_count << 16)); | 2541 | cq->cq_number | (cqe_count << 16)); |
| 2334 | // nesadapter->tune_timer.cq_count += cqe_count; | 2542 | /* nesadapter->tune_timer.cq_count += cqe_count; */ |
| 2335 | nesdev->currcq_count += cqe_count; | 2543 | nesdev->currcq_count += cqe_count; |
| 2336 | cqe_count = 0; | 2544 | cqe_count = 0; |
| 2337 | nes_replenish_nic_rq(nesvnic); | 2545 | nes_replenish_nic_rq(nesvnic); |
| @@ -2379,9 +2587,16 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
| 2379 | >> 16); | 2587 | >> 16); |
| 2380 | nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n", | 2588 | nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n", |
| 2381 | nesvnic->netdev->name, vlan_tag); | 2589 | nesvnic->netdev->name, vlan_tag); |
| 2382 | nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag); | 2590 | if (nes_use_lro) |
| 2591 | lro_vlan_hwaccel_receive_skb(&nesvnic->lro_mgr, rx_skb, | ||
| 2592 | nesvnic->vlan_grp, vlan_tag, NULL); | ||
| 2593 | else | ||
| 2594 | nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag); | ||
| 2383 | } else { | 2595 | } else { |
| 2384 | nes_netif_rx(rx_skb); | 2596 | if (nes_use_lro) |
| 2597 | lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL); | ||
| 2598 | else | ||
| 2599 | nes_netif_rx(rx_skb); | ||
| 2385 | } | 2600 | } |
| 2386 | } | 2601 | } |
| 2387 | 2602 | ||
| @@ -2399,7 +2614,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
| 2399 | /* Replenish Nic CQ */ | 2614 | /* Replenish Nic CQ */ |
| 2400 | nes_write32(nesdev->regs+NES_CQE_ALLOC, | 2615 | nes_write32(nesdev->regs+NES_CQE_ALLOC, |
| 2401 | cq->cq_number | (cqe_count << 16)); | 2616 | cq->cq_number | (cqe_count << 16)); |
| 2402 | // nesdev->nesadapter->tune_timer.cq_count += cqe_count; | 2617 | /* nesdev->nesadapter->tune_timer.cq_count += cqe_count; */ |
| 2403 | nesdev->currcq_count += cqe_count; | 2618 | nesdev->currcq_count += cqe_count; |
| 2404 | cqe_count = 0; | 2619 | cqe_count = 0; |
| 2405 | } | 2620 | } |
| @@ -2413,26 +2628,27 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
| 2413 | 2628 | ||
| 2414 | } while (1); | 2629 | } while (1); |
| 2415 | 2630 | ||
| 2631 | if (nes_use_lro) | ||
| 2632 | lro_flush_all(&nesvnic->lro_mgr); | ||
| 2416 | if (sq_cqes) { | 2633 | if (sq_cqes) { |
| 2417 | barrier(); | 2634 | barrier(); |
| 2418 | /* restart the queue if it had been stopped */ | 2635 | /* restart the queue if it had been stopped */ |
| 2419 | if (netif_queue_stopped(nesvnic->netdev)) | 2636 | if (netif_queue_stopped(nesvnic->netdev)) |
| 2420 | netif_wake_queue(nesvnic->netdev); | 2637 | netif_wake_queue(nesvnic->netdev); |
| 2421 | } | 2638 | } |
| 2422 | |||
| 2423 | cq->cq_head = head; | 2639 | cq->cq_head = head; |
| 2424 | /* nes_debug(NES_DBG_CQ, "CQ%u Processed = %u cqes, new head = %u.\n", | 2640 | /* nes_debug(NES_DBG_CQ, "CQ%u Processed = %u cqes, new head = %u.\n", |
| 2425 | cq->cq_number, cqe_count, cq->cq_head); */ | 2641 | cq->cq_number, cqe_count, cq->cq_head); */ |
| 2426 | cq->cqe_allocs_pending = cqe_count; | 2642 | cq->cqe_allocs_pending = cqe_count; |
| 2427 | if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) | 2643 | if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) |
| 2428 | { | 2644 | { |
| 2429 | // nesdev->nesadapter->tune_timer.cq_count += cqe_count; | 2645 | /* nesdev->nesadapter->tune_timer.cq_count += cqe_count; */ |
| 2430 | nesdev->currcq_count += cqe_count; | 2646 | nesdev->currcq_count += cqe_count; |
| 2431 | nes_nic_tune_timer(nesdev); | 2647 | nes_nic_tune_timer(nesdev); |
| 2432 | } | 2648 | } |
| 2433 | if (atomic_read(&nesvnic->rx_skbs_needed)) | 2649 | if (atomic_read(&nesvnic->rx_skbs_needed)) |
| 2434 | nes_replenish_nic_rq(nesvnic); | 2650 | nes_replenish_nic_rq(nesvnic); |
| 2435 | } | 2651 | } |
| 2436 | 2652 | ||
| 2437 | 2653 | ||
| 2438 | /** | 2654 | /** |
| @@ -2461,7 +2677,7 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq) | |||
| 2461 | 2677 | ||
| 2462 | if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) { | 2678 | if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) { |
| 2463 | u64temp = (((u64)(le32_to_cpu(cq->cq_vbase[head]. | 2679 | u64temp = (((u64)(le32_to_cpu(cq->cq_vbase[head]. |
| 2464 | cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX])))<<32) | | 2680 | cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX]))) << 32) | |
| 2465 | ((u64)(le32_to_cpu(cq->cq_vbase[head]. | 2681 | ((u64)(le32_to_cpu(cq->cq_vbase[head]. |
| 2466 | cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]))); | 2682 | cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]))); |
| 2467 | cqp = *((struct nes_hw_cqp **)&u64temp); | 2683 | cqp = *((struct nes_hw_cqp **)&u64temp); |
| @@ -2478,7 +2694,7 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq) | |||
| 2478 | } | 2694 | } |
| 2479 | 2695 | ||
| 2480 | u64temp = (((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail]. | 2696 | u64temp = (((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail]. |
| 2481 | wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX])))<<32) | | 2697 | wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX]))) << 32) | |
| 2482 | ((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail]. | 2698 | ((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail]. |
| 2483 | wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX]))); | 2699 | wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX]))); |
| 2484 | cqp_request = *((struct nes_cqp_request **)&u64temp); | 2700 | cqp_request = *((struct nes_cqp_request **)&u64temp); |
| @@ -2515,7 +2731,7 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq) | |||
| 2515 | } else { | 2731 | } else { |
| 2516 | nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) freed.\n", | 2732 | nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) freed.\n", |
| 2517 | cqp_request, | 2733 | cqp_request, |
| 2518 | le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX])&0x3f); | 2734 | le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX]) & 0x3f); |
| 2519 | if (cqp_request->dynamic) { | 2735 | if (cqp_request->dynamic) { |
| 2520 | kfree(cqp_request); | 2736 | kfree(cqp_request); |
| 2521 | } else { | 2737 | } else { |
| @@ -2529,7 +2745,7 @@ static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq) | |||
| 2529 | } | 2745 | } |
| 2530 | 2746 | ||
| 2531 | cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0; | 2747 | cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0; |
| 2532 | nes_write32(nesdev->regs+NES_CQE_ALLOC, cq->cq_number | (1 << 16)); | 2748 | nes_write32(nesdev->regs + NES_CQE_ALLOC, cq->cq_number | (1 << 16)); |
| 2533 | if (++cqp->sq_tail >= cqp->sq_size) | 2749 | if (++cqp->sq_tail >= cqp->sq_size) |
| 2534 | cqp->sq_tail = 0; | 2750 | cqp->sq_tail = 0; |
| 2535 | 2751 | ||
| @@ -2598,13 +2814,13 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
| 2598 | nes_debug(NES_DBG_AEQ, "\n"); | 2814 | nes_debug(NES_DBG_AEQ, "\n"); |
| 2599 | aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]); | 2815 | aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]); |
| 2600 | if ((NES_AEQE_INBOUND_RDMA&aeq_info) || (!(NES_AEQE_QP&aeq_info))) { | 2816 | if ((NES_AEQE_INBOUND_RDMA&aeq_info) || (!(NES_AEQE_QP&aeq_info))) { |
| 2601 | context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]); | 2817 | context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]); |
| 2602 | context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32; | 2818 | context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32; |
| 2603 | } else { | 2819 | } else { |
| 2604 | aeqe_context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]); | 2820 | aeqe_context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]); |
| 2605 | aeqe_context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32; | 2821 | aeqe_context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32; |
| 2606 | context = (unsigned long)nesadapter->qp_table[le32_to_cpu( | 2822 | context = (unsigned long)nesadapter->qp_table[le32_to_cpu( |
| 2607 | aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN]; | 2823 | aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]) - NES_FIRST_QPN]; |
| 2608 | BUG_ON(!context); | 2824 | BUG_ON(!context); |
| 2609 | } | 2825 | } |
| 2610 | 2826 | ||
| @@ -2617,7 +2833,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
| 2617 | le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), aeqe, | 2833 | le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), aeqe, |
| 2618 | nes_tcp_state_str[tcp_state], nes_iwarp_state_str[iwarp_state]); | 2834 | nes_tcp_state_str[tcp_state], nes_iwarp_state_str[iwarp_state]); |
| 2619 | 2835 | ||
| 2620 | |||
| 2621 | switch (async_event_id) { | 2836 | switch (async_event_id) { |
| 2622 | case NES_AEQE_AEID_LLP_FIN_RECEIVED: | 2837 | case NES_AEQE_AEID_LLP_FIN_RECEIVED: |
| 2623 | nesqp = *((struct nes_qp **)&context); | 2838 | nesqp = *((struct nes_qp **)&context); |
| @@ -3021,7 +3236,7 @@ void nes_manage_arp_cache(struct net_device *netdev, unsigned char *mac_addr, | |||
| 3021 | cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_ARP_VALID); | 3236 | cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_ARP_VALID); |
| 3022 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = cpu_to_le32( | 3237 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = cpu_to_le32( |
| 3023 | (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) | | 3238 | (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) | |
| 3024 | (((u32)mac_addr[4]) << 8) | (u32)mac_addr[5]); | 3239 | (((u32)mac_addr[4]) << 8) | (u32)mac_addr[5]); |
| 3025 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = cpu_to_le32( | 3240 | cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = cpu_to_le32( |
| 3026 | (((u32)mac_addr[0]) << 16) | (u32)mac_addr[1]); | 3241 | (((u32)mac_addr[0]) << 16) | (u32)mac_addr[1]); |
| 3027 | } else { | 3242 | } else { |
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 8f36e231bdf5..745bf94f3f07 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h | |||
| @@ -33,8 +33,12 @@ | |||
| 33 | #ifndef __NES_HW_H | 33 | #ifndef __NES_HW_H |
| 34 | #define __NES_HW_H | 34 | #define __NES_HW_H |
| 35 | 35 | ||
| 36 | #define NES_PHY_TYPE_1G 2 | 36 | #include <linux/inet_lro.h> |
| 37 | #define NES_PHY_TYPE_IRIS 3 | 37 | |
| 38 | #define NES_PHY_TYPE_1G 2 | ||
| 39 | #define NES_PHY_TYPE_IRIS 3 | ||
| 40 | #define NES_PHY_TYPE_ARGUS 4 | ||
| 41 | #define NES_PHY_TYPE_PUMA_1G 5 | ||
| 38 | #define NES_PHY_TYPE_PUMA_10G 6 | 42 | #define NES_PHY_TYPE_PUMA_10G 6 |
| 39 | 43 | ||
| 40 | #define NES_MULTICAST_PF_MAX 8 | 44 | #define NES_MULTICAST_PF_MAX 8 |
| @@ -965,7 +969,7 @@ struct nes_arp_entry { | |||
| 965 | #define NES_NIC_CQ_DOWNWARD_TREND 16 | 969 | #define NES_NIC_CQ_DOWNWARD_TREND 16 |
| 966 | 970 | ||
| 967 | struct nes_hw_tune_timer { | 971 | struct nes_hw_tune_timer { |
| 968 | //u16 cq_count; | 972 | /* u16 cq_count; */ |
| 969 | u16 threshold_low; | 973 | u16 threshold_low; |
| 970 | u16 threshold_target; | 974 | u16 threshold_target; |
| 971 | u16 threshold_high; | 975 | u16 threshold_high; |
| @@ -982,8 +986,10 @@ struct nes_hw_tune_timer { | |||
| 982 | #define NES_TIMER_INT_LIMIT 2 | 986 | #define NES_TIMER_INT_LIMIT 2 |
| 983 | #define NES_TIMER_INT_LIMIT_DYNAMIC 10 | 987 | #define NES_TIMER_INT_LIMIT_DYNAMIC 10 |
| 984 | #define NES_TIMER_ENABLE_LIMIT 4 | 988 | #define NES_TIMER_ENABLE_LIMIT 4 |
| 985 | #define NES_MAX_LINK_INTERRUPTS 128 | 989 | #define NES_MAX_LINK_INTERRUPTS 128 |
| 986 | #define NES_MAX_LINK_CHECK 200 | 990 | #define NES_MAX_LINK_CHECK 200 |
| 991 | #define NES_MAX_LRO_DESCRIPTORS 32 | ||
| 992 | #define NES_LRO_MAX_AGGR 64 | ||
| 987 | 993 | ||
| 988 | struct nes_adapter { | 994 | struct nes_adapter { |
| 989 | u64 fw_ver; | 995 | u64 fw_ver; |
| @@ -1183,6 +1189,9 @@ struct nes_vnic { | |||
| 1183 | u8 of_device_registered; | 1189 | u8 of_device_registered; |
| 1184 | u8 rdma_enabled; | 1190 | u8 rdma_enabled; |
| 1185 | u8 rx_checksum_disabled; | 1191 | u8 rx_checksum_disabled; |
| 1192 | u32 lro_max_aggr; | ||
| 1193 | struct net_lro_mgr lro_mgr; | ||
| 1194 | struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS]; | ||
| 1186 | }; | 1195 | }; |
| 1187 | 1196 | ||
| 1188 | struct nes_ib_device { | 1197 | struct nes_ib_device { |
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index e5366b013c1a..1b0938c87774 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c | |||
| @@ -185,12 +185,13 @@ static int nes_netdev_open(struct net_device *netdev) | |||
| 185 | nic_active |= nic_active_bit; | 185 | nic_active |= nic_active_bit; |
| 186 | nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active); | 186 | nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active); |
| 187 | 187 | ||
| 188 | macaddr_high = ((u16)netdev->dev_addr[0]) << 8; | 188 | macaddr_high = ((u16)netdev->dev_addr[0]) << 8; |
| 189 | macaddr_high += (u16)netdev->dev_addr[1]; | 189 | macaddr_high += (u16)netdev->dev_addr[1]; |
| 190 | macaddr_low = ((u32)netdev->dev_addr[2]) << 24; | 190 | |
| 191 | macaddr_low += ((u32)netdev->dev_addr[3]) << 16; | 191 | macaddr_low = ((u32)netdev->dev_addr[2]) << 24; |
| 192 | macaddr_low += ((u32)netdev->dev_addr[4]) << 8; | 192 | macaddr_low += ((u32)netdev->dev_addr[3]) << 16; |
| 193 | macaddr_low += (u32)netdev->dev_addr[5]; | 193 | macaddr_low += ((u32)netdev->dev_addr[4]) << 8; |
| 194 | macaddr_low += (u32)netdev->dev_addr[5]; | ||
| 194 | 195 | ||
| 195 | /* Program the various MAC regs */ | 196 | /* Program the various MAC regs */ |
| 196 | for (i = 0; i < NES_MAX_PORT_COUNT; i++) { | 197 | for (i = 0; i < NES_MAX_PORT_COUNT; i++) { |
| @@ -451,7 +452,7 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
| 451 | __le16 *wqe_fragment_length; | 452 | __le16 *wqe_fragment_length; |
| 452 | u32 nr_frags; | 453 | u32 nr_frags; |
| 453 | u32 original_first_length; | 454 | u32 original_first_length; |
| 454 | // u64 *wqe_fragment_address; | 455 | /* u64 *wqe_fragment_address; */ |
| 455 | /* first fragment (0) is used by copy buffer */ | 456 | /* first fragment (0) is used by copy buffer */ |
| 456 | u16 wqe_fragment_index=1; | 457 | u16 wqe_fragment_index=1; |
| 457 | u16 hoffset; | 458 | u16 hoffset; |
| @@ -461,11 +462,12 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
| 461 | u32 old_head; | 462 | u32 old_head; |
| 462 | u32 wqe_misc; | 463 | u32 wqe_misc; |
| 463 | 464 | ||
| 464 | /* nes_debug(NES_DBG_NIC_TX, "%s Request to tx NIC packet length %u, headlen %u," | 465 | /* |
| 465 | " (%u frags), tso_size=%u\n", | 466 | * nes_debug(NES_DBG_NIC_TX, "%s Request to tx NIC packet length %u, headlen %u," |
| 466 | netdev->name, skb->len, skb_headlen(skb), | 467 | * " (%u frags), tso_size=%u\n", |
| 467 | skb_shinfo(skb)->nr_frags, skb_is_gso(skb)); | 468 | * netdev->name, skb->len, skb_headlen(skb), |
| 468 | */ | 469 | * skb_shinfo(skb)->nr_frags, skb_is_gso(skb)); |
| 470 | */ | ||
| 469 | 471 | ||
| 470 | if (!netif_carrier_ok(netdev)) | 472 | if (!netif_carrier_ok(netdev)) |
| 471 | return NETDEV_TX_OK; | 473 | return NETDEV_TX_OK; |
| @@ -795,12 +797,12 @@ static int nes_netdev_set_mac_address(struct net_device *netdev, void *p) | |||
| 795 | memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len); | 797 | memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len); |
| 796 | printk(PFX "%s: Address length = %d, Address = %s\n", | 798 | printk(PFX "%s: Address length = %d, Address = %s\n", |
| 797 | __func__, netdev->addr_len, print_mac(mac, mac_addr->sa_data)); | 799 | __func__, netdev->addr_len, print_mac(mac, mac_addr->sa_data)); |
| 798 | macaddr_high = ((u16)netdev->dev_addr[0]) << 8; | 800 | macaddr_high = ((u16)netdev->dev_addr[0]) << 8; |
| 799 | macaddr_high += (u16)netdev->dev_addr[1]; | 801 | macaddr_high += (u16)netdev->dev_addr[1]; |
| 800 | macaddr_low = ((u32)netdev->dev_addr[2]) << 24; | 802 | macaddr_low = ((u32)netdev->dev_addr[2]) << 24; |
| 801 | macaddr_low += ((u32)netdev->dev_addr[3]) << 16; | 803 | macaddr_low += ((u32)netdev->dev_addr[3]) << 16; |
| 802 | macaddr_low += ((u32)netdev->dev_addr[4]) << 8; | 804 | macaddr_low += ((u32)netdev->dev_addr[4]) << 8; |
| 803 | macaddr_low += (u32)netdev->dev_addr[5]; | 805 | macaddr_low += (u32)netdev->dev_addr[5]; |
| 804 | 806 | ||
| 805 | for (i = 0; i < NES_MAX_PORT_COUNT; i++) { | 807 | for (i = 0; i < NES_MAX_PORT_COUNT; i++) { |
| 806 | if (nesvnic->qp_nic_index[i] == 0xf) { | 808 | if (nesvnic->qp_nic_index[i] == 0xf) { |
| @@ -881,12 +883,12 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
| 881 | print_mac(mac, multicast_addr->dmi_addr), | 883 | print_mac(mac, multicast_addr->dmi_addr), |
| 882 | perfect_filter_register_address+(mc_index * 8), | 884 | perfect_filter_register_address+(mc_index * 8), |
| 883 | mc_nic_index); | 885 | mc_nic_index); |
| 884 | macaddr_high = ((u16)multicast_addr->dmi_addr[0]) << 8; | 886 | macaddr_high = ((u16)multicast_addr->dmi_addr[0]) << 8; |
| 885 | macaddr_high += (u16)multicast_addr->dmi_addr[1]; | 887 | macaddr_high += (u16)multicast_addr->dmi_addr[1]; |
| 886 | macaddr_low = ((u32)multicast_addr->dmi_addr[2]) << 24; | 888 | macaddr_low = ((u32)multicast_addr->dmi_addr[2]) << 24; |
| 887 | macaddr_low += ((u32)multicast_addr->dmi_addr[3]) << 16; | 889 | macaddr_low += ((u32)multicast_addr->dmi_addr[3]) << 16; |
| 888 | macaddr_low += ((u32)multicast_addr->dmi_addr[4]) << 8; | 890 | macaddr_low += ((u32)multicast_addr->dmi_addr[4]) << 8; |
| 889 | macaddr_low += (u32)multicast_addr->dmi_addr[5]; | 891 | macaddr_low += (u32)multicast_addr->dmi_addr[5]; |
| 890 | nes_write_indexed(nesdev, | 892 | nes_write_indexed(nesdev, |
| 891 | perfect_filter_register_address+(mc_index * 8), | 893 | perfect_filter_register_address+(mc_index * 8), |
| 892 | macaddr_low); | 894 | macaddr_low); |
| @@ -910,23 +912,23 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
| 910 | /** | 912 | /** |
| 911 | * nes_netdev_change_mtu | 913 | * nes_netdev_change_mtu |
| 912 | */ | 914 | */ |
| 913 | static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu) | 915 | static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu) |
| 914 | { | 916 | { |
| 915 | struct nes_vnic *nesvnic = netdev_priv(netdev); | 917 | struct nes_vnic *nesvnic = netdev_priv(netdev); |
| 916 | struct nes_device *nesdev = nesvnic->nesdev; | 918 | struct nes_device *nesdev = nesvnic->nesdev; |
| 917 | int ret = 0; | 919 | int ret = 0; |
| 918 | u8 jumbomode=0; | 920 | u8 jumbomode = 0; |
| 919 | 921 | ||
| 920 | if ((new_mtu < ETH_ZLEN) || (new_mtu > max_mtu)) | 922 | if ((new_mtu < ETH_ZLEN) || (new_mtu > max_mtu)) |
| 921 | return -EINVAL; | 923 | return -EINVAL; |
| 922 | 924 | ||
| 923 | netdev->mtu = new_mtu; | 925 | netdev->mtu = new_mtu; |
| 924 | nesvnic->max_frame_size = new_mtu + VLAN_ETH_HLEN; | 926 | nesvnic->max_frame_size = new_mtu + VLAN_ETH_HLEN; |
| 925 | 927 | ||
| 926 | if (netdev->mtu > 1500) { | 928 | if (netdev->mtu > 1500) { |
| 927 | jumbomode=1; | 929 | jumbomode=1; |
| 928 | } | 930 | } |
| 929 | nes_nic_init_timer_defaults(nesdev, jumbomode); | 931 | nes_nic_init_timer_defaults(nesdev, jumbomode); |
| 930 | 932 | ||
| 931 | if (netif_running(netdev)) { | 933 | if (netif_running(netdev)) { |
| 932 | nes_netdev_stop(netdev); | 934 | nes_netdev_stop(netdev); |
| @@ -936,8 +938,7 @@ static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu) | |||
| 936 | return ret; | 938 | return ret; |
| 937 | } | 939 | } |
| 938 | 940 | ||
| 939 | #define NES_ETHTOOL_STAT_COUNT 55 | 941 | static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = { |
| 940 | static const char nes_ethtool_stringset[NES_ETHTOOL_STAT_COUNT][ETH_GSTRING_LEN] = { | ||
| 941 | "Link Change Interrupts", | 942 | "Link Change Interrupts", |
| 942 | "Linearized SKBs", | 943 | "Linearized SKBs", |
| 943 | "T/GSO Requests", | 944 | "T/GSO Requests", |
| @@ -993,8 +994,12 @@ static const char nes_ethtool_stringset[NES_ETHTOOL_STAT_COUNT][ETH_GSTRING_LEN] | |||
| 993 | "CQ Depth 32", | 994 | "CQ Depth 32", |
| 994 | "CQ Depth 128", | 995 | "CQ Depth 128", |
| 995 | "CQ Depth 256", | 996 | "CQ Depth 256", |
| 997 | "LRO aggregated", | ||
| 998 | "LRO flushed", | ||
| 999 | "LRO no_desc", | ||
| 996 | }; | 1000 | }; |
| 997 | 1001 | ||
| 1002 | #define NES_ETHTOOL_STAT_COUNT ARRAY_SIZE(nes_ethtool_stringset) | ||
| 998 | 1003 | ||
| 999 | /** | 1004 | /** |
| 1000 | * nes_netdev_get_rx_csum | 1005 | * nes_netdev_get_rx_csum |
| @@ -1189,6 +1194,9 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev, | |||
| 1189 | target_stat_values[52] = int_mod_cq_depth_32; | 1194 | target_stat_values[52] = int_mod_cq_depth_32; |
| 1190 | target_stat_values[53] = int_mod_cq_depth_128; | 1195 | target_stat_values[53] = int_mod_cq_depth_128; |
| 1191 | target_stat_values[54] = int_mod_cq_depth_256; | 1196 | target_stat_values[54] = int_mod_cq_depth_256; |
| 1197 | target_stat_values[55] = nesvnic->lro_mgr.stats.aggregated; | ||
| 1198 | target_stat_values[56] = nesvnic->lro_mgr.stats.flushed; | ||
| 1199 | target_stat_values[57] = nesvnic->lro_mgr.stats.no_desc; | ||
| 1192 | 1200 | ||
| 1193 | } | 1201 | } |
| 1194 | 1202 | ||
| @@ -1219,14 +1227,14 @@ static int nes_netdev_set_coalesce(struct net_device *netdev, | |||
| 1219 | struct ethtool_coalesce *et_coalesce) | 1227 | struct ethtool_coalesce *et_coalesce) |
| 1220 | { | 1228 | { |
| 1221 | struct nes_vnic *nesvnic = netdev_priv(netdev); | 1229 | struct nes_vnic *nesvnic = netdev_priv(netdev); |
| 1222 | struct nes_device *nesdev = nesvnic->nesdev; | 1230 | struct nes_device *nesdev = nesvnic->nesdev; |
| 1223 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1231 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
| 1224 | struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; | 1232 | struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; |
| 1225 | unsigned long flags; | 1233 | unsigned long flags; |
| 1226 | 1234 | ||
| 1227 | spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); | 1235 | spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); |
| 1228 | if (et_coalesce->rx_max_coalesced_frames_low) { | 1236 | if (et_coalesce->rx_max_coalesced_frames_low) { |
| 1229 | shared_timer->threshold_low = et_coalesce->rx_max_coalesced_frames_low; | 1237 | shared_timer->threshold_low = et_coalesce->rx_max_coalesced_frames_low; |
| 1230 | } | 1238 | } |
| 1231 | if (et_coalesce->rx_max_coalesced_frames_irq) { | 1239 | if (et_coalesce->rx_max_coalesced_frames_irq) { |
| 1232 | shared_timer->threshold_target = et_coalesce->rx_max_coalesced_frames_irq; | 1240 | shared_timer->threshold_target = et_coalesce->rx_max_coalesced_frames_irq; |
| @@ -1246,14 +1254,14 @@ static int nes_netdev_set_coalesce(struct net_device *netdev, | |||
| 1246 | nesadapter->et_rx_coalesce_usecs_irq = et_coalesce->rx_coalesce_usecs_irq; | 1254 | nesadapter->et_rx_coalesce_usecs_irq = et_coalesce->rx_coalesce_usecs_irq; |
| 1247 | if (et_coalesce->use_adaptive_rx_coalesce) { | 1255 | if (et_coalesce->use_adaptive_rx_coalesce) { |
| 1248 | nesadapter->et_use_adaptive_rx_coalesce = 1; | 1256 | nesadapter->et_use_adaptive_rx_coalesce = 1; |
| 1249 | nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT_DYNAMIC; | 1257 | nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT_DYNAMIC; |
| 1250 | nesadapter->et_rx_coalesce_usecs_irq = 0; | 1258 | nesadapter->et_rx_coalesce_usecs_irq = 0; |
| 1251 | if (et_coalesce->pkt_rate_low) { | 1259 | if (et_coalesce->pkt_rate_low) { |
| 1252 | nesadapter->et_pkt_rate_low = et_coalesce->pkt_rate_low; | 1260 | nesadapter->et_pkt_rate_low = et_coalesce->pkt_rate_low; |
| 1253 | } | 1261 | } |
| 1254 | } else { | 1262 | } else { |
| 1255 | nesadapter->et_use_adaptive_rx_coalesce = 0; | 1263 | nesadapter->et_use_adaptive_rx_coalesce = 0; |
| 1256 | nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT; | 1264 | nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT; |
| 1257 | if (nesadapter->et_rx_coalesce_usecs_irq) { | 1265 | if (nesadapter->et_rx_coalesce_usecs_irq) { |
| 1258 | nes_write32(nesdev->regs+NES_PERIODIC_CONTROL, | 1266 | nes_write32(nesdev->regs+NES_PERIODIC_CONTROL, |
| 1259 | 0x80000000 | ((u32)(nesadapter->et_rx_coalesce_usecs_irq*8))); | 1267 | 0x80000000 | ((u32)(nesadapter->et_rx_coalesce_usecs_irq*8))); |
| @@ -1270,28 +1278,28 @@ static int nes_netdev_get_coalesce(struct net_device *netdev, | |||
| 1270 | struct ethtool_coalesce *et_coalesce) | 1278 | struct ethtool_coalesce *et_coalesce) |
| 1271 | { | 1279 | { |
| 1272 | struct nes_vnic *nesvnic = netdev_priv(netdev); | 1280 | struct nes_vnic *nesvnic = netdev_priv(netdev); |
| 1273 | struct nes_device *nesdev = nesvnic->nesdev; | 1281 | struct nes_device *nesdev = nesvnic->nesdev; |
| 1274 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1282 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
| 1275 | struct ethtool_coalesce temp_et_coalesce; | 1283 | struct ethtool_coalesce temp_et_coalesce; |
| 1276 | struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; | 1284 | struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; |
| 1277 | unsigned long flags; | 1285 | unsigned long flags; |
| 1278 | 1286 | ||
| 1279 | memset(&temp_et_coalesce, 0, sizeof(temp_et_coalesce)); | 1287 | memset(&temp_et_coalesce, 0, sizeof(temp_et_coalesce)); |
| 1280 | temp_et_coalesce.rx_coalesce_usecs_irq = nesadapter->et_rx_coalesce_usecs_irq; | 1288 | temp_et_coalesce.rx_coalesce_usecs_irq = nesadapter->et_rx_coalesce_usecs_irq; |
| 1281 | temp_et_coalesce.use_adaptive_rx_coalesce = nesadapter->et_use_adaptive_rx_coalesce; | 1289 | temp_et_coalesce.use_adaptive_rx_coalesce = nesadapter->et_use_adaptive_rx_coalesce; |
| 1282 | temp_et_coalesce.rate_sample_interval = nesadapter->et_rate_sample_interval; | 1290 | temp_et_coalesce.rate_sample_interval = nesadapter->et_rate_sample_interval; |
| 1283 | temp_et_coalesce.pkt_rate_low = nesadapter->et_pkt_rate_low; | 1291 | temp_et_coalesce.pkt_rate_low = nesadapter->et_pkt_rate_low; |
| 1284 | spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); | 1292 | spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); |
| 1285 | temp_et_coalesce.rx_max_coalesced_frames_low = shared_timer->threshold_low; | 1293 | temp_et_coalesce.rx_max_coalesced_frames_low = shared_timer->threshold_low; |
| 1286 | temp_et_coalesce.rx_max_coalesced_frames_irq = shared_timer->threshold_target; | 1294 | temp_et_coalesce.rx_max_coalesced_frames_irq = shared_timer->threshold_target; |
| 1287 | temp_et_coalesce.rx_max_coalesced_frames_high = shared_timer->threshold_high; | 1295 | temp_et_coalesce.rx_max_coalesced_frames_high = shared_timer->threshold_high; |
| 1288 | temp_et_coalesce.rx_coalesce_usecs_low = shared_timer->timer_in_use_min; | 1296 | temp_et_coalesce.rx_coalesce_usecs_low = shared_timer->timer_in_use_min; |
| 1289 | temp_et_coalesce.rx_coalesce_usecs_high = shared_timer->timer_in_use_max; | 1297 | temp_et_coalesce.rx_coalesce_usecs_high = shared_timer->timer_in_use_max; |
| 1290 | if (nesadapter->et_use_adaptive_rx_coalesce) { | 1298 | if (nesadapter->et_use_adaptive_rx_coalesce) { |
| 1291 | temp_et_coalesce.rx_coalesce_usecs_irq = shared_timer->timer_in_use; | 1299 | temp_et_coalesce.rx_coalesce_usecs_irq = shared_timer->timer_in_use; |
| 1292 | } | 1300 | } |
| 1293 | spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags); | 1301 | spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags); |
| 1294 | memcpy(et_coalesce, &temp_et_coalesce, sizeof(*et_coalesce)); | 1302 | memcpy(et_coalesce, &temp_et_coalesce, sizeof(*et_coalesce)); |
| 1295 | return 0; | 1303 | return 0; |
| 1296 | } | 1304 | } |
| 1297 | 1305 | ||
| @@ -1370,30 +1378,38 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd | |||
| 1370 | u16 phy_data; | 1378 | u16 phy_data; |
| 1371 | 1379 | ||
| 1372 | et_cmd->duplex = DUPLEX_FULL; | 1380 | et_cmd->duplex = DUPLEX_FULL; |
| 1373 | et_cmd->port = PORT_MII; | 1381 | et_cmd->port = PORT_MII; |
| 1382 | |||
| 1374 | if (nesadapter->OneG_Mode) { | 1383 | if (nesadapter->OneG_Mode) { |
| 1375 | et_cmd->supported = SUPPORTED_1000baseT_Full|SUPPORTED_Autoneg; | ||
| 1376 | et_cmd->advertising = ADVERTISED_1000baseT_Full|ADVERTISED_Autoneg; | ||
| 1377 | et_cmd->speed = SPEED_1000; | 1384 | et_cmd->speed = SPEED_1000; |
| 1378 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], | 1385 | if (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) { |
| 1379 | &phy_data); | 1386 | et_cmd->supported = SUPPORTED_1000baseT_Full; |
| 1380 | if (phy_data&0x1000) { | 1387 | et_cmd->advertising = ADVERTISED_1000baseT_Full; |
| 1381 | et_cmd->autoneg = AUTONEG_ENABLE; | 1388 | et_cmd->autoneg = AUTONEG_DISABLE; |
| 1389 | et_cmd->transceiver = XCVR_INTERNAL; | ||
| 1390 | et_cmd->phy_address = nesdev->mac_index; | ||
| 1382 | } else { | 1391 | } else { |
| 1383 | et_cmd->autoneg = AUTONEG_DISABLE; | 1392 | et_cmd->supported = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg; |
| 1393 | et_cmd->advertising = ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg; | ||
| 1394 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], &phy_data); | ||
| 1395 | if (phy_data & 0x1000) | ||
| 1396 | et_cmd->autoneg = AUTONEG_ENABLE; | ||
| 1397 | else | ||
| 1398 | et_cmd->autoneg = AUTONEG_DISABLE; | ||
| 1399 | et_cmd->transceiver = XCVR_EXTERNAL; | ||
| 1400 | et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; | ||
| 1384 | } | 1401 | } |
| 1385 | et_cmd->transceiver = XCVR_EXTERNAL; | ||
| 1386 | et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; | ||
| 1387 | } else { | 1402 | } else { |
| 1388 | if (nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) { | 1403 | if ((nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) || |
| 1404 | (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_ARGUS)) { | ||
| 1389 | et_cmd->transceiver = XCVR_EXTERNAL; | 1405 | et_cmd->transceiver = XCVR_EXTERNAL; |
| 1390 | et_cmd->port = PORT_FIBRE; | 1406 | et_cmd->port = PORT_FIBRE; |
| 1391 | et_cmd->supported = SUPPORTED_FIBRE; | 1407 | et_cmd->supported = SUPPORTED_FIBRE; |
| 1392 | et_cmd->advertising = ADVERTISED_FIBRE; | 1408 | et_cmd->advertising = ADVERTISED_FIBRE; |
| 1393 | et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; | 1409 | et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; |
| 1394 | } else { | 1410 | } else { |
| 1395 | et_cmd->transceiver = XCVR_INTERNAL; | 1411 | et_cmd->transceiver = XCVR_INTERNAL; |
| 1396 | et_cmd->supported = SUPPORTED_10000baseT_Full; | 1412 | et_cmd->supported = SUPPORTED_10000baseT_Full; |
| 1397 | et_cmd->advertising = ADVERTISED_10000baseT_Full; | 1413 | et_cmd->advertising = ADVERTISED_10000baseT_Full; |
| 1398 | et_cmd->phy_address = nesdev->mac_index; | 1414 | et_cmd->phy_address = nesdev->mac_index; |
| 1399 | } | 1415 | } |
| @@ -1416,14 +1432,15 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd | |||
| 1416 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1432 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
| 1417 | u16 phy_data; | 1433 | u16 phy_data; |
| 1418 | 1434 | ||
| 1419 | if (nesadapter->OneG_Mode) { | 1435 | if ((nesadapter->OneG_Mode) && |
| 1436 | (nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G)) { | ||
| 1420 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], | 1437 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], |
| 1421 | &phy_data); | 1438 | &phy_data); |
| 1422 | if (et_cmd->autoneg) { | 1439 | if (et_cmd->autoneg) { |
| 1423 | /* Turn on Full duplex, Autoneg, and restart autonegotiation */ | 1440 | /* Turn on Full duplex, Autoneg, and restart autonegotiation */ |
| 1424 | phy_data |= 0x1300; | 1441 | phy_data |= 0x1300; |
| 1425 | } else { | 1442 | } else { |
| 1426 | // Turn off autoneg | 1443 | /* Turn off autoneg */ |
| 1427 | phy_data &= ~0x1000; | 1444 | phy_data &= ~0x1000; |
| 1428 | } | 1445 | } |
| 1429 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], | 1446 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], |
| @@ -1454,6 +1471,8 @@ static struct ethtool_ops nes_ethtool_ops = { | |||
| 1454 | .set_sg = ethtool_op_set_sg, | 1471 | .set_sg = ethtool_op_set_sg, |
| 1455 | .get_tso = ethtool_op_get_tso, | 1472 | .get_tso = ethtool_op_get_tso, |
| 1456 | .set_tso = ethtool_op_set_tso, | 1473 | .set_tso = ethtool_op_set_tso, |
| 1474 | .get_flags = ethtool_op_get_flags, | ||
| 1475 | .set_flags = ethtool_op_set_flags, | ||
| 1457 | }; | 1476 | }; |
| 1458 | 1477 | ||
| 1459 | 1478 | ||
| @@ -1607,27 +1626,34 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
| 1607 | list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]); | 1626 | list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]); |
| 1608 | 1627 | ||
| 1609 | if ((nesdev->netdev_count == 0) && | 1628 | if ((nesdev->netdev_count == 0) && |
| 1610 | (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) { | 1629 | ((PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index) || |
| 1611 | nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n", | 1630 | ((nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) && |
| 1612 | NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1))); | 1631 | (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || |
| 1632 | ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { | ||
| 1633 | /* | ||
| 1634 | * nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n", | ||
| 1635 | * NES_IDX_PHY_PCS_CONTROL_STATUS0 + (0x200 * (nesvnic->logical_port & 1))); | ||
| 1636 | */ | ||
| 1613 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1637 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
| 1614 | (0x200*(nesvnic->logical_port&1))); | 1638 | (0x200 * (nesdev->mac_index & 1))); |
| 1615 | u32temp |= 0x00200000; | 1639 | if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G) { |
| 1616 | nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1640 | u32temp |= 0x00200000; |
| 1617 | (0x200*(nesvnic->logical_port&1)), u32temp); | 1641 | nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
| 1642 | (0x200 * (nesdev->mac_index & 1)), u32temp); | ||
| 1643 | } | ||
| 1644 | |||
| 1618 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1645 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
| 1619 | (0x200*(nesvnic->logical_port&1)) ); | 1646 | (0x200 * (nesdev->mac_index & 1))); |
| 1647 | |||
| 1620 | if ((u32temp&0x0f1f0000) == 0x0f0f0000) { | 1648 | if ((u32temp&0x0f1f0000) == 0x0f0f0000) { |
| 1621 | if (nesdev->nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) { | 1649 | if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) { |
| 1622 | nes_init_phy(nesdev); | 1650 | nes_init_phy(nesdev); |
| 1623 | nes_read_10G_phy_reg(nesdev, 1, | 1651 | nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1); |
| 1624 | nesdev->nesadapter->phy_index[nesvnic->logical_port]); | ||
| 1625 | temp_phy_data = (u16)nes_read_indexed(nesdev, | 1652 | temp_phy_data = (u16)nes_read_indexed(nesdev, |
| 1626 | NES_IDX_MAC_MDIO_CONTROL); | 1653 | NES_IDX_MAC_MDIO_CONTROL); |
| 1627 | u32temp = 20; | 1654 | u32temp = 20; |
| 1628 | do { | 1655 | do { |
| 1629 | nes_read_10G_phy_reg(nesdev, 1, | 1656 | nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1); |
| 1630 | nesdev->nesadapter->phy_index[nesvnic->logical_port]); | ||
| 1631 | phy_data = (u16)nes_read_indexed(nesdev, | 1657 | phy_data = (u16)nes_read_indexed(nesdev, |
| 1632 | NES_IDX_MAC_MDIO_CONTROL); | 1658 | NES_IDX_MAC_MDIO_CONTROL); |
| 1633 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | 1659 | if ((phy_data == temp_phy_data) || (!(--u32temp))) |
| @@ -1644,6 +1670,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
| 1644 | nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); | 1670 | nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); |
| 1645 | nesvnic->linkup = 1; | 1671 | nesvnic->linkup = 1; |
| 1646 | } | 1672 | } |
| 1673 | } else if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) { | ||
| 1674 | nes_debug(NES_DBG_INIT, "mac_index=%d, logical_port=%d, u32temp=0x%04X, PCI_FUNC=%d\n", | ||
| 1675 | nesdev->mac_index, nesvnic->logical_port, u32temp, PCI_FUNC(nesdev->pcidev->devfn)); | ||
| 1676 | if (((nesdev->mac_index < 2) && ((u32temp&0x01010000) == 0x01010000)) || | ||
| 1677 | ((nesdev->mac_index > 1) && ((u32temp&0x02020000) == 0x02020000))) { | ||
| 1678 | nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); | ||
| 1679 | nesvnic->linkup = 1; | ||
| 1680 | } | ||
| 1647 | } | 1681 | } |
| 1648 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ | 1682 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ |
| 1649 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); | 1683 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); |
diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c index c6d5631a6995..fe83d1b2b177 100644 --- a/drivers/infiniband/hw/nes/nes_utils.c +++ b/drivers/infiniband/hw/nes/nes_utils.c | |||
| @@ -444,15 +444,13 @@ void nes_read_1G_phy_reg(struct nes_device *nesdev, u8 phy_reg, u8 phy_addr, u16 | |||
| 444 | /** | 444 | /** |
| 445 | * nes_write_10G_phy_reg | 445 | * nes_write_10G_phy_reg |
| 446 | */ | 446 | */ |
| 447 | void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, | 447 | void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_addr, u8 dev_addr, u16 phy_reg, |
| 448 | u8 phy_addr, u16 data) | 448 | u16 data) |
| 449 | { | 449 | { |
| 450 | u32 dev_addr; | ||
| 451 | u32 port_addr; | 450 | u32 port_addr; |
| 452 | u32 u32temp; | 451 | u32 u32temp; |
| 453 | u32 counter; | 452 | u32 counter; |
| 454 | 453 | ||
| 455 | dev_addr = 1; | ||
| 456 | port_addr = phy_addr; | 454 | port_addr = phy_addr; |
| 457 | 455 | ||
| 458 | /* set address */ | 456 | /* set address */ |
| @@ -492,14 +490,12 @@ void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, | |||
| 492 | * This routine only issues the read, the data must be read | 490 | * This routine only issues the read, the data must be read |
| 493 | * separately. | 491 | * separately. |
| 494 | */ | 492 | */ |
| 495 | void nes_read_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, u8 phy_addr) | 493 | void nes_read_10G_phy_reg(struct nes_device *nesdev, u8 phy_addr, u8 dev_addr, u16 phy_reg) |
| 496 | { | 494 | { |
| 497 | u32 dev_addr; | ||
| 498 | u32 port_addr; | 495 | u32 port_addr; |
| 499 | u32 u32temp; | 496 | u32 u32temp; |
| 500 | u32 counter; | 497 | u32 counter; |
| 501 | 498 | ||
| 502 | dev_addr = 1; | ||
| 503 | port_addr = phy_addr; | 499 | port_addr = phy_addr; |
| 504 | 500 | ||
| 505 | /* set address */ | 501 | /* set address */ |
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 9ae397a0ff7e..99b3c4ae86eb 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
| @@ -1266,7 +1266,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, | |||
| 1266 | sq_size = init_attr->cap.max_send_wr; | 1266 | sq_size = init_attr->cap.max_send_wr; |
| 1267 | rq_size = init_attr->cap.max_recv_wr; | 1267 | rq_size = init_attr->cap.max_recv_wr; |
| 1268 | 1268 | ||
| 1269 | // check if the encoded sizes are OK or not... | 1269 | /* check if the encoded sizes are OK or not... */ |
| 1270 | sq_encoded_size = nes_get_encoded_size(&sq_size); | 1270 | sq_encoded_size = nes_get_encoded_size(&sq_size); |
| 1271 | rq_encoded_size = nes_get_encoded_size(&rq_size); | 1271 | rq_encoded_size = nes_get_encoded_size(&rq_size); |
| 1272 | 1272 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index f1f142dc64b1..9044f8803532 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
| @@ -95,6 +95,8 @@ enum { | |||
| 95 | IPOIB_MCAST_FLAG_SENDONLY = 1, | 95 | IPOIB_MCAST_FLAG_SENDONLY = 1, |
| 96 | IPOIB_MCAST_FLAG_BUSY = 2, /* joining or already joined */ | 96 | IPOIB_MCAST_FLAG_BUSY = 2, /* joining or already joined */ |
| 97 | IPOIB_MCAST_FLAG_ATTACHED = 3, | 97 | IPOIB_MCAST_FLAG_ATTACHED = 3, |
| 98 | |||
| 99 | MAX_SEND_CQE = 16, | ||
| 98 | }; | 100 | }; |
| 99 | 101 | ||
| 100 | #define IPOIB_OP_RECV (1ul << 31) | 102 | #define IPOIB_OP_RECV (1ul << 31) |
| @@ -285,7 +287,8 @@ struct ipoib_dev_priv { | |||
| 285 | u16 pkey_index; | 287 | u16 pkey_index; |
| 286 | struct ib_pd *pd; | 288 | struct ib_pd *pd; |
| 287 | struct ib_mr *mr; | 289 | struct ib_mr *mr; |
| 288 | struct ib_cq *cq; | 290 | struct ib_cq *recv_cq; |
| 291 | struct ib_cq *send_cq; | ||
| 289 | struct ib_qp *qp; | 292 | struct ib_qp *qp; |
| 290 | u32 qkey; | 293 | u32 qkey; |
| 291 | 294 | ||
| @@ -305,6 +308,7 @@ struct ipoib_dev_priv { | |||
| 305 | struct ib_sge tx_sge[MAX_SKB_FRAGS + 1]; | 308 | struct ib_sge tx_sge[MAX_SKB_FRAGS + 1]; |
| 306 | struct ib_send_wr tx_wr; | 309 | struct ib_send_wr tx_wr; |
| 307 | unsigned tx_outstanding; | 310 | unsigned tx_outstanding; |
| 311 | struct ib_wc send_wc[MAX_SEND_CQE]; | ||
| 308 | 312 | ||
| 309 | struct ib_recv_wr rx_wr; | 313 | struct ib_recv_wr rx_wr; |
| 310 | struct ib_sge rx_sge[IPOIB_UD_RX_SG]; | 314 | struct ib_sge rx_sge[IPOIB_UD_RX_SG]; |
| @@ -662,7 +666,6 @@ static inline int ipoib_register_debugfs(void) { return 0; } | |||
| 662 | static inline void ipoib_unregister_debugfs(void) { } | 666 | static inline void ipoib_unregister_debugfs(void) { } |
| 663 | #endif | 667 | #endif |
| 664 | 668 | ||
| 665 | |||
| 666 | #define ipoib_printk(level, priv, format, arg...) \ | 669 | #define ipoib_printk(level, priv, format, arg...) \ |
| 667 | printk(level "%s: " format, ((struct ipoib_dev_priv *) priv)->dev->name , ## arg) | 670 | printk(level "%s: " format, ((struct ipoib_dev_priv *) priv)->dev->name , ## arg) |
| 668 | #define ipoib_warn(priv, format, arg...) \ | 671 | #define ipoib_warn(priv, format, arg...) \ |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 9db7b0bd9134..97e67d36378f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
| @@ -249,8 +249,8 @@ static struct ib_qp *ipoib_cm_create_rx_qp(struct net_device *dev, | |||
| 249 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 249 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 250 | struct ib_qp_init_attr attr = { | 250 | struct ib_qp_init_attr attr = { |
| 251 | .event_handler = ipoib_cm_rx_event_handler, | 251 | .event_handler = ipoib_cm_rx_event_handler, |
| 252 | .send_cq = priv->cq, /* For drain WR */ | 252 | .send_cq = priv->recv_cq, /* For drain WR */ |
| 253 | .recv_cq = priv->cq, | 253 | .recv_cq = priv->recv_cq, |
| 254 | .srq = priv->cm.srq, | 254 | .srq = priv->cm.srq, |
| 255 | .cap.max_send_wr = 1, /* For drain WR */ | 255 | .cap.max_send_wr = 1, /* For drain WR */ |
| 256 | .cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */ | 256 | .cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */ |
| @@ -951,8 +951,8 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_ | |||
| 951 | { | 951 | { |
| 952 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 952 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 953 | struct ib_qp_init_attr attr = { | 953 | struct ib_qp_init_attr attr = { |
| 954 | .send_cq = priv->cq, | 954 | .send_cq = priv->recv_cq, |
| 955 | .recv_cq = priv->cq, | 955 | .recv_cq = priv->recv_cq, |
| 956 | .srq = priv->cm.srq, | 956 | .srq = priv->cm.srq, |
| 957 | .cap.max_send_wr = ipoib_sendq_size, | 957 | .cap.max_send_wr = ipoib_sendq_size, |
| 958 | .cap.max_send_sge = 1, | 958 | .cap.max_send_sge = 1, |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c index 9a47428366c9..10279b79c44d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c | |||
| @@ -71,7 +71,7 @@ static int ipoib_set_coalesce(struct net_device *dev, | |||
| 71 | coal->rx_max_coalesced_frames > 0xffff) | 71 | coal->rx_max_coalesced_frames > 0xffff) |
| 72 | return -EINVAL; | 72 | return -EINVAL; |
| 73 | 73 | ||
| 74 | ret = ib_modify_cq(priv->cq, coal->rx_max_coalesced_frames, | 74 | ret = ib_modify_cq(priv->recv_cq, coal->rx_max_coalesced_frames, |
| 75 | coal->rx_coalesce_usecs); | 75 | coal->rx_coalesce_usecs); |
| 76 | if (ret && ret != -ENOSYS) { | 76 | if (ret && ret != -ENOSYS) { |
| 77 | ipoib_warn(priv, "failed modifying CQ (%d)\n", ret); | 77 | ipoib_warn(priv, "failed modifying CQ (%d)\n", ret); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 7cf1fa7074ab..97b815c1a3fc 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
| @@ -364,7 +364,6 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) | |||
| 364 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 364 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 365 | unsigned int wr_id = wc->wr_id; | 365 | unsigned int wr_id = wc->wr_id; |
| 366 | struct ipoib_tx_buf *tx_req; | 366 | struct ipoib_tx_buf *tx_req; |
| 367 | unsigned long flags; | ||
| 368 | 367 | ||
| 369 | ipoib_dbg_data(priv, "send completion: id %d, status: %d\n", | 368 | ipoib_dbg_data(priv, "send completion: id %d, status: %d\n", |
| 370 | wr_id, wc->status); | 369 | wr_id, wc->status); |
| @@ -384,13 +383,11 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) | |||
| 384 | 383 | ||
| 385 | dev_kfree_skb_any(tx_req->skb); | 384 | dev_kfree_skb_any(tx_req->skb); |
| 386 | 385 | ||
| 387 | spin_lock_irqsave(&priv->tx_lock, flags); | ||
| 388 | ++priv->tx_tail; | 386 | ++priv->tx_tail; |
| 389 | if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) && | 387 | if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) && |
| 390 | netif_queue_stopped(dev) && | 388 | netif_queue_stopped(dev) && |
| 391 | test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) | 389 | test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) |
| 392 | netif_wake_queue(dev); | 390 | netif_wake_queue(dev); |
| 393 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
| 394 | 391 | ||
| 395 | if (wc->status != IB_WC_SUCCESS && | 392 | if (wc->status != IB_WC_SUCCESS && |
| 396 | wc->status != IB_WC_WR_FLUSH_ERR) | 393 | wc->status != IB_WC_WR_FLUSH_ERR) |
| @@ -399,6 +396,17 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) | |||
| 399 | wc->status, wr_id, wc->vendor_err); | 396 | wc->status, wr_id, wc->vendor_err); |
| 400 | } | 397 | } |
| 401 | 398 | ||
| 399 | static int poll_tx(struct ipoib_dev_priv *priv) | ||
| 400 | { | ||
| 401 | int n, i; | ||
| 402 | |||
| 403 | n = ib_poll_cq(priv->send_cq, MAX_SEND_CQE, priv->send_wc); | ||
| 404 | for (i = 0; i < n; ++i) | ||
| 405 | ipoib_ib_handle_tx_wc(priv->dev, priv->send_wc + i); | ||
| 406 | |||
| 407 | return n == MAX_SEND_CQE; | ||
| 408 | } | ||
| 409 | |||
| 402 | int ipoib_poll(struct napi_struct *napi, int budget) | 410 | int ipoib_poll(struct napi_struct *napi, int budget) |
| 403 | { | 411 | { |
| 404 | struct ipoib_dev_priv *priv = container_of(napi, struct ipoib_dev_priv, napi); | 412 | struct ipoib_dev_priv *priv = container_of(napi, struct ipoib_dev_priv, napi); |
| @@ -414,7 +422,7 @@ poll_more: | |||
| 414 | int max = (budget - done); | 422 | int max = (budget - done); |
| 415 | 423 | ||
| 416 | t = min(IPOIB_NUM_WC, max); | 424 | t = min(IPOIB_NUM_WC, max); |
| 417 | n = ib_poll_cq(priv->cq, t, priv->ibwc); | 425 | n = ib_poll_cq(priv->recv_cq, t, priv->ibwc); |
| 418 | 426 | ||
| 419 | for (i = 0; i < n; i++) { | 427 | for (i = 0; i < n; i++) { |
| 420 | struct ib_wc *wc = priv->ibwc + i; | 428 | struct ib_wc *wc = priv->ibwc + i; |
| @@ -425,12 +433,8 @@ poll_more: | |||
| 425 | ipoib_cm_handle_rx_wc(dev, wc); | 433 | ipoib_cm_handle_rx_wc(dev, wc); |
| 426 | else | 434 | else |
| 427 | ipoib_ib_handle_rx_wc(dev, wc); | 435 | ipoib_ib_handle_rx_wc(dev, wc); |
| 428 | } else { | 436 | } else |
| 429 | if (wc->wr_id & IPOIB_OP_CM) | 437 | ipoib_cm_handle_tx_wc(priv->dev, wc); |
| 430 | ipoib_cm_handle_tx_wc(dev, wc); | ||
| 431 | else | ||
| 432 | ipoib_ib_handle_tx_wc(dev, wc); | ||
| 433 | } | ||
| 434 | } | 438 | } |
| 435 | 439 | ||
| 436 | if (n != t) | 440 | if (n != t) |
| @@ -439,7 +443,7 @@ poll_more: | |||
| 439 | 443 | ||
| 440 | if (done < budget) { | 444 | if (done < budget) { |
| 441 | netif_rx_complete(dev, napi); | 445 | netif_rx_complete(dev, napi); |
| 442 | if (unlikely(ib_req_notify_cq(priv->cq, | 446 | if (unlikely(ib_req_notify_cq(priv->recv_cq, |
| 443 | IB_CQ_NEXT_COMP | | 447 | IB_CQ_NEXT_COMP | |
| 444 | IB_CQ_REPORT_MISSED_EVENTS)) && | 448 | IB_CQ_REPORT_MISSED_EVENTS)) && |
| 445 | netif_rx_reschedule(dev, napi)) | 449 | netif_rx_reschedule(dev, napi)) |
| @@ -562,12 +566,16 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
| 562 | 566 | ||
| 563 | address->last_send = priv->tx_head; | 567 | address->last_send = priv->tx_head; |
| 564 | ++priv->tx_head; | 568 | ++priv->tx_head; |
| 569 | skb_orphan(skb); | ||
| 565 | 570 | ||
| 566 | if (++priv->tx_outstanding == ipoib_sendq_size) { | 571 | if (++priv->tx_outstanding == ipoib_sendq_size) { |
| 567 | ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); | 572 | ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); |
| 568 | netif_stop_queue(dev); | 573 | netif_stop_queue(dev); |
| 569 | } | 574 | } |
| 570 | } | 575 | } |
| 576 | |||
| 577 | if (unlikely(priv->tx_outstanding > MAX_SEND_CQE)) | ||
| 578 | poll_tx(priv); | ||
| 571 | } | 579 | } |
| 572 | 580 | ||
| 573 | static void __ipoib_reap_ah(struct net_device *dev) | 581 | static void __ipoib_reap_ah(struct net_device *dev) |
| @@ -714,7 +722,7 @@ void ipoib_drain_cq(struct net_device *dev) | |||
| 714 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 722 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 715 | int i, n; | 723 | int i, n; |
| 716 | do { | 724 | do { |
| 717 | n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc); | 725 | n = ib_poll_cq(priv->recv_cq, IPOIB_NUM_WC, priv->ibwc); |
| 718 | for (i = 0; i < n; ++i) { | 726 | for (i = 0; i < n; ++i) { |
| 719 | /* | 727 | /* |
| 720 | * Convert any successful completions to flush | 728 | * Convert any successful completions to flush |
| @@ -729,14 +737,13 @@ void ipoib_drain_cq(struct net_device *dev) | |||
| 729 | ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); | 737 | ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); |
| 730 | else | 738 | else |
| 731 | ipoib_ib_handle_rx_wc(dev, priv->ibwc + i); | 739 | ipoib_ib_handle_rx_wc(dev, priv->ibwc + i); |
| 732 | } else { | 740 | } else |
| 733 | if (priv->ibwc[i].wr_id & IPOIB_OP_CM) | 741 | ipoib_cm_handle_tx_wc(dev, priv->ibwc + i); |
| 734 | ipoib_cm_handle_tx_wc(dev, priv->ibwc + i); | ||
| 735 | else | ||
| 736 | ipoib_ib_handle_tx_wc(dev, priv->ibwc + i); | ||
| 737 | } | ||
| 738 | } | 742 | } |
| 739 | } while (n == IPOIB_NUM_WC); | 743 | } while (n == IPOIB_NUM_WC); |
| 744 | |||
| 745 | while (poll_tx(priv)) | ||
| 746 | ; /* nothing */ | ||
| 740 | } | 747 | } |
| 741 | 748 | ||
| 742 | int ipoib_ib_dev_stop(struct net_device *dev, int flush) | 749 | int ipoib_ib_dev_stop(struct net_device *dev, int flush) |
| @@ -826,7 +833,7 @@ timeout: | |||
| 826 | msleep(1); | 833 | msleep(1); |
| 827 | } | 834 | } |
| 828 | 835 | ||
| 829 | ib_req_notify_cq(priv->cq, IB_CQ_NEXT_COMP); | 836 | ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP); |
| 830 | 837 | ||
| 831 | return 0; | 838 | return 0; |
| 832 | } | 839 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 7a4ed9d3d844..2442090ac8d1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
| @@ -1298,7 +1298,8 @@ static int __init ipoib_init_module(void) | |||
| 1298 | 1298 | ||
| 1299 | ipoib_sendq_size = roundup_pow_of_two(ipoib_sendq_size); | 1299 | ipoib_sendq_size = roundup_pow_of_two(ipoib_sendq_size); |
| 1300 | ipoib_sendq_size = min(ipoib_sendq_size, IPOIB_MAX_QUEUE_SIZE); | 1300 | ipoib_sendq_size = min(ipoib_sendq_size, IPOIB_MAX_QUEUE_SIZE); |
| 1301 | ipoib_sendq_size = max(ipoib_sendq_size, IPOIB_MIN_QUEUE_SIZE); | 1301 | ipoib_sendq_size = max(ipoib_sendq_size, max(2 * MAX_SEND_CQE, |
| 1302 | IPOIB_MIN_QUEUE_SIZE)); | ||
| 1302 | #ifdef CONFIG_INFINIBAND_IPOIB_CM | 1303 | #ifdef CONFIG_INFINIBAND_IPOIB_CM |
| 1303 | ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP); | 1304 | ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP); |
| 1304 | #endif | 1305 | #endif |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 07c03f178a49..c1e7ece1fd44 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c | |||
| @@ -171,26 +171,33 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) | |||
| 171 | goto out_free_pd; | 171 | goto out_free_pd; |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | size = ipoib_sendq_size + ipoib_recvq_size + 1; | 174 | size = ipoib_recvq_size + 1; |
| 175 | ret = ipoib_cm_dev_init(dev); | 175 | ret = ipoib_cm_dev_init(dev); |
| 176 | if (!ret) { | 176 | if (!ret) { |
| 177 | size += ipoib_sendq_size; | ||
| 177 | if (ipoib_cm_has_srq(dev)) | 178 | if (ipoib_cm_has_srq(dev)) |
| 178 | size += ipoib_recvq_size + 1; /* 1 extra for rx_drain_qp */ | 179 | size += ipoib_recvq_size + 1; /* 1 extra for rx_drain_qp */ |
| 179 | else | 180 | else |
| 180 | size += ipoib_recvq_size * ipoib_max_conn_qp; | 181 | size += ipoib_recvq_size * ipoib_max_conn_qp; |
| 181 | } | 182 | } |
| 182 | 183 | ||
| 183 | priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, size, 0); | 184 | priv->recv_cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, size, 0); |
| 184 | if (IS_ERR(priv->cq)) { | 185 | if (IS_ERR(priv->recv_cq)) { |
| 185 | printk(KERN_WARNING "%s: failed to create CQ\n", ca->name); | 186 | printk(KERN_WARNING "%s: failed to create receive CQ\n", ca->name); |
| 186 | goto out_free_mr; | 187 | goto out_free_mr; |
| 187 | } | 188 | } |
| 188 | 189 | ||
| 189 | if (ib_req_notify_cq(priv->cq, IB_CQ_NEXT_COMP)) | 190 | priv->send_cq = ib_create_cq(priv->ca, NULL, NULL, dev, ipoib_sendq_size, 0); |
| 190 | goto out_free_cq; | 191 | if (IS_ERR(priv->send_cq)) { |
| 192 | printk(KERN_WARNING "%s: failed to create send CQ\n", ca->name); | ||
| 193 | goto out_free_recv_cq; | ||
| 194 | } | ||
| 195 | |||
| 196 | if (ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP)) | ||
| 197 | goto out_free_send_cq; | ||
| 191 | 198 | ||
| 192 | init_attr.send_cq = priv->cq; | 199 | init_attr.send_cq = priv->send_cq; |
| 193 | init_attr.recv_cq = priv->cq; | 200 | init_attr.recv_cq = priv->recv_cq; |
| 194 | 201 | ||
| 195 | if (priv->hca_caps & IB_DEVICE_UD_TSO) | 202 | if (priv->hca_caps & IB_DEVICE_UD_TSO) |
| 196 | init_attr.create_flags = IB_QP_CREATE_IPOIB_UD_LSO; | 203 | init_attr.create_flags = IB_QP_CREATE_IPOIB_UD_LSO; |
| @@ -201,7 +208,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) | |||
| 201 | priv->qp = ib_create_qp(priv->pd, &init_attr); | 208 | priv->qp = ib_create_qp(priv->pd, &init_attr); |
| 202 | if (IS_ERR(priv->qp)) { | 209 | if (IS_ERR(priv->qp)) { |
| 203 | printk(KERN_WARNING "%s: failed to create QP\n", ca->name); | 210 | printk(KERN_WARNING "%s: failed to create QP\n", ca->name); |
| 204 | goto out_free_cq; | 211 | goto out_free_send_cq; |
| 205 | } | 212 | } |
| 206 | 213 | ||
| 207 | priv->dev->dev_addr[1] = (priv->qp->qp_num >> 16) & 0xff; | 214 | priv->dev->dev_addr[1] = (priv->qp->qp_num >> 16) & 0xff; |
| @@ -230,8 +237,11 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) | |||
| 230 | 237 | ||
| 231 | return 0; | 238 | return 0; |
| 232 | 239 | ||
| 233 | out_free_cq: | 240 | out_free_send_cq: |
| 234 | ib_destroy_cq(priv->cq); | 241 | ib_destroy_cq(priv->send_cq); |
| 242 | |||
| 243 | out_free_recv_cq: | ||
| 244 | ib_destroy_cq(priv->recv_cq); | ||
| 235 | 245 | ||
| 236 | out_free_mr: | 246 | out_free_mr: |
| 237 | ib_dereg_mr(priv->mr); | 247 | ib_dereg_mr(priv->mr); |
| @@ -254,8 +264,11 @@ void ipoib_transport_dev_cleanup(struct net_device *dev) | |||
| 254 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 264 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); |
| 255 | } | 265 | } |
| 256 | 266 | ||
| 257 | if (ib_destroy_cq(priv->cq)) | 267 | if (ib_destroy_cq(priv->send_cq)) |
| 258 | ipoib_warn(priv, "ib_cq_destroy failed\n"); | 268 | ipoib_warn(priv, "ib_cq_destroy (send) failed\n"); |
| 269 | |||
| 270 | if (ib_destroy_cq(priv->recv_cq)) | ||
| 271 | ipoib_warn(priv, "ib_cq_destroy (recv) failed\n"); | ||
| 259 | 272 | ||
| 260 | ipoib_cm_dev_cleanup(dev); | 273 | ipoib_cm_dev_cleanup(dev); |
| 261 | 274 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index 431fdeaa2dc4..1cdb5cfb0ff1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c | |||
| @@ -90,6 +90,9 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) | |||
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | priv->max_ib_mtu = ppriv->max_ib_mtu; | 92 | priv->max_ib_mtu = ppriv->max_ib_mtu; |
| 93 | /* MTU will be reset when mcast join happens */ | ||
| 94 | priv->dev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu); | ||
| 95 | priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu; | ||
| 93 | set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags); | 96 | set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags); |
| 94 | 97 | ||
| 95 | priv->pkey = pkey; | 98 | priv->pkey = pkey; |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index be1b9fbd416d..aeb58cae9a3f 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
| @@ -473,13 +473,15 @@ iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *s | |||
| 473 | stats->r2t_pdus = conn->r2t_pdus_cnt; /* always 0 */ | 473 | stats->r2t_pdus = conn->r2t_pdus_cnt; /* always 0 */ |
| 474 | stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; | 474 | stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; |
| 475 | stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; | 475 | stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; |
| 476 | stats->custom_length = 3; | 476 | stats->custom_length = 4; |
| 477 | strcpy(stats->custom[0].desc, "qp_tx_queue_full"); | 477 | strcpy(stats->custom[0].desc, "qp_tx_queue_full"); |
| 478 | stats->custom[0].value = 0; /* TB iser_conn->qp_tx_queue_full; */ | 478 | stats->custom[0].value = 0; /* TB iser_conn->qp_tx_queue_full; */ |
| 479 | strcpy(stats->custom[1].desc, "fmr_map_not_avail"); | 479 | strcpy(stats->custom[1].desc, "fmr_map_not_avail"); |
| 480 | stats->custom[1].value = 0; /* TB iser_conn->fmr_map_not_avail */; | 480 | stats->custom[1].value = 0; /* TB iser_conn->fmr_map_not_avail */; |
| 481 | strcpy(stats->custom[2].desc, "eh_abort_cnt"); | 481 | strcpy(stats->custom[2].desc, "eh_abort_cnt"); |
| 482 | stats->custom[2].value = conn->eh_abort_cnt; | 482 | stats->custom[2].value = conn->eh_abort_cnt; |
| 483 | strcpy(stats->custom[3].desc, "fmr_unalign_cnt"); | ||
| 484 | stats->custom[3].value = conn->fmr_unalign_cnt; | ||
| 483 | } | 485 | } |
| 484 | 486 | ||
| 485 | static int | 487 | static int |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index 1ee867b1b341..a8c1b300e34d 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h | |||
| @@ -71,6 +71,13 @@ | |||
| 71 | 71 | ||
| 72 | #define iser_dbg(fmt, arg...) \ | 72 | #define iser_dbg(fmt, arg...) \ |
| 73 | do { \ | 73 | do { \ |
| 74 | if (iser_debug_level > 1) \ | ||
| 75 | printk(KERN_DEBUG PFX "%s:" fmt,\ | ||
| 76 | __func__ , ## arg); \ | ||
| 77 | } while (0) | ||
| 78 | |||
| 79 | #define iser_warn(fmt, arg...) \ | ||
| 80 | do { \ | ||
| 74 | if (iser_debug_level > 0) \ | 81 | if (iser_debug_level > 0) \ |
| 75 | printk(KERN_DEBUG PFX "%s:" fmt,\ | 82 | printk(KERN_DEBUG PFX "%s:" fmt,\ |
| 76 | __func__ , ## arg); \ | 83 | __func__ , ## arg); \ |
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index 4a17743a639f..cac50c4dc159 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c | |||
| @@ -334,8 +334,11 @@ static void iser_data_buf_dump(struct iser_data_buf *data, | |||
| 334 | struct scatterlist *sg; | 334 | struct scatterlist *sg; |
| 335 | int i; | 335 | int i; |
| 336 | 336 | ||
| 337 | if (iser_debug_level == 0) | ||
| 338 | return; | ||
| 339 | |||
| 337 | for_each_sg(sgl, sg, data->dma_nents, i) | 340 | for_each_sg(sgl, sg, data->dma_nents, i) |
| 338 | iser_err("sg[%d] dma_addr:0x%lX page:0x%p " | 341 | iser_warn("sg[%d] dma_addr:0x%lX page:0x%p " |
| 339 | "off:0x%x sz:0x%x dma_len:0x%x\n", | 342 | "off:0x%x sz:0x%x dma_len:0x%x\n", |
| 340 | i, (unsigned long)ib_sg_dma_address(ibdev, sg), | 343 | i, (unsigned long)ib_sg_dma_address(ibdev, sg), |
| 341 | sg_page(sg), sg->offset, | 344 | sg_page(sg), sg->offset, |
| @@ -420,6 +423,7 @@ void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask) | |||
| 420 | int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask, | 423 | int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask, |
| 421 | enum iser_data_dir cmd_dir) | 424 | enum iser_data_dir cmd_dir) |
| 422 | { | 425 | { |
| 426 | struct iscsi_conn *iscsi_conn = iser_ctask->iser_conn->iscsi_conn; | ||
| 423 | struct iser_conn *ib_conn = iser_ctask->iser_conn->ib_conn; | 427 | struct iser_conn *ib_conn = iser_ctask->iser_conn->ib_conn; |
| 424 | struct iser_device *device = ib_conn->device; | 428 | struct iser_device *device = ib_conn->device; |
| 425 | struct ib_device *ibdev = device->ib_device; | 429 | struct ib_device *ibdev = device->ib_device; |
| @@ -434,7 +438,8 @@ int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask, | |||
| 434 | 438 | ||
| 435 | aligned_len = iser_data_buf_aligned_len(mem, ibdev); | 439 | aligned_len = iser_data_buf_aligned_len(mem, ibdev); |
| 436 | if (aligned_len != mem->dma_nents) { | 440 | if (aligned_len != mem->dma_nents) { |
| 437 | iser_err("rdma alignment violation %d/%d aligned\n", | 441 | iscsi_conn->fmr_unalign_cnt++; |
| 442 | iser_warn("rdma alignment violation %d/%d aligned\n", | ||
| 438 | aligned_len, mem->size); | 443 | aligned_len, mem->size); |
| 439 | iser_data_buf_dump(mem, ibdev); | 444 | iser_data_buf_dump(mem, ibdev); |
| 440 | 445 | ||
diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h index 229303ff6a39..a0177fc55e28 100644 --- a/drivers/net/cxgb3/version.h +++ b/drivers/net/cxgb3/version.h | |||
| @@ -38,7 +38,7 @@ | |||
| 38 | #define DRV_VERSION "1.0-ko" | 38 | #define DRV_VERSION "1.0-ko" |
| 39 | 39 | ||
| 40 | /* Firmware version */ | 40 | /* Firmware version */ |
| 41 | #define FW_VERSION_MAJOR 5 | 41 | #define FW_VERSION_MAJOR 6 |
| 42 | #define FW_VERSION_MINOR 0 | 42 | #define FW_VERSION_MINOR 0 |
| 43 | #define FW_VERSION_MICRO 0 | 43 | #define FW_VERSION_MICRO 0 |
| 44 | #endif /* __CHELSIO_VERSION_H */ | 44 | #endif /* __CHELSIO_VERSION_H */ |
diff --git a/drivers/net/mlx4/cq.c b/drivers/net/mlx4/cq.c index 6fda0af9d0a6..95e87a2f8896 100644 --- a/drivers/net/mlx4/cq.c +++ b/drivers/net/mlx4/cq.c | |||
| @@ -188,7 +188,8 @@ int mlx4_cq_resize(struct mlx4_dev *dev, struct mlx4_cq *cq, | |||
| 188 | EXPORT_SYMBOL_GPL(mlx4_cq_resize); | 188 | EXPORT_SYMBOL_GPL(mlx4_cq_resize); |
| 189 | 189 | ||
| 190 | int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt, | 190 | int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt, |
| 191 | struct mlx4_uar *uar, u64 db_rec, struct mlx4_cq *cq) | 191 | struct mlx4_uar *uar, u64 db_rec, struct mlx4_cq *cq, |
| 192 | int collapsed) | ||
| 192 | { | 193 | { |
| 193 | struct mlx4_priv *priv = mlx4_priv(dev); | 194 | struct mlx4_priv *priv = mlx4_priv(dev); |
| 194 | struct mlx4_cq_table *cq_table = &priv->cq_table; | 195 | struct mlx4_cq_table *cq_table = &priv->cq_table; |
| @@ -224,6 +225,7 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt, | |||
| 224 | cq_context = mailbox->buf; | 225 | cq_context = mailbox->buf; |
| 225 | memset(cq_context, 0, sizeof *cq_context); | 226 | memset(cq_context, 0, sizeof *cq_context); |
| 226 | 227 | ||
| 228 | cq_context->flags = cpu_to_be32(!!collapsed << 18); | ||
| 227 | cq_context->logsize_usrpage = cpu_to_be32((ilog2(nent) << 24) | uar->index); | 229 | cq_context->logsize_usrpage = cpu_to_be32((ilog2(nent) << 24) | uar->index); |
| 228 | cq_context->comp_eqn = priv->eq_table.eq[MLX4_EQ_COMP].eqn; | 230 | cq_context->comp_eqn = priv->eq_table.eq[MLX4_EQ_COMP].eqn; |
| 229 | cq_context->log_page_size = mtt->page_shift - MLX4_ICM_PAGE_SHIFT; | 231 | cq_context->log_page_size = mtt->page_shift - MLX4_ICM_PAGE_SHIFT; |
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c index 79b317b88c86..cb46446b2691 100644 --- a/drivers/net/mlx4/mr.c +++ b/drivers/net/mlx4/mr.c | |||
| @@ -607,15 +607,9 @@ EXPORT_SYMBOL_GPL(mlx4_fmr_enable); | |||
| 607 | void mlx4_fmr_unmap(struct mlx4_dev *dev, struct mlx4_fmr *fmr, | 607 | void mlx4_fmr_unmap(struct mlx4_dev *dev, struct mlx4_fmr *fmr, |
| 608 | u32 *lkey, u32 *rkey) | 608 | u32 *lkey, u32 *rkey) |
| 609 | { | 609 | { |
| 610 | u32 key; | ||
| 611 | |||
| 612 | if (!fmr->maps) | 610 | if (!fmr->maps) |
| 613 | return; | 611 | return; |
| 614 | 612 | ||
| 615 | key = key_to_hw_index(fmr->mr.key); | ||
| 616 | key &= dev->caps.num_mpts - 1; | ||
| 617 | *lkey = *rkey = fmr->mr.key = hw_index_to_key(key); | ||
| 618 | |||
| 619 | fmr->maps = 0; | 613 | fmr->maps = 0; |
| 620 | 614 | ||
| 621 | *(u8 *) fmr->mpt = MLX4_MPT_STATUS_SW; | 615 | *(u8 *) fmr->mpt = MLX4_MPT_STATUS_SW; |
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index e83b166aa6b9..432e837a1760 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c | |||
| @@ -649,7 +649,7 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd) | |||
| 649 | DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]); | 649 | DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]); |
| 650 | } | 650 | } |
| 651 | 651 | ||
| 652 | if (!capable(CAP_NET_ADMIN)) | 652 | if (!capable(CAP_SYS_RAWIO)) |
| 653 | return -EPERM; | 653 | return -EPERM; |
| 654 | 654 | ||
| 655 | switch (data[0]) { | 655 | switch (data[0]) { |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index b0f9ad362d1d..946466cd9f25 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
| @@ -357,7 +357,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 357 | printk(KERN_WARNING "hfs: Filesystem is marked locked, mounting read-only.\n"); | 357 | printk(KERN_WARNING "hfs: Filesystem is marked locked, mounting read-only.\n"); |
| 358 | sb->s_flags |= MS_RDONLY; | 358 | sb->s_flags |= MS_RDONLY; |
| 359 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { | 359 | } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { |
| 360 | printk(KERN_WARNING "hfs: write access to a jounaled filesystem is not supported, " | 360 | printk(KERN_WARNING "hfs: write access to a journaled filesystem is not supported, " |
| 361 | "use the force option at your own risk, mounting read-only.\n"); | 361 | "use the force option at your own risk, mounting read-only.\n"); |
| 362 | sb->s_flags |= MS_RDONLY; | 362 | sb->s_flags |= MS_RDONLY; |
| 363 | } | 363 | } |
diff --git a/include/linux/audit.h b/include/linux/audit.h index 4ccb048cae1d..63c3bb98558f 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
| @@ -146,7 +146,7 @@ | |||
| 146 | /* Rule structure sizes -- if these change, different AUDIT_ADD and | 146 | /* Rule structure sizes -- if these change, different AUDIT_ADD and |
| 147 | * AUDIT_LIST commands must be implemented. */ | 147 | * AUDIT_LIST commands must be implemented. */ |
| 148 | #define AUDIT_MAX_FIELDS 64 | 148 | #define AUDIT_MAX_FIELDS 64 |
| 149 | #define AUDIT_MAX_KEY_LEN 32 | 149 | #define AUDIT_MAX_KEY_LEN 256 |
| 150 | #define AUDIT_BITMASK_SIZE 64 | 150 | #define AUDIT_BITMASK_SIZE 64 |
| 151 | #define AUDIT_WORD(nr) ((__u32)((nr)/32)) | 151 | #define AUDIT_WORD(nr) ((__u32)((nr)/32)) |
| 152 | #define AUDIT_BIT(nr) (1 << ((nr) - AUDIT_WORD(nr)*32)) | 152 | #define AUDIT_BIT(nr) (1 << ((nr) - AUDIT_WORD(nr)*32)) |
| @@ -209,6 +209,7 @@ | |||
| 209 | #define AUDIT_WATCH 105 | 209 | #define AUDIT_WATCH 105 |
| 210 | #define AUDIT_PERM 106 | 210 | #define AUDIT_PERM 106 |
| 211 | #define AUDIT_DIR 107 | 211 | #define AUDIT_DIR 107 |
| 212 | #define AUDIT_FILETYPE 108 | ||
| 212 | 213 | ||
| 213 | #define AUDIT_ARG0 200 | 214 | #define AUDIT_ARG0 200 |
| 214 | #define AUDIT_ARG1 (AUDIT_ARG0+1) | 215 | #define AUDIT_ARG1 (AUDIT_ARG0+1) |
| @@ -549,16 +550,20 @@ extern void audit_log_format(struct audit_buffer *ab, | |||
| 549 | const char *fmt, ...) | 550 | const char *fmt, ...) |
| 550 | __attribute__((format(printf,2,3))); | 551 | __attribute__((format(printf,2,3))); |
| 551 | extern void audit_log_end(struct audit_buffer *ab); | 552 | extern void audit_log_end(struct audit_buffer *ab); |
| 552 | extern void audit_log_hex(struct audit_buffer *ab, | ||
| 553 | const unsigned char *buf, | ||
| 554 | size_t len); | ||
| 555 | extern int audit_string_contains_control(const char *string, | 553 | extern int audit_string_contains_control(const char *string, |
| 556 | size_t len); | 554 | size_t len); |
| 555 | extern void audit_log_n_hex(struct audit_buffer *ab, | ||
| 556 | const unsigned char *buf, | ||
| 557 | size_t len); | ||
| 558 | extern void audit_log_n_string(struct audit_buffer *ab, | ||
| 559 | const char *buf, | ||
| 560 | size_t n); | ||
| 561 | #define audit_log_string(a,b) audit_log_n_string(a, b, strlen(b)); | ||
| 562 | extern void audit_log_n_untrustedstring(struct audit_buffer *ab, | ||
| 563 | const char *string, | ||
| 564 | size_t n); | ||
| 557 | extern void audit_log_untrustedstring(struct audit_buffer *ab, | 565 | extern void audit_log_untrustedstring(struct audit_buffer *ab, |
| 558 | const char *string); | 566 | const char *string); |
| 559 | extern void audit_log_n_untrustedstring(struct audit_buffer *ab, | ||
| 560 | size_t n, | ||
| 561 | const char *string); | ||
| 562 | extern void audit_log_d_path(struct audit_buffer *ab, | 567 | extern void audit_log_d_path(struct audit_buffer *ab, |
| 563 | const char *prefix, | 568 | const char *prefix, |
| 564 | struct path *path); | 569 | struct path *path); |
| @@ -569,7 +574,8 @@ extern int audit_update_lsm_rules(void); | |||
| 569 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); | 574 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); |
| 570 | extern int audit_filter_type(int type); | 575 | extern int audit_filter_type(int type); |
| 571 | extern int audit_receive_filter(int type, int pid, int uid, int seq, | 576 | extern int audit_receive_filter(int type, int pid, int uid, int seq, |
| 572 | void *data, size_t datasz, uid_t loginuid, u32 sid); | 577 | void *data, size_t datasz, uid_t loginuid, |
| 578 | u32 sessionid, u32 sid); | ||
| 573 | extern int audit_enabled; | 579 | extern int audit_enabled; |
| 574 | #else | 580 | #else |
| 575 | #define audit_log(c,g,t,f,...) do { ; } while (0) | 581 | #define audit_log(c,g,t,f,...) do { ; } while (0) |
| @@ -577,9 +583,11 @@ extern int audit_enabled; | |||
| 577 | #define audit_log_vformat(b,f,a) do { ; } while (0) | 583 | #define audit_log_vformat(b,f,a) do { ; } while (0) |
| 578 | #define audit_log_format(b,f,...) do { ; } while (0) | 584 | #define audit_log_format(b,f,...) do { ; } while (0) |
| 579 | #define audit_log_end(b) do { ; } while (0) | 585 | #define audit_log_end(b) do { ; } while (0) |
| 580 | #define audit_log_hex(a,b,l) do { ; } while (0) | 586 | #define audit_log_n_hex(a,b,l) do { ; } while (0) |
| 581 | #define audit_log_untrustedstring(a,s) do { ; } while (0) | 587 | #define audit_log_n_string(a,c,l) do { ; } while (0) |
| 588 | #define audit_log_string(a,c) do { ; } while (0) | ||
| 582 | #define audit_log_n_untrustedstring(a,n,s) do { ; } while (0) | 589 | #define audit_log_n_untrustedstring(a,n,s) do { ; } while (0) |
| 590 | #define audit_log_untrustedstring(a,s) do { ; } while (0) | ||
| 583 | #define audit_log_d_path(b, p, d) do { ; } while (0) | 591 | #define audit_log_d_path(b, p, d) do { ; } while (0) |
| 584 | #define audit_enabled 0 | 592 | #define audit_enabled 0 |
| 585 | #endif | 593 | #endif |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 95864b3ff298..d2a1b71e93c3 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -412,8 +412,12 @@ struct request_queue | |||
| 412 | 412 | ||
| 413 | static inline int queue_is_locked(struct request_queue *q) | 413 | static inline int queue_is_locked(struct request_queue *q) |
| 414 | { | 414 | { |
| 415 | #ifdef CONFIG_SMP | ||
| 415 | spinlock_t *lock = q->queue_lock; | 416 | spinlock_t *lock = q->queue_lock; |
| 416 | return lock && spin_is_locked(lock); | 417 | return lock && spin_is_locked(lock); |
| 418 | #else | ||
| 419 | return 1; | ||
| 420 | #endif | ||
| 417 | } | 421 | } |
| 418 | 422 | ||
| 419 | static inline void queue_flag_set_unlocked(unsigned int flag, | 423 | static inline void queue_flag_set_unlocked(unsigned int flag, |
diff --git a/include/linux/capability.h b/include/linux/capability.h index eaab759b1460..f4ea0dd9a618 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h | |||
| @@ -365,12 +365,12 @@ typedef struct kernel_cap_struct { | |||
| 365 | # error Fix up hand-coded capability macro initializers | 365 | # error Fix up hand-coded capability macro initializers |
| 366 | #else /* HAND-CODED capability initializers */ | 366 | #else /* HAND-CODED capability initializers */ |
| 367 | 367 | ||
| 368 | # define CAP_EMPTY_SET {{ 0, 0 }} | 368 | # define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }}) |
| 369 | # define CAP_FULL_SET {{ ~0, ~0 }} | 369 | # define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) |
| 370 | # define CAP_INIT_EFF_SET {{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }} | 370 | # define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }}) |
| 371 | # define CAP_FS_SET {{ CAP_FS_MASK_B0, CAP_FS_MASK_B1 } } | 371 | # define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0, CAP_FS_MASK_B1 } }) |
| 372 | # define CAP_NFSD_SET {{ CAP_FS_MASK_B0|CAP_TO_MASK(CAP_SYS_RESOURCE), \ | 372 | # define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0|CAP_TO_MASK(CAP_SYS_RESOURCE), \ |
| 373 | CAP_FS_MASK_B1 } } | 373 | CAP_FS_MASK_B1 } }) |
| 374 | 374 | ||
| 375 | #endif /* _LINUX_CAPABILITY_U32S != 2 */ | 375 | #endif /* _LINUX_CAPABILITY_U32S != 2 */ |
| 376 | 376 | ||
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 9fa1a8002ce2..a744383d16e9 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
| @@ -382,7 +382,8 @@ void mlx4_free_hwq_res(struct mlx4_dev *mdev, struct mlx4_hwq_resources *wqres, | |||
| 382 | int size); | 382 | int size); |
| 383 | 383 | ||
| 384 | int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt, | 384 | int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt, |
| 385 | struct mlx4_uar *uar, u64 db_rec, struct mlx4_cq *cq); | 385 | struct mlx4_uar *uar, u64 db_rec, struct mlx4_cq *cq, |
| 386 | int collapsed); | ||
| 386 | void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq); | 387 | void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq); |
| 387 | 388 | ||
| 388 | int mlx4_qp_alloc(struct mlx4_dev *dev, int sqpn, struct mlx4_qp *qp); | 389 | int mlx4_qp_alloc(struct mlx4_dev *dev, int sqpn, struct mlx4_qp *qp); |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index fb0713b6ffaf..bec1062a25a1 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
| @@ -166,6 +166,7 @@ struct netlink_skb_parms | |||
| 166 | __u32 dst_group; | 166 | __u32 dst_group; |
| 167 | kernel_cap_t eff_cap; | 167 | kernel_cap_t eff_cap; |
| 168 | __u32 loginuid; /* Login (audit) uid */ | 168 | __u32 loginuid; /* Login (audit) uid */ |
| 169 | __u32 sessionid; /* Session id (audit) */ | ||
| 169 | __u32 sid; /* SELinux security id */ | 170 | __u32 sid; /* SELinux security id */ |
| 170 | }; | 171 | }; |
| 171 | 172 | ||
diff --git a/include/linux/security.h b/include/linux/security.h index adb09d893ae0..50737c70e78e 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -1481,7 +1481,7 @@ struct security_operations { | |||
| 1481 | int (*getprocattr) (struct task_struct *p, char *name, char **value); | 1481 | int (*getprocattr) (struct task_struct *p, char *name, char **value); |
| 1482 | int (*setprocattr) (struct task_struct *p, char *name, void *value, size_t size); | 1482 | int (*setprocattr) (struct task_struct *p, char *name, void *value, size_t size); |
| 1483 | int (*secid_to_secctx) (u32 secid, char **secdata, u32 *seclen); | 1483 | int (*secid_to_secctx) (u32 secid, char **secdata, u32 *seclen); |
| 1484 | int (*secctx_to_secid) (char *secdata, u32 seclen, u32 *secid); | 1484 | int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid); |
| 1485 | void (*release_secctx) (char *secdata, u32 seclen); | 1485 | void (*release_secctx) (char *secdata, u32 seclen); |
| 1486 | 1486 | ||
| 1487 | #ifdef CONFIG_SECURITY_NETWORK | 1487 | #ifdef CONFIG_SECURITY_NETWORK |
| @@ -1730,7 +1730,7 @@ int security_setprocattr(struct task_struct *p, char *name, void *value, size_t | |||
| 1730 | int security_netlink_send(struct sock *sk, struct sk_buff *skb); | 1730 | int security_netlink_send(struct sock *sk, struct sk_buff *skb); |
| 1731 | int security_netlink_recv(struct sk_buff *skb, int cap); | 1731 | int security_netlink_recv(struct sk_buff *skb, int cap); |
| 1732 | int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); | 1732 | int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); |
| 1733 | int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid); | 1733 | int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); |
| 1734 | void security_release_secctx(char *secdata, u32 seclen); | 1734 | void security_release_secctx(char *secdata, u32 seclen); |
| 1735 | 1735 | ||
| 1736 | #else /* CONFIG_SECURITY */ | 1736 | #else /* CONFIG_SECURITY */ |
| @@ -2449,7 +2449,7 @@ static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *secle | |||
| 2449 | return -EOPNOTSUPP; | 2449 | return -EOPNOTSUPP; |
| 2450 | } | 2450 | } |
| 2451 | 2451 | ||
| 2452 | static inline int security_secctx_to_secid(char *secdata, | 2452 | static inline int security_secctx_to_secid(const char *secdata, |
| 2453 | u32 seclen, | 2453 | u32 seclen, |
| 2454 | u32 *secid) | 2454 | u32 *secid) |
| 2455 | { | 2455 | { |
diff --git a/include/linux/tty.h b/include/linux/tty.h index dd8e08fe8855..265831ccaa88 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
| @@ -300,7 +300,6 @@ extern void tty_hangup(struct tty_struct * tty); | |||
| 300 | extern void tty_vhangup(struct tty_struct * tty); | 300 | extern void tty_vhangup(struct tty_struct * tty); |
| 301 | extern void tty_unhangup(struct file *filp); | 301 | extern void tty_unhangup(struct file *filp); |
| 302 | extern int tty_hung_up_p(struct file * filp); | 302 | extern int tty_hung_up_p(struct file * filp); |
| 303 | extern int is_tty(struct file *filp); | ||
| 304 | extern void do_SAK(struct tty_struct *tty); | 303 | extern void do_SAK(struct tty_struct *tty); |
| 305 | extern void __do_SAK(struct tty_struct *tty); | 304 | extern void __do_SAK(struct tty_struct *tty); |
| 306 | extern void disassociate_ctty(int priv); | 305 | extern void disassociate_ctty(int priv); |
| @@ -351,8 +350,7 @@ extern void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, | |||
| 351 | extern void tty_audit_exit(void); | 350 | extern void tty_audit_exit(void); |
| 352 | extern void tty_audit_fork(struct signal_struct *sig); | 351 | extern void tty_audit_fork(struct signal_struct *sig); |
| 353 | extern void tty_audit_push(struct tty_struct *tty); | 352 | extern void tty_audit_push(struct tty_struct *tty); |
| 354 | extern void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid); | 353 | extern void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid); |
| 355 | extern void tty_audit_opening(void); | ||
| 356 | #else | 354 | #else |
| 357 | static inline void tty_audit_add_data(struct tty_struct *tty, | 355 | static inline void tty_audit_add_data(struct tty_struct *tty, |
| 358 | unsigned char *data, size_t size) | 356 | unsigned char *data, size_t size) |
| @@ -367,10 +365,7 @@ static inline void tty_audit_fork(struct signal_struct *sig) | |||
| 367 | static inline void tty_audit_push(struct tty_struct *tty) | 365 | static inline void tty_audit_push(struct tty_struct *tty) |
| 368 | { | 366 | { |
| 369 | } | 367 | } |
| 370 | static inline void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid) | 368 | static inline void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid) |
| 371 | { | ||
| 372 | } | ||
| 373 | static inline void tty_audit_opening(void) | ||
| 374 | { | 369 | { |
| 375 | } | 370 | } |
| 376 | #endif | 371 | #endif |
diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 5e53a85b5ca1..e4d2d6baa983 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h | |||
| @@ -103,6 +103,7 @@ struct cipso_v4_doi; | |||
| 103 | struct netlbl_audit { | 103 | struct netlbl_audit { |
| 104 | u32 secid; | 104 | u32 secid; |
| 105 | uid_t loginuid; | 105 | uid_t loginuid; |
| 106 | u32 sessionid; | ||
| 106 | }; | 107 | }; |
| 107 | 108 | ||
| 108 | /* | 109 | /* |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index baa9f372cfd1..d1350bcccb03 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
| @@ -597,8 +597,9 @@ struct xfrm_spi_skb_cb { | |||
| 597 | /* Audit Information */ | 597 | /* Audit Information */ |
| 598 | struct xfrm_audit | 598 | struct xfrm_audit |
| 599 | { | 599 | { |
| 600 | u32 loginuid; | ||
| 601 | u32 secid; | 600 | u32 secid; |
| 601 | uid_t loginuid; | ||
| 602 | u32 sessionid; | ||
| 602 | }; | 603 | }; |
| 603 | 604 | ||
| 604 | #ifdef CONFIG_AUDITSYSCALL | 605 | #ifdef CONFIG_AUDITSYSCALL |
| @@ -616,13 +617,13 @@ static inline struct audit_buffer *xfrm_audit_start(const char *op) | |||
| 616 | return audit_buf; | 617 | return audit_buf; |
| 617 | } | 618 | } |
| 618 | 619 | ||
| 619 | static inline void xfrm_audit_helper_usrinfo(u32 auid, u32 secid, | 620 | static inline void xfrm_audit_helper_usrinfo(uid_t auid, u32 ses, u32 secid, |
| 620 | struct audit_buffer *audit_buf) | 621 | struct audit_buffer *audit_buf) |
| 621 | { | 622 | { |
| 622 | char *secctx; | 623 | char *secctx; |
| 623 | u32 secctx_len; | 624 | u32 secctx_len; |
| 624 | 625 | ||
| 625 | audit_log_format(audit_buf, " auid=%u", auid); | 626 | audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses); |
| 626 | if (secid != 0 && | 627 | if (secid != 0 && |
| 627 | security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) { | 628 | security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) { |
| 628 | audit_log_format(audit_buf, " subj=%s", secctx); | 629 | audit_log_format(audit_buf, " subj=%s", secctx); |
| @@ -632,13 +633,13 @@ static inline void xfrm_audit_helper_usrinfo(u32 auid, u32 secid, | |||
| 632 | } | 633 | } |
| 633 | 634 | ||
| 634 | extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | 635 | extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, |
| 635 | u32 auid, u32 secid); | 636 | u32 auid, u32 ses, u32 secid); |
| 636 | extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, | 637 | extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, |
| 637 | u32 auid, u32 secid); | 638 | u32 auid, u32 ses, u32 secid); |
| 638 | extern void xfrm_audit_state_add(struct xfrm_state *x, int result, | 639 | extern void xfrm_audit_state_add(struct xfrm_state *x, int result, |
| 639 | u32 auid, u32 secid); | 640 | u32 auid, u32 ses, u32 secid); |
| 640 | extern void xfrm_audit_state_delete(struct xfrm_state *x, int result, | 641 | extern void xfrm_audit_state_delete(struct xfrm_state *x, int result, |
| 641 | u32 auid, u32 secid); | 642 | u32 auid, u32 ses, u32 secid); |
| 642 | extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x, | 643 | extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x, |
| 643 | struct sk_buff *skb); | 644 | struct sk_buff *skb); |
| 644 | extern void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family); | 645 | extern void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family); |
| @@ -647,10 +648,10 @@ extern void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, | |||
| 647 | extern void xfrm_audit_state_icvfail(struct xfrm_state *x, | 648 | extern void xfrm_audit_state_icvfail(struct xfrm_state *x, |
| 648 | struct sk_buff *skb, u8 proto); | 649 | struct sk_buff *skb, u8 proto); |
| 649 | #else | 650 | #else |
| 650 | #define xfrm_audit_policy_add(x, r, a, s) do { ; } while (0) | 651 | #define xfrm_audit_policy_add(x, r, a, se, s) do { ; } while (0) |
| 651 | #define xfrm_audit_policy_delete(x, r, a, s) do { ; } while (0) | 652 | #define xfrm_audit_policy_delete(x, r, a, se, s) do { ; } while (0) |
| 652 | #define xfrm_audit_state_add(x, r, a, s) do { ; } while (0) | 653 | #define xfrm_audit_state_add(x, r, a, se, s) do { ; } while (0) |
| 653 | #define xfrm_audit_state_delete(x, r, a, s) do { ; } while (0) | 654 | #define xfrm_audit_state_delete(x, r, a, se, s) do { ; } while (0) |
| 654 | #define xfrm_audit_state_replay_overflow(x, s) do { ; } while (0) | 655 | #define xfrm_audit_state_replay_overflow(x, s) do { ; } while (0) |
| 655 | #define xfrm_audit_state_notfound_simple(s, f) do { ; } while (0) | 656 | #define xfrm_audit_state_notfound_simple(s, f) do { ; } while (0) |
| 656 | #define xfrm_audit_state_notfound(s, f, sp, sq) do { ; } while (0) | 657 | #define xfrm_audit_state_notfound(s, f, sp, sq) do { ; } while (0) |
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 7b90b63fb5c7..cd3ca63d4fb1 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h | |||
| @@ -225,6 +225,7 @@ struct iscsi_conn { | |||
| 225 | 225 | ||
| 226 | /* custom statistics */ | 226 | /* custom statistics */ |
| 227 | uint32_t eh_abort_cnt; | 227 | uint32_t eh_abort_cnt; |
| 228 | uint32_t fmr_unalign_cnt; | ||
| 228 | }; | 229 | }; |
| 229 | 230 | ||
| 230 | struct iscsi_pool { | 231 | struct iscsi_pool { |
diff --git a/kernel/audit.c b/kernel/audit.c index a7b16086d36f..b7d3709cc452 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -126,6 +126,8 @@ static int audit_freelist_count; | |||
| 126 | static LIST_HEAD(audit_freelist); | 126 | static LIST_HEAD(audit_freelist); |
| 127 | 127 | ||
| 128 | static struct sk_buff_head audit_skb_queue; | 128 | static struct sk_buff_head audit_skb_queue; |
| 129 | /* queue of skbs to send to auditd when/if it comes back */ | ||
| 130 | static struct sk_buff_head audit_skb_hold_queue; | ||
| 129 | static struct task_struct *kauditd_task; | 131 | static struct task_struct *kauditd_task; |
| 130 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); | 132 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); |
| 131 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); | 133 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); |
| @@ -154,6 +156,11 @@ struct audit_buffer { | |||
| 154 | gfp_t gfp_mask; | 156 | gfp_t gfp_mask; |
| 155 | }; | 157 | }; |
| 156 | 158 | ||
| 159 | struct audit_reply { | ||
| 160 | int pid; | ||
| 161 | struct sk_buff *skb; | ||
| 162 | }; | ||
| 163 | |||
| 157 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) | 164 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) |
| 158 | { | 165 | { |
| 159 | if (ab) { | 166 | if (ab) { |
| @@ -252,14 +259,15 @@ void audit_log_lost(const char *message) | |||
| 252 | } | 259 | } |
| 253 | 260 | ||
| 254 | static int audit_log_config_change(char *function_name, int new, int old, | 261 | static int audit_log_config_change(char *function_name, int new, int old, |
| 255 | uid_t loginuid, u32 sid, int allow_changes) | 262 | uid_t loginuid, u32 sessionid, u32 sid, |
| 263 | int allow_changes) | ||
| 256 | { | 264 | { |
| 257 | struct audit_buffer *ab; | 265 | struct audit_buffer *ab; |
| 258 | int rc = 0; | 266 | int rc = 0; |
| 259 | 267 | ||
| 260 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 268 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
| 261 | audit_log_format(ab, "%s=%d old=%d by auid=%u", function_name, new, | 269 | audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new, |
| 262 | old, loginuid); | 270 | old, loginuid, sessionid); |
| 263 | if (sid) { | 271 | if (sid) { |
| 264 | char *ctx = NULL; | 272 | char *ctx = NULL; |
| 265 | u32 len; | 273 | u32 len; |
| @@ -279,7 +287,8 @@ static int audit_log_config_change(char *function_name, int new, int old, | |||
| 279 | } | 287 | } |
| 280 | 288 | ||
| 281 | static int audit_do_config_change(char *function_name, int *to_change, | 289 | static int audit_do_config_change(char *function_name, int *to_change, |
| 282 | int new, uid_t loginuid, u32 sid) | 290 | int new, uid_t loginuid, u32 sessionid, |
| 291 | u32 sid) | ||
| 283 | { | 292 | { |
| 284 | int allow_changes, rc = 0, old = *to_change; | 293 | int allow_changes, rc = 0, old = *to_change; |
| 285 | 294 | ||
| @@ -290,8 +299,8 @@ static int audit_do_config_change(char *function_name, int *to_change, | |||
| 290 | allow_changes = 1; | 299 | allow_changes = 1; |
| 291 | 300 | ||
| 292 | if (audit_enabled != AUDIT_OFF) { | 301 | if (audit_enabled != AUDIT_OFF) { |
| 293 | rc = audit_log_config_change(function_name, new, old, | 302 | rc = audit_log_config_change(function_name, new, old, loginuid, |
| 294 | loginuid, sid, allow_changes); | 303 | sessionid, sid, allow_changes); |
| 295 | if (rc) | 304 | if (rc) |
| 296 | allow_changes = 0; | 305 | allow_changes = 0; |
| 297 | } | 306 | } |
| @@ -305,26 +314,28 @@ static int audit_do_config_change(char *function_name, int *to_change, | |||
| 305 | return rc; | 314 | return rc; |
| 306 | } | 315 | } |
| 307 | 316 | ||
| 308 | static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid) | 317 | static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sessionid, |
| 318 | u32 sid) | ||
| 309 | { | 319 | { |
| 310 | return audit_do_config_change("audit_rate_limit", &audit_rate_limit, | 320 | return audit_do_config_change("audit_rate_limit", &audit_rate_limit, |
| 311 | limit, loginuid, sid); | 321 | limit, loginuid, sessionid, sid); |
| 312 | } | 322 | } |
| 313 | 323 | ||
| 314 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) | 324 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sessionid, |
| 325 | u32 sid) | ||
| 315 | { | 326 | { |
| 316 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, | 327 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, |
| 317 | limit, loginuid, sid); | 328 | limit, loginuid, sessionid, sid); |
| 318 | } | 329 | } |
| 319 | 330 | ||
| 320 | static int audit_set_enabled(int state, uid_t loginuid, u32 sid) | 331 | static int audit_set_enabled(int state, uid_t loginuid, u32 sessionid, u32 sid) |
| 321 | { | 332 | { |
| 322 | int rc; | 333 | int rc; |
| 323 | if (state < AUDIT_OFF || state > AUDIT_LOCKED) | 334 | if (state < AUDIT_OFF || state > AUDIT_LOCKED) |
| 324 | return -EINVAL; | 335 | return -EINVAL; |
| 325 | 336 | ||
| 326 | rc = audit_do_config_change("audit_enabled", &audit_enabled, state, | 337 | rc = audit_do_config_change("audit_enabled", &audit_enabled, state, |
| 327 | loginuid, sid); | 338 | loginuid, sessionid, sid); |
| 328 | 339 | ||
| 329 | if (!rc) | 340 | if (!rc) |
| 330 | audit_ever_enabled |= !!state; | 341 | audit_ever_enabled |= !!state; |
| @@ -332,7 +343,7 @@ static int audit_set_enabled(int state, uid_t loginuid, u32 sid) | |||
| 332 | return rc; | 343 | return rc; |
| 333 | } | 344 | } |
| 334 | 345 | ||
| 335 | static int audit_set_failure(int state, uid_t loginuid, u32 sid) | 346 | static int audit_set_failure(int state, uid_t loginuid, u32 sessionid, u32 sid) |
| 336 | { | 347 | { |
| 337 | if (state != AUDIT_FAIL_SILENT | 348 | if (state != AUDIT_FAIL_SILENT |
| 338 | && state != AUDIT_FAIL_PRINTK | 349 | && state != AUDIT_FAIL_PRINTK |
| @@ -340,7 +351,43 @@ static int audit_set_failure(int state, uid_t loginuid, u32 sid) | |||
| 340 | return -EINVAL; | 351 | return -EINVAL; |
| 341 | 352 | ||
| 342 | return audit_do_config_change("audit_failure", &audit_failure, state, | 353 | return audit_do_config_change("audit_failure", &audit_failure, state, |
| 343 | loginuid, sid); | 354 | loginuid, sessionid, sid); |
| 355 | } | ||
| 356 | |||
| 357 | /* | ||
| 358 | * Queue skbs to be sent to auditd when/if it comes back. These skbs should | ||
| 359 | * already have been sent via prink/syslog and so if these messages are dropped | ||
| 360 | * it is not a huge concern since we already passed the audit_log_lost() | ||
| 361 | * notification and stuff. This is just nice to get audit messages during | ||
| 362 | * boot before auditd is running or messages generated while auditd is stopped. | ||
| 363 | * This only holds messages is audit_default is set, aka booting with audit=1 | ||
| 364 | * or building your kernel that way. | ||
| 365 | */ | ||
| 366 | static void audit_hold_skb(struct sk_buff *skb) | ||
| 367 | { | ||
| 368 | if (audit_default && | ||
| 369 | skb_queue_len(&audit_skb_hold_queue) < audit_backlog_limit) | ||
| 370 | skb_queue_tail(&audit_skb_hold_queue, skb); | ||
| 371 | else | ||
| 372 | kfree_skb(skb); | ||
| 373 | } | ||
| 374 | |||
| 375 | static void kauditd_send_skb(struct sk_buff *skb) | ||
| 376 | { | ||
| 377 | int err; | ||
| 378 | /* take a reference in case we can't send it and we want to hold it */ | ||
| 379 | skb_get(skb); | ||
| 380 | err = netlink_unicast(audit_sock, skb, audit_nlk_pid, 0); | ||
| 381 | if (err < 0) { | ||
| 382 | BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */ | ||
| 383 | printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid); | ||
| 384 | audit_log_lost("auditd dissapeared\n"); | ||
| 385 | audit_pid = 0; | ||
| 386 | /* we might get lucky and get this in the next auditd */ | ||
| 387 | audit_hold_skb(skb); | ||
| 388 | } else | ||
| 389 | /* drop the extra reference if sent ok */ | ||
| 390 | kfree_skb(skb); | ||
| 344 | } | 391 | } |
| 345 | 392 | ||
| 346 | static int kauditd_thread(void *dummy) | 393 | static int kauditd_thread(void *dummy) |
| @@ -349,24 +396,41 @@ static int kauditd_thread(void *dummy) | |||
| 349 | 396 | ||
| 350 | set_freezable(); | 397 | set_freezable(); |
| 351 | while (!kthread_should_stop()) { | 398 | while (!kthread_should_stop()) { |
| 399 | /* | ||
| 400 | * if auditd just started drain the queue of messages already | ||
| 401 | * sent to syslog/printk. remember loss here is ok. we already | ||
| 402 | * called audit_log_lost() if it didn't go out normally. so the | ||
| 403 | * race between the skb_dequeue and the next check for audit_pid | ||
| 404 | * doesn't matter. | ||
| 405 | * | ||
| 406 | * if you ever find kauditd to be too slow we can get a perf win | ||
| 407 | * by doing our own locking and keeping better track if there | ||
| 408 | * are messages in this queue. I don't see the need now, but | ||
| 409 | * in 5 years when I want to play with this again I'll see this | ||
| 410 | * note and still have no friggin idea what i'm thinking today. | ||
| 411 | */ | ||
| 412 | if (audit_default && audit_pid) { | ||
| 413 | skb = skb_dequeue(&audit_skb_hold_queue); | ||
| 414 | if (unlikely(skb)) { | ||
| 415 | while (skb && audit_pid) { | ||
| 416 | kauditd_send_skb(skb); | ||
| 417 | skb = skb_dequeue(&audit_skb_hold_queue); | ||
| 418 | } | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 352 | skb = skb_dequeue(&audit_skb_queue); | 422 | skb = skb_dequeue(&audit_skb_queue); |
| 353 | wake_up(&audit_backlog_wait); | 423 | wake_up(&audit_backlog_wait); |
| 354 | if (skb) { | 424 | if (skb) { |
| 355 | if (audit_pid) { | 425 | if (audit_pid) |
| 356 | int err = netlink_unicast(audit_sock, skb, audit_nlk_pid, 0); | 426 | kauditd_send_skb(skb); |
| 357 | if (err < 0) { | 427 | else { |
| 358 | BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */ | ||
| 359 | printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid); | ||
| 360 | audit_log_lost("auditd dissapeared\n"); | ||
| 361 | audit_pid = 0; | ||
| 362 | } | ||
| 363 | } else { | ||
| 364 | if (printk_ratelimit()) | 428 | if (printk_ratelimit()) |
| 365 | printk(KERN_NOTICE "%s\n", skb->data + | 429 | printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0)); |
| 366 | NLMSG_SPACE(0)); | ||
| 367 | else | 430 | else |
| 368 | audit_log_lost("printk limit exceeded\n"); | 431 | audit_log_lost("printk limit exceeded\n"); |
| 369 | kfree_skb(skb); | 432 | |
| 433 | audit_hold_skb(skb); | ||
| 370 | } | 434 | } |
| 371 | } else { | 435 | } else { |
| 372 | DECLARE_WAITQUEUE(wait, current); | 436 | DECLARE_WAITQUEUE(wait, current); |
| @@ -385,13 +449,13 @@ static int kauditd_thread(void *dummy) | |||
| 385 | return 0; | 449 | return 0; |
| 386 | } | 450 | } |
| 387 | 451 | ||
| 388 | static int audit_prepare_user_tty(pid_t pid, uid_t loginuid) | 452 | static int audit_prepare_user_tty(pid_t pid, uid_t loginuid, u32 sessionid) |
| 389 | { | 453 | { |
| 390 | struct task_struct *tsk; | 454 | struct task_struct *tsk; |
| 391 | int err; | 455 | int err; |
| 392 | 456 | ||
| 393 | read_lock(&tasklist_lock); | 457 | read_lock(&tasklist_lock); |
| 394 | tsk = find_task_by_pid(pid); | 458 | tsk = find_task_by_vpid(pid); |
| 395 | err = -ESRCH; | 459 | err = -ESRCH; |
| 396 | if (!tsk) | 460 | if (!tsk) |
| 397 | goto out; | 461 | goto out; |
| @@ -404,7 +468,7 @@ static int audit_prepare_user_tty(pid_t pid, uid_t loginuid) | |||
| 404 | if (err) | 468 | if (err) |
| 405 | goto out; | 469 | goto out; |
| 406 | 470 | ||
| 407 | tty_audit_push_task(tsk, loginuid); | 471 | tty_audit_push_task(tsk, loginuid, sessionid); |
| 408 | out: | 472 | out: |
| 409 | read_unlock(&tasklist_lock); | 473 | read_unlock(&tasklist_lock); |
| 410 | return err; | 474 | return err; |
| @@ -469,6 +533,19 @@ nlmsg_failure: /* Used by NLMSG_PUT */ | |||
| 469 | return NULL; | 533 | return NULL; |
| 470 | } | 534 | } |
| 471 | 535 | ||
| 536 | static int audit_send_reply_thread(void *arg) | ||
| 537 | { | ||
| 538 | struct audit_reply *reply = (struct audit_reply *)arg; | ||
| 539 | |||
| 540 | mutex_lock(&audit_cmd_mutex); | ||
| 541 | mutex_unlock(&audit_cmd_mutex); | ||
| 542 | |||
| 543 | /* Ignore failure. It'll only happen if the sender goes away, | ||
| 544 | because our timeout is set to infinite. */ | ||
| 545 | netlink_unicast(audit_sock, reply->skb, reply->pid, 0); | ||
| 546 | kfree(reply); | ||
| 547 | return 0; | ||
| 548 | } | ||
| 472 | /** | 549 | /** |
| 473 | * audit_send_reply - send an audit reply message via netlink | 550 | * audit_send_reply - send an audit reply message via netlink |
| 474 | * @pid: process id to send reply to | 551 | * @pid: process id to send reply to |
| @@ -485,14 +562,26 @@ nlmsg_failure: /* Used by NLMSG_PUT */ | |||
| 485 | void audit_send_reply(int pid, int seq, int type, int done, int multi, | 562 | void audit_send_reply(int pid, int seq, int type, int done, int multi, |
| 486 | void *payload, int size) | 563 | void *payload, int size) |
| 487 | { | 564 | { |
| 488 | struct sk_buff *skb; | 565 | struct sk_buff *skb; |
| 566 | struct task_struct *tsk; | ||
| 567 | struct audit_reply *reply = kmalloc(sizeof(struct audit_reply), | ||
| 568 | GFP_KERNEL); | ||
| 569 | |||
| 570 | if (!reply) | ||
| 571 | return; | ||
| 572 | |||
| 489 | skb = audit_make_reply(pid, seq, type, done, multi, payload, size); | 573 | skb = audit_make_reply(pid, seq, type, done, multi, payload, size); |
| 490 | if (!skb) | 574 | if (!skb) |
| 491 | return; | 575 | return; |
| 492 | /* Ignore failure. It'll only happen if the sender goes away, | 576 | |
| 493 | because our timeout is set to infinite. */ | 577 | reply->pid = pid; |
| 494 | netlink_unicast(audit_sock, skb, pid, 0); | 578 | reply->skb = skb; |
| 495 | return; | 579 | |
| 580 | tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply"); | ||
| 581 | if (IS_ERR(tsk)) { | ||
| 582 | kfree(reply); | ||
| 583 | kfree_skb(skb); | ||
| 584 | } | ||
| 496 | } | 585 | } |
| 497 | 586 | ||
| 498 | /* | 587 | /* |
| @@ -534,7 +623,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | |||
| 534 | } | 623 | } |
| 535 | 624 | ||
| 536 | static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | 625 | static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, |
| 537 | u32 pid, u32 uid, uid_t auid, u32 sid) | 626 | u32 pid, u32 uid, uid_t auid, u32 ses, |
| 627 | u32 sid) | ||
| 538 | { | 628 | { |
| 539 | int rc = 0; | 629 | int rc = 0; |
| 540 | char *ctx = NULL; | 630 | char *ctx = NULL; |
| @@ -546,8 +636,8 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | |||
| 546 | } | 636 | } |
| 547 | 637 | ||
| 548 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); | 638 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
| 549 | audit_log_format(*ab, "user pid=%d uid=%u auid=%u", | 639 | audit_log_format(*ab, "user pid=%d uid=%u auid=%u ses=%u", |
| 550 | pid, uid, auid); | 640 | pid, uid, auid, ses); |
| 551 | if (sid) { | 641 | if (sid) { |
| 552 | rc = security_secid_to_secctx(sid, &ctx, &len); | 642 | rc = security_secid_to_secctx(sid, &ctx, &len); |
| 553 | if (rc) | 643 | if (rc) |
| @@ -570,6 +660,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 570 | struct audit_buffer *ab; | 660 | struct audit_buffer *ab; |
| 571 | u16 msg_type = nlh->nlmsg_type; | 661 | u16 msg_type = nlh->nlmsg_type; |
| 572 | uid_t loginuid; /* loginuid of sender */ | 662 | uid_t loginuid; /* loginuid of sender */ |
| 663 | u32 sessionid; | ||
| 573 | struct audit_sig_info *sig_data; | 664 | struct audit_sig_info *sig_data; |
| 574 | char *ctx = NULL; | 665 | char *ctx = NULL; |
| 575 | u32 len; | 666 | u32 len; |
| @@ -591,6 +682,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 591 | pid = NETLINK_CREDS(skb)->pid; | 682 | pid = NETLINK_CREDS(skb)->pid; |
| 592 | uid = NETLINK_CREDS(skb)->uid; | 683 | uid = NETLINK_CREDS(skb)->uid; |
| 593 | loginuid = NETLINK_CB(skb).loginuid; | 684 | loginuid = NETLINK_CB(skb).loginuid; |
| 685 | sessionid = NETLINK_CB(skb).sessionid; | ||
| 594 | sid = NETLINK_CB(skb).sid; | 686 | sid = NETLINK_CB(skb).sid; |
| 595 | seq = nlh->nlmsg_seq; | 687 | seq = nlh->nlmsg_seq; |
| 596 | data = NLMSG_DATA(nlh); | 688 | data = NLMSG_DATA(nlh); |
| @@ -613,12 +705,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 613 | status_get = (struct audit_status *)data; | 705 | status_get = (struct audit_status *)data; |
| 614 | if (status_get->mask & AUDIT_STATUS_ENABLED) { | 706 | if (status_get->mask & AUDIT_STATUS_ENABLED) { |
| 615 | err = audit_set_enabled(status_get->enabled, | 707 | err = audit_set_enabled(status_get->enabled, |
| 616 | loginuid, sid); | 708 | loginuid, sessionid, sid); |
| 617 | if (err < 0) return err; | 709 | if (err < 0) return err; |
| 618 | } | 710 | } |
| 619 | if (status_get->mask & AUDIT_STATUS_FAILURE) { | 711 | if (status_get->mask & AUDIT_STATUS_FAILURE) { |
| 620 | err = audit_set_failure(status_get->failure, | 712 | err = audit_set_failure(status_get->failure, |
| 621 | loginuid, sid); | 713 | loginuid, sessionid, sid); |
| 622 | if (err < 0) return err; | 714 | if (err < 0) return err; |
| 623 | } | 715 | } |
| 624 | if (status_get->mask & AUDIT_STATUS_PID) { | 716 | if (status_get->mask & AUDIT_STATUS_PID) { |
| @@ -627,17 +719,17 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 627 | if (audit_enabled != AUDIT_OFF) | 719 | if (audit_enabled != AUDIT_OFF) |
| 628 | audit_log_config_change("audit_pid", new_pid, | 720 | audit_log_config_change("audit_pid", new_pid, |
| 629 | audit_pid, loginuid, | 721 | audit_pid, loginuid, |
| 630 | sid, 1); | 722 | sessionid, sid, 1); |
| 631 | 723 | ||
| 632 | audit_pid = new_pid; | 724 | audit_pid = new_pid; |
| 633 | audit_nlk_pid = NETLINK_CB(skb).pid; | 725 | audit_nlk_pid = NETLINK_CB(skb).pid; |
| 634 | } | 726 | } |
| 635 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) | 727 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) |
| 636 | err = audit_set_rate_limit(status_get->rate_limit, | 728 | err = audit_set_rate_limit(status_get->rate_limit, |
| 637 | loginuid, sid); | 729 | loginuid, sessionid, sid); |
| 638 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) | 730 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) |
| 639 | err = audit_set_backlog_limit(status_get->backlog_limit, | 731 | err = audit_set_backlog_limit(status_get->backlog_limit, |
| 640 | loginuid, sid); | 732 | loginuid, sessionid, sid); |
| 641 | break; | 733 | break; |
| 642 | case AUDIT_USER: | 734 | case AUDIT_USER: |
| 643 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: | 735 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: |
| @@ -649,12 +741,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 649 | if (err == 1) { | 741 | if (err == 1) { |
| 650 | err = 0; | 742 | err = 0; |
| 651 | if (msg_type == AUDIT_USER_TTY) { | 743 | if (msg_type == AUDIT_USER_TTY) { |
| 652 | err = audit_prepare_user_tty(pid, loginuid); | 744 | err = audit_prepare_user_tty(pid, loginuid, |
| 745 | sessionid); | ||
| 653 | if (err) | 746 | if (err) |
| 654 | break; | 747 | break; |
| 655 | } | 748 | } |
| 656 | audit_log_common_recv_msg(&ab, msg_type, pid, uid, | 749 | audit_log_common_recv_msg(&ab, msg_type, pid, uid, |
| 657 | loginuid, sid); | 750 | loginuid, sessionid, sid); |
| 658 | 751 | ||
| 659 | if (msg_type != AUDIT_USER_TTY) | 752 | if (msg_type != AUDIT_USER_TTY) |
| 660 | audit_log_format(ab, " msg='%.1024s'", | 753 | audit_log_format(ab, " msg='%.1024s'", |
| @@ -664,8 +757,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 664 | 757 | ||
| 665 | audit_log_format(ab, " msg="); | 758 | audit_log_format(ab, " msg="); |
| 666 | size = nlmsg_len(nlh); | 759 | size = nlmsg_len(nlh); |
| 667 | audit_log_n_untrustedstring(ab, size, | 760 | audit_log_n_untrustedstring(ab, data, size); |
| 668 | data); | ||
| 669 | } | 761 | } |
| 670 | audit_set_pid(ab, pid); | 762 | audit_set_pid(ab, pid); |
| 671 | audit_log_end(ab); | 763 | audit_log_end(ab); |
| @@ -677,7 +769,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 677 | return -EINVAL; | 769 | return -EINVAL; |
| 678 | if (audit_enabled == AUDIT_LOCKED) { | 770 | if (audit_enabled == AUDIT_LOCKED) { |
| 679 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 771 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
| 680 | uid, loginuid, sid); | 772 | uid, loginuid, sessionid, sid); |
| 681 | 773 | ||
| 682 | audit_log_format(ab, " audit_enabled=%d res=0", | 774 | audit_log_format(ab, " audit_enabled=%d res=0", |
| 683 | audit_enabled); | 775 | audit_enabled); |
| @@ -688,7 +780,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 688 | case AUDIT_LIST: | 780 | case AUDIT_LIST: |
| 689 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 781 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
| 690 | uid, seq, data, nlmsg_len(nlh), | 782 | uid, seq, data, nlmsg_len(nlh), |
| 691 | loginuid, sid); | 783 | loginuid, sessionid, sid); |
| 692 | break; | 784 | break; |
| 693 | case AUDIT_ADD_RULE: | 785 | case AUDIT_ADD_RULE: |
| 694 | case AUDIT_DEL_RULE: | 786 | case AUDIT_DEL_RULE: |
| @@ -696,7 +788,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 696 | return -EINVAL; | 788 | return -EINVAL; |
| 697 | if (audit_enabled == AUDIT_LOCKED) { | 789 | if (audit_enabled == AUDIT_LOCKED) { |
| 698 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 790 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
| 699 | uid, loginuid, sid); | 791 | uid, loginuid, sessionid, sid); |
| 700 | 792 | ||
| 701 | audit_log_format(ab, " audit_enabled=%d res=0", | 793 | audit_log_format(ab, " audit_enabled=%d res=0", |
| 702 | audit_enabled); | 794 | audit_enabled); |
| @@ -707,13 +799,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 707 | case AUDIT_LIST_RULES: | 799 | case AUDIT_LIST_RULES: |
| 708 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 800 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
| 709 | uid, seq, data, nlmsg_len(nlh), | 801 | uid, seq, data, nlmsg_len(nlh), |
| 710 | loginuid, sid); | 802 | loginuid, sessionid, sid); |
| 711 | break; | 803 | break; |
| 712 | case AUDIT_TRIM: | 804 | case AUDIT_TRIM: |
| 713 | audit_trim_trees(); | 805 | audit_trim_trees(); |
| 714 | 806 | ||
| 715 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 807 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
| 716 | uid, loginuid, sid); | 808 | uid, loginuid, sessionid, sid); |
| 717 | 809 | ||
| 718 | audit_log_format(ab, " op=trim res=1"); | 810 | audit_log_format(ab, " op=trim res=1"); |
| 719 | audit_log_end(ab); | 811 | audit_log_end(ab); |
| @@ -721,21 +813,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 721 | case AUDIT_MAKE_EQUIV: { | 813 | case AUDIT_MAKE_EQUIV: { |
| 722 | void *bufp = data; | 814 | void *bufp = data; |
| 723 | u32 sizes[2]; | 815 | u32 sizes[2]; |
| 724 | size_t len = nlmsg_len(nlh); | 816 | size_t msglen = nlmsg_len(nlh); |
| 725 | char *old, *new; | 817 | char *old, *new; |
| 726 | 818 | ||
| 727 | err = -EINVAL; | 819 | err = -EINVAL; |
| 728 | if (len < 2 * sizeof(u32)) | 820 | if (msglen < 2 * sizeof(u32)) |
| 729 | break; | 821 | break; |
| 730 | memcpy(sizes, bufp, 2 * sizeof(u32)); | 822 | memcpy(sizes, bufp, 2 * sizeof(u32)); |
| 731 | bufp += 2 * sizeof(u32); | 823 | bufp += 2 * sizeof(u32); |
| 732 | len -= 2 * sizeof(u32); | 824 | msglen -= 2 * sizeof(u32); |
| 733 | old = audit_unpack_string(&bufp, &len, sizes[0]); | 825 | old = audit_unpack_string(&bufp, &msglen, sizes[0]); |
| 734 | if (IS_ERR(old)) { | 826 | if (IS_ERR(old)) { |
| 735 | err = PTR_ERR(old); | 827 | err = PTR_ERR(old); |
| 736 | break; | 828 | break; |
| 737 | } | 829 | } |
| 738 | new = audit_unpack_string(&bufp, &len, sizes[1]); | 830 | new = audit_unpack_string(&bufp, &msglen, sizes[1]); |
| 739 | if (IS_ERR(new)) { | 831 | if (IS_ERR(new)) { |
| 740 | err = PTR_ERR(new); | 832 | err = PTR_ERR(new); |
| 741 | kfree(old); | 833 | kfree(old); |
| @@ -745,7 +837,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 745 | err = audit_tag_tree(old, new); | 837 | err = audit_tag_tree(old, new); |
| 746 | 838 | ||
| 747 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 839 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
| 748 | uid, loginuid, sid); | 840 | uid, loginuid, sessionid, sid); |
| 749 | 841 | ||
| 750 | audit_log_format(ab, " op=make_equiv old="); | 842 | audit_log_format(ab, " op=make_equiv old="); |
| 751 | audit_log_untrustedstring(ab, old); | 843 | audit_log_untrustedstring(ab, old); |
| @@ -779,7 +871,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 779 | struct task_struct *tsk; | 871 | struct task_struct *tsk; |
| 780 | 872 | ||
| 781 | read_lock(&tasklist_lock); | 873 | read_lock(&tasklist_lock); |
| 782 | tsk = find_task_by_pid(pid); | 874 | tsk = find_task_by_vpid(pid); |
| 783 | if (!tsk) | 875 | if (!tsk) |
| 784 | err = -ESRCH; | 876 | err = -ESRCH; |
| 785 | else { | 877 | else { |
| @@ -802,7 +894,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 802 | if (s->enabled != 0 && s->enabled != 1) | 894 | if (s->enabled != 0 && s->enabled != 1) |
| 803 | return -EINVAL; | 895 | return -EINVAL; |
| 804 | read_lock(&tasklist_lock); | 896 | read_lock(&tasklist_lock); |
| 805 | tsk = find_task_by_pid(pid); | 897 | tsk = find_task_by_vpid(pid); |
| 806 | if (!tsk) | 898 | if (!tsk) |
| 807 | err = -ESRCH; | 899 | err = -ESRCH; |
| 808 | else { | 900 | else { |
| @@ -877,6 +969,7 @@ static int __init audit_init(void) | |||
| 877 | audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; | 969 | audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; |
| 878 | 970 | ||
| 879 | skb_queue_head_init(&audit_skb_queue); | 971 | skb_queue_head_init(&audit_skb_queue); |
| 972 | skb_queue_head_init(&audit_skb_hold_queue); | ||
| 880 | audit_initialized = 1; | 973 | audit_initialized = 1; |
| 881 | audit_enabled = audit_default; | 974 | audit_enabled = audit_default; |
| 882 | audit_ever_enabled |= !!audit_default; | 975 | audit_ever_enabled |= !!audit_default; |
| @@ -1199,7 +1292,7 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) | |||
| 1199 | * This function will take the passed buf and convert it into a string of | 1292 | * This function will take the passed buf and convert it into a string of |
| 1200 | * ascii hex digits. The new string is placed onto the skb. | 1293 | * ascii hex digits. The new string is placed onto the skb. |
| 1201 | */ | 1294 | */ |
| 1202 | void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, | 1295 | void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf, |
| 1203 | size_t len) | 1296 | size_t len) |
| 1204 | { | 1297 | { |
| 1205 | int i, avail, new_len; | 1298 | int i, avail, new_len; |
| @@ -1235,8 +1328,8 @@ void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, | |||
| 1235 | * Format a string of no more than slen characters into the audit buffer, | 1328 | * Format a string of no more than slen characters into the audit buffer, |
| 1236 | * enclosed in quote marks. | 1329 | * enclosed in quote marks. |
| 1237 | */ | 1330 | */ |
| 1238 | static void audit_log_n_string(struct audit_buffer *ab, size_t slen, | 1331 | void audit_log_n_string(struct audit_buffer *ab, const char *string, |
| 1239 | const char *string) | 1332 | size_t slen) |
| 1240 | { | 1333 | { |
| 1241 | int avail, new_len; | 1334 | int avail, new_len; |
| 1242 | unsigned char *ptr; | 1335 | unsigned char *ptr; |
| @@ -1292,13 +1385,13 @@ int audit_string_contains_control(const char *string, size_t len) | |||
| 1292 | * The caller specifies the number of characters in the string to log, which may | 1385 | * The caller specifies the number of characters in the string to log, which may |
| 1293 | * or may not be the entire string. | 1386 | * or may not be the entire string. |
| 1294 | */ | 1387 | */ |
| 1295 | void audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len, | 1388 | void audit_log_n_untrustedstring(struct audit_buffer *ab, const char *string, |
| 1296 | const char *string) | 1389 | size_t len) |
| 1297 | { | 1390 | { |
| 1298 | if (audit_string_contains_control(string, len)) | 1391 | if (audit_string_contains_control(string, len)) |
| 1299 | audit_log_hex(ab, string, len); | 1392 | audit_log_n_hex(ab, string, len); |
| 1300 | else | 1393 | else |
| 1301 | audit_log_n_string(ab, len, string); | 1394 | audit_log_n_string(ab, string, len); |
| 1302 | } | 1395 | } |
| 1303 | 1396 | ||
| 1304 | /** | 1397 | /** |
| @@ -1311,7 +1404,7 @@ void audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len, | |||
| 1311 | */ | 1404 | */ |
| 1312 | void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) | 1405 | void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) |
| 1313 | { | 1406 | { |
| 1314 | audit_log_n_untrustedstring(ab, strlen(string), string); | 1407 | audit_log_n_untrustedstring(ab, string, strlen(string)); |
| 1315 | } | 1408 | } |
| 1316 | 1409 | ||
| 1317 | /* This is a helper-function to print the escaped d_path */ | 1410 | /* This is a helper-function to print the escaped d_path */ |
| @@ -1355,19 +1448,23 @@ void audit_log_end(struct audit_buffer *ab) | |||
| 1355 | audit_log_lost("rate limit exceeded"); | 1448 | audit_log_lost("rate limit exceeded"); |
| 1356 | } else { | 1449 | } else { |
| 1357 | struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); | 1450 | struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); |
| 1451 | nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0); | ||
| 1452 | |||
| 1358 | if (audit_pid) { | 1453 | if (audit_pid) { |
| 1359 | nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0); | ||
| 1360 | skb_queue_tail(&audit_skb_queue, ab->skb); | 1454 | skb_queue_tail(&audit_skb_queue, ab->skb); |
| 1361 | ab->skb = NULL; | ||
| 1362 | wake_up_interruptible(&kauditd_wait); | 1455 | wake_up_interruptible(&kauditd_wait); |
| 1363 | } else if (nlh->nlmsg_type != AUDIT_EOE) { | 1456 | } else { |
| 1364 | if (printk_ratelimit()) { | 1457 | if (nlh->nlmsg_type != AUDIT_EOE) { |
| 1365 | printk(KERN_NOTICE "type=%d %s\n", | 1458 | if (printk_ratelimit()) { |
| 1366 | nlh->nlmsg_type, | 1459 | printk(KERN_NOTICE "type=%d %s\n", |
| 1367 | ab->skb->data + NLMSG_SPACE(0)); | 1460 | nlh->nlmsg_type, |
| 1368 | } else | 1461 | ab->skb->data + NLMSG_SPACE(0)); |
| 1369 | audit_log_lost("printk limit exceeded\n"); | 1462 | } else |
| 1463 | audit_log_lost("printk limit exceeded\n"); | ||
| 1464 | } | ||
| 1465 | audit_hold_skb(ab->skb); | ||
| 1370 | } | 1466 | } |
| 1467 | ab->skb = NULL; | ||
| 1371 | } | 1468 | } |
| 1372 | audit_buffer_free(ab); | 1469 | audit_buffer_free(ab); |
| 1373 | } | 1470 | } |
diff --git a/kernel/audit.h b/kernel/audit.h index 3cfc54ee3e1f..9d6717412fec 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
| @@ -74,6 +74,11 @@ struct audit_entry { | |||
| 74 | struct audit_krule rule; | 74 | struct audit_krule rule; |
| 75 | }; | 75 | }; |
| 76 | 76 | ||
| 77 | #ifdef CONFIG_AUDIT | ||
| 78 | extern int audit_enabled; | ||
| 79 | extern int audit_ever_enabled; | ||
| 80 | #endif | ||
| 81 | |||
| 77 | extern int audit_pid; | 82 | extern int audit_pid; |
| 78 | 83 | ||
| 79 | #define AUDIT_INODE_BUCKETS 32 | 84 | #define AUDIT_INODE_BUCKETS 32 |
| @@ -104,6 +109,9 @@ struct audit_netlink_list { | |||
| 104 | int audit_send_list(void *); | 109 | int audit_send_list(void *); |
| 105 | 110 | ||
| 106 | struct inotify_watch; | 111 | struct inotify_watch; |
| 112 | /* Inotify handle */ | ||
| 113 | extern struct inotify_handle *audit_ih; | ||
| 114 | |||
| 107 | extern void audit_free_parent(struct inotify_watch *); | 115 | extern void audit_free_parent(struct inotify_watch *); |
| 108 | extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32, | 116 | extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32, |
| 109 | const char *, struct inode *); | 117 | const char *, struct inode *); |
| @@ -111,6 +119,7 @@ extern int selinux_audit_rule_update(void); | |||
| 111 | 119 | ||
| 112 | extern struct mutex audit_filter_mutex; | 120 | extern struct mutex audit_filter_mutex; |
| 113 | extern void audit_free_rule_rcu(struct rcu_head *); | 121 | extern void audit_free_rule_rcu(struct rcu_head *); |
| 122 | extern struct list_head audit_filter_list[]; | ||
| 114 | 123 | ||
| 115 | #ifdef CONFIG_AUDIT_TREE | 124 | #ifdef CONFIG_AUDIT_TREE |
| 116 | extern struct audit_chunk *audit_tree_lookup(const struct inode *); | 125 | extern struct audit_chunk *audit_tree_lookup(const struct inode *); |
| @@ -137,6 +146,10 @@ extern void audit_put_tree(struct audit_tree *); | |||
| 137 | 146 | ||
| 138 | extern char *audit_unpack_string(void **, size_t *, size_t); | 147 | extern char *audit_unpack_string(void **, size_t *, size_t); |
| 139 | 148 | ||
| 149 | extern pid_t audit_sig_pid; | ||
| 150 | extern uid_t audit_sig_uid; | ||
| 151 | extern u32 audit_sig_sid; | ||
| 152 | |||
| 140 | #ifdef CONFIG_AUDITSYSCALL | 153 | #ifdef CONFIG_AUDITSYSCALL |
| 141 | extern int __audit_signal_info(int sig, struct task_struct *t); | 154 | extern int __audit_signal_info(int sig, struct task_struct *t); |
| 142 | static inline int audit_signal_info(int sig, struct task_struct *t) | 155 | static inline int audit_signal_info(int sig, struct task_struct *t) |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 13430176b3c9..0e0bd27e6512 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
| @@ -89,14 +89,9 @@ struct list_head audit_filter_list[AUDIT_NR_FILTERS] = { | |||
| 89 | 89 | ||
| 90 | DEFINE_MUTEX(audit_filter_mutex); | 90 | DEFINE_MUTEX(audit_filter_mutex); |
| 91 | 91 | ||
| 92 | /* Inotify handle */ | ||
| 93 | extern struct inotify_handle *audit_ih; | ||
| 94 | |||
| 95 | /* Inotify events we care about. */ | 92 | /* Inotify events we care about. */ |
| 96 | #define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF | 93 | #define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF |
| 97 | 94 | ||
| 98 | extern int audit_enabled; | ||
| 99 | |||
| 100 | void audit_free_parent(struct inotify_watch *i_watch) | 95 | void audit_free_parent(struct inotify_watch *i_watch) |
| 101 | { | 96 | { |
| 102 | struct audit_parent *parent; | 97 | struct audit_parent *parent; |
| @@ -422,7 +417,7 @@ exit_err: | |||
| 422 | static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | 417 | static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) |
| 423 | { | 418 | { |
| 424 | struct audit_entry *entry; | 419 | struct audit_entry *entry; |
| 425 | struct audit_field *f; | 420 | struct audit_field *ino_f; |
| 426 | int err = 0; | 421 | int err = 0; |
| 427 | int i; | 422 | int i; |
| 428 | 423 | ||
| @@ -483,6 +478,10 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | |||
| 483 | if (f->val & ~15) | 478 | if (f->val & ~15) |
| 484 | goto exit_free; | 479 | goto exit_free; |
| 485 | break; | 480 | break; |
| 481 | case AUDIT_FILETYPE: | ||
| 482 | if ((f->val & ~S_IFMT) > S_IFMT) | ||
| 483 | goto exit_free; | ||
| 484 | break; | ||
| 486 | case AUDIT_INODE: | 485 | case AUDIT_INODE: |
| 487 | err = audit_to_inode(&entry->rule, f); | 486 | err = audit_to_inode(&entry->rule, f); |
| 488 | if (err) | 487 | if (err) |
| @@ -504,9 +503,9 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | |||
| 504 | } | 503 | } |
| 505 | } | 504 | } |
| 506 | 505 | ||
| 507 | f = entry->rule.inode_f; | 506 | ino_f = entry->rule.inode_f; |
| 508 | if (f) { | 507 | if (ino_f) { |
| 509 | switch(f->op) { | 508 | switch(ino_f->op) { |
| 510 | case AUDIT_NOT_EQUAL: | 509 | case AUDIT_NOT_EQUAL: |
| 511 | entry->rule.inode_f = NULL; | 510 | entry->rule.inode_f = NULL; |
| 512 | case AUDIT_EQUAL: | 511 | case AUDIT_EQUAL: |
| @@ -531,7 +530,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
| 531 | { | 530 | { |
| 532 | int err = 0; | 531 | int err = 0; |
| 533 | struct audit_entry *entry; | 532 | struct audit_entry *entry; |
| 534 | struct audit_field *f; | 533 | struct audit_field *ino_f; |
| 535 | void *bufp; | 534 | void *bufp; |
| 536 | size_t remain = datasz - sizeof(struct audit_rule_data); | 535 | size_t remain = datasz - sizeof(struct audit_rule_data); |
| 537 | int i; | 536 | int i; |
| @@ -654,14 +653,18 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
| 654 | if (f->val & ~15) | 653 | if (f->val & ~15) |
| 655 | goto exit_free; | 654 | goto exit_free; |
| 656 | break; | 655 | break; |
| 656 | case AUDIT_FILETYPE: | ||
| 657 | if ((f->val & ~S_IFMT) > S_IFMT) | ||
| 658 | goto exit_free; | ||
| 659 | break; | ||
| 657 | default: | 660 | default: |
| 658 | goto exit_free; | 661 | goto exit_free; |
| 659 | } | 662 | } |
| 660 | } | 663 | } |
| 661 | 664 | ||
| 662 | f = entry->rule.inode_f; | 665 | ino_f = entry->rule.inode_f; |
| 663 | if (f) { | 666 | if (ino_f) { |
| 664 | switch(f->op) { | 667 | switch(ino_f->op) { |
| 665 | case AUDIT_NOT_EQUAL: | 668 | case AUDIT_NOT_EQUAL: |
| 666 | entry->rule.inode_f = NULL; | 669 | entry->rule.inode_f = NULL; |
| 667 | case AUDIT_EQUAL: | 670 | case AUDIT_EQUAL: |
| @@ -1500,8 +1503,9 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q) | |||
| 1500 | } | 1503 | } |
| 1501 | 1504 | ||
| 1502 | /* Log rule additions and removals */ | 1505 | /* Log rule additions and removals */ |
| 1503 | static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, | 1506 | static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid, |
| 1504 | struct audit_krule *rule, int res) | 1507 | char *action, struct audit_krule *rule, |
| 1508 | int res) | ||
| 1505 | { | 1509 | { |
| 1506 | struct audit_buffer *ab; | 1510 | struct audit_buffer *ab; |
| 1507 | 1511 | ||
| @@ -1511,7 +1515,7 @@ static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, | |||
| 1511 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 1515 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
| 1512 | if (!ab) | 1516 | if (!ab) |
| 1513 | return; | 1517 | return; |
| 1514 | audit_log_format(ab, "auid=%u", loginuid); | 1518 | audit_log_format(ab, "auid=%u ses=%u", loginuid, sessionid); |
| 1515 | if (sid) { | 1519 | if (sid) { |
| 1516 | char *ctx = NULL; | 1520 | char *ctx = NULL; |
| 1517 | u32 len; | 1521 | u32 len; |
| @@ -1543,7 +1547,7 @@ static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, | |||
| 1543 | * @sid: SE Linux Security ID of sender | 1547 | * @sid: SE Linux Security ID of sender |
| 1544 | */ | 1548 | */ |
| 1545 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | 1549 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, |
| 1546 | size_t datasz, uid_t loginuid, u32 sid) | 1550 | size_t datasz, uid_t loginuid, u32 sessionid, u32 sid) |
| 1547 | { | 1551 | { |
| 1548 | struct task_struct *tsk; | 1552 | struct task_struct *tsk; |
| 1549 | struct audit_netlink_list *dest; | 1553 | struct audit_netlink_list *dest; |
| @@ -1590,7 +1594,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
| 1590 | 1594 | ||
| 1591 | err = audit_add_rule(entry, | 1595 | err = audit_add_rule(entry, |
| 1592 | &audit_filter_list[entry->rule.listnr]); | 1596 | &audit_filter_list[entry->rule.listnr]); |
| 1593 | audit_log_rule_change(loginuid, sid, "add", &entry->rule, !err); | 1597 | audit_log_rule_change(loginuid, sessionid, sid, "add", |
| 1598 | &entry->rule, !err); | ||
| 1594 | 1599 | ||
| 1595 | if (err) | 1600 | if (err) |
| 1596 | audit_free_rule(entry); | 1601 | audit_free_rule(entry); |
| @@ -1606,8 +1611,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
| 1606 | 1611 | ||
| 1607 | err = audit_del_rule(entry, | 1612 | err = audit_del_rule(entry, |
| 1608 | &audit_filter_list[entry->rule.listnr]); | 1613 | &audit_filter_list[entry->rule.listnr]); |
| 1609 | audit_log_rule_change(loginuid, sid, "remove", &entry->rule, | 1614 | audit_log_rule_change(loginuid, sessionid, sid, "remove", |
| 1610 | !err); | 1615 | &entry->rule, !err); |
| 1611 | 1616 | ||
| 1612 | audit_free_rule(entry); | 1617 | audit_free_rule(entry); |
| 1613 | break; | 1618 | break; |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 56e56ed594a8..c10e7aae04d7 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -68,9 +68,6 @@ | |||
| 68 | 68 | ||
| 69 | #include "audit.h" | 69 | #include "audit.h" |
| 70 | 70 | ||
| 71 | extern struct list_head audit_filter_list[]; | ||
| 72 | extern int audit_ever_enabled; | ||
| 73 | |||
| 74 | /* AUDIT_NAMES is the number of slots we reserve in the audit_context | 71 | /* AUDIT_NAMES is the number of slots we reserve in the audit_context |
| 75 | * for saving names from getname(). */ | 72 | * for saving names from getname(). */ |
| 76 | #define AUDIT_NAMES 20 | 73 | #define AUDIT_NAMES 20 |
| @@ -283,6 +280,19 @@ static int audit_match_perm(struct audit_context *ctx, int mask) | |||
| 283 | } | 280 | } |
| 284 | } | 281 | } |
| 285 | 282 | ||
| 283 | static int audit_match_filetype(struct audit_context *ctx, int which) | ||
| 284 | { | ||
| 285 | unsigned index = which & ~S_IFMT; | ||
| 286 | mode_t mode = which & S_IFMT; | ||
| 287 | if (index >= ctx->name_count) | ||
| 288 | return 0; | ||
| 289 | if (ctx->names[index].ino == -1) | ||
| 290 | return 0; | ||
| 291 | if ((ctx->names[index].mode ^ mode) & S_IFMT) | ||
| 292 | return 0; | ||
| 293 | return 1; | ||
| 294 | } | ||
| 295 | |||
| 286 | /* | 296 | /* |
| 287 | * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *; | 297 | * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *; |
| 288 | * ->first_trees points to its beginning, ->trees - to the current end of data. | 298 | * ->first_trees points to its beginning, ->trees - to the current end of data. |
| @@ -592,6 +602,9 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
| 592 | case AUDIT_PERM: | 602 | case AUDIT_PERM: |
| 593 | result = audit_match_perm(ctx, f->val); | 603 | result = audit_match_perm(ctx, f->val); |
| 594 | break; | 604 | break; |
| 605 | case AUDIT_FILETYPE: | ||
| 606 | result = audit_match_filetype(ctx, f->val); | ||
| 607 | break; | ||
| 595 | } | 608 | } |
| 596 | 609 | ||
| 597 | if (!result) | 610 | if (!result) |
| @@ -1095,7 +1108,7 @@ static int audit_log_single_execve_arg(struct audit_context *context, | |||
| 1095 | audit_log_format(*ab, "[%d]", i); | 1108 | audit_log_format(*ab, "[%d]", i); |
| 1096 | audit_log_format(*ab, "="); | 1109 | audit_log_format(*ab, "="); |
| 1097 | if (has_cntl) | 1110 | if (has_cntl) |
| 1098 | audit_log_hex(*ab, buf, to_send); | 1111 | audit_log_n_hex(*ab, buf, to_send); |
| 1099 | else | 1112 | else |
| 1100 | audit_log_format(*ab, "\"%s\"", buf); | 1113 | audit_log_format(*ab, "\"%s\"", buf); |
| 1101 | audit_log_format(*ab, "\n"); | 1114 | audit_log_format(*ab, "\n"); |
| @@ -1296,7 +1309,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
| 1296 | break; } | 1309 | break; } |
| 1297 | 1310 | ||
| 1298 | case AUDIT_SOCKETCALL: { | 1311 | case AUDIT_SOCKETCALL: { |
| 1299 | int i; | ||
| 1300 | struct audit_aux_data_socketcall *axs = (void *)aux; | 1312 | struct audit_aux_data_socketcall *axs = (void *)aux; |
| 1301 | audit_log_format(ab, "nargs=%d", axs->nargs); | 1313 | audit_log_format(ab, "nargs=%d", axs->nargs); |
| 1302 | for (i=0; i<axs->nargs; i++) | 1314 | for (i=0; i<axs->nargs; i++) |
| @@ -1307,7 +1319,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
| 1307 | struct audit_aux_data_sockaddr *axs = (void *)aux; | 1319 | struct audit_aux_data_sockaddr *axs = (void *)aux; |
| 1308 | 1320 | ||
| 1309 | audit_log_format(ab, "saddr="); | 1321 | audit_log_format(ab, "saddr="); |
| 1310 | audit_log_hex(ab, axs->a, axs->len); | 1322 | audit_log_n_hex(ab, axs->a, axs->len); |
| 1311 | break; } | 1323 | break; } |
| 1312 | 1324 | ||
| 1313 | case AUDIT_FD_PAIR: { | 1325 | case AUDIT_FD_PAIR: { |
| @@ -1321,7 +1333,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
| 1321 | 1333 | ||
| 1322 | for (aux = context->aux_pids; aux; aux = aux->next) { | 1334 | for (aux = context->aux_pids; aux; aux = aux->next) { |
| 1323 | struct audit_aux_data_pids *axs = (void *)aux; | 1335 | struct audit_aux_data_pids *axs = (void *)aux; |
| 1324 | int i; | ||
| 1325 | 1336 | ||
| 1326 | for (i = 0; i < axs->pid_count; i++) | 1337 | for (i = 0; i < axs->pid_count; i++) |
| 1327 | if (audit_log_pid_context(context, axs->target_pid[i], | 1338 | if (audit_log_pid_context(context, axs->target_pid[i], |
| @@ -1371,8 +1382,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
| 1371 | default: | 1382 | default: |
| 1372 | /* log the name's directory component */ | 1383 | /* log the name's directory component */ |
| 1373 | audit_log_format(ab, " name="); | 1384 | audit_log_format(ab, " name="); |
| 1374 | audit_log_n_untrustedstring(ab, n->name_len, | 1385 | audit_log_n_untrustedstring(ab, n->name, |
| 1375 | n->name); | 1386 | n->name_len); |
| 1376 | } | 1387 | } |
| 1377 | } else | 1388 | } else |
| 1378 | audit_log_format(ab, " name=(null)"); | 1389 | audit_log_format(ab, " name=(null)"); |
| @@ -1596,7 +1607,7 @@ static inline void handle_one(const struct inode *inode) | |||
| 1596 | if (likely(put_tree_ref(context, chunk))) | 1607 | if (likely(put_tree_ref(context, chunk))) |
| 1597 | return; | 1608 | return; |
| 1598 | if (unlikely(!grow_tree_refs(context))) { | 1609 | if (unlikely(!grow_tree_refs(context))) { |
| 1599 | printk(KERN_WARNING "out of memory, audit has lost a tree reference"); | 1610 | printk(KERN_WARNING "out of memory, audit has lost a tree reference\n"); |
| 1600 | audit_set_auditable(context); | 1611 | audit_set_auditable(context); |
| 1601 | audit_put_chunk(chunk); | 1612 | audit_put_chunk(chunk); |
| 1602 | unroll_tree_refs(context, p, count); | 1613 | unroll_tree_refs(context, p, count); |
| @@ -1656,7 +1667,7 @@ retry: | |||
| 1656 | } | 1667 | } |
| 1657 | /* too bad */ | 1668 | /* too bad */ |
| 1658 | printk(KERN_WARNING | 1669 | printk(KERN_WARNING |
| 1659 | "out of memory, audit has lost a tree reference"); | 1670 | "out of memory, audit has lost a tree reference\n"); |
| 1660 | unroll_tree_refs(context, p, count); | 1671 | unroll_tree_refs(context, p, count); |
| 1661 | audit_set_auditable(context); | 1672 | audit_set_auditable(context); |
| 1662 | return; | 1673 | return; |
| @@ -1752,13 +1763,13 @@ static int audit_inc_name_count(struct audit_context *context, | |||
| 1752 | if (context->name_count >= AUDIT_NAMES) { | 1763 | if (context->name_count >= AUDIT_NAMES) { |
| 1753 | if (inode) | 1764 | if (inode) |
| 1754 | printk(KERN_DEBUG "name_count maxed, losing inode data: " | 1765 | printk(KERN_DEBUG "name_count maxed, losing inode data: " |
| 1755 | "dev=%02x:%02x, inode=%lu", | 1766 | "dev=%02x:%02x, inode=%lu\n", |
| 1756 | MAJOR(inode->i_sb->s_dev), | 1767 | MAJOR(inode->i_sb->s_dev), |
| 1757 | MINOR(inode->i_sb->s_dev), | 1768 | MINOR(inode->i_sb->s_dev), |
| 1758 | inode->i_ino); | 1769 | inode->i_ino); |
| 1759 | 1770 | ||
| 1760 | else | 1771 | else |
| 1761 | printk(KERN_DEBUG "name_count maxed, losing inode data"); | 1772 | printk(KERN_DEBUG "name_count maxed, losing inode data\n"); |
| 1762 | return 1; | 1773 | return 1; |
| 1763 | } | 1774 | } |
| 1764 | context->name_count++; | 1775 | context->name_count++; |
| @@ -2361,9 +2372,6 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
| 2361 | struct audit_aux_data_pids *axp; | 2372 | struct audit_aux_data_pids *axp; |
| 2362 | struct task_struct *tsk = current; | 2373 | struct task_struct *tsk = current; |
| 2363 | struct audit_context *ctx = tsk->audit_context; | 2374 | struct audit_context *ctx = tsk->audit_context; |
| 2364 | extern pid_t audit_sig_pid; | ||
| 2365 | extern uid_t audit_sig_uid; | ||
| 2366 | extern u32 audit_sig_sid; | ||
| 2367 | 2375 | ||
| 2368 | if (audit_pid && t->tgid == audit_pid) { | 2376 | if (audit_pid && t->tgid == audit_pid) { |
| 2369 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { | 2377 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 2403a31fe0f6..9e7236ff6bcc 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -1498,7 +1498,8 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, | |||
| 1498 | err = xfrm_state_update(x); | 1498 | err = xfrm_state_update(x); |
| 1499 | 1499 | ||
| 1500 | xfrm_audit_state_add(x, err ? 0 : 1, | 1500 | xfrm_audit_state_add(x, err ? 0 : 1, |
| 1501 | audit_get_loginuid(current), 0); | 1501 | audit_get_loginuid(current), |
| 1502 | audit_get_sessionid(current), 0); | ||
| 1502 | 1503 | ||
| 1503 | if (err < 0) { | 1504 | if (err < 0) { |
| 1504 | x->km.state = XFRM_STATE_DEAD; | 1505 | x->km.state = XFRM_STATE_DEAD; |
| @@ -1552,7 +1553,8 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
| 1552 | km_state_notify(x, &c); | 1553 | km_state_notify(x, &c); |
| 1553 | out: | 1554 | out: |
| 1554 | xfrm_audit_state_delete(x, err ? 0 : 1, | 1555 | xfrm_audit_state_delete(x, err ? 0 : 1, |
| 1555 | audit_get_loginuid(current), 0); | 1556 | audit_get_loginuid(current), |
| 1557 | audit_get_sessionid(current), 0); | ||
| 1556 | xfrm_state_put(x); | 1558 | xfrm_state_put(x); |
| 1557 | 1559 | ||
| 1558 | return err; | 1560 | return err; |
| @@ -1728,6 +1730,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
| 1728 | return -EINVAL; | 1730 | return -EINVAL; |
| 1729 | 1731 | ||
| 1730 | audit_info.loginuid = audit_get_loginuid(current); | 1732 | audit_info.loginuid = audit_get_loginuid(current); |
| 1733 | audit_info.sessionid = audit_get_sessionid(current); | ||
| 1731 | audit_info.secid = 0; | 1734 | audit_info.secid = 0; |
| 1732 | err = xfrm_state_flush(proto, &audit_info); | 1735 | err = xfrm_state_flush(proto, &audit_info); |
| 1733 | if (err) | 1736 | if (err) |
| @@ -2324,7 +2327,8 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
| 2324 | hdr->sadb_msg_type != SADB_X_SPDUPDATE); | 2327 | hdr->sadb_msg_type != SADB_X_SPDUPDATE); |
| 2325 | 2328 | ||
| 2326 | xfrm_audit_policy_add(xp, err ? 0 : 1, | 2329 | xfrm_audit_policy_add(xp, err ? 0 : 1, |
| 2327 | audit_get_loginuid(current), 0); | 2330 | audit_get_loginuid(current), |
| 2331 | audit_get_sessionid(current), 0); | ||
| 2328 | 2332 | ||
| 2329 | if (err) | 2333 | if (err) |
| 2330 | goto out; | 2334 | goto out; |
| @@ -2406,7 +2410,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
| 2406 | return -ENOENT; | 2410 | return -ENOENT; |
| 2407 | 2411 | ||
| 2408 | xfrm_audit_policy_delete(xp, err ? 0 : 1, | 2412 | xfrm_audit_policy_delete(xp, err ? 0 : 1, |
| 2409 | audit_get_loginuid(current), 0); | 2413 | audit_get_loginuid(current), |
| 2414 | audit_get_sessionid(current), 0); | ||
| 2410 | 2415 | ||
| 2411 | if (err) | 2416 | if (err) |
| 2412 | goto out; | 2417 | goto out; |
| @@ -2667,7 +2672,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
| 2667 | 2672 | ||
| 2668 | if (delete) { | 2673 | if (delete) { |
| 2669 | xfrm_audit_policy_delete(xp, err ? 0 : 1, | 2674 | xfrm_audit_policy_delete(xp, err ? 0 : 1, |
| 2670 | audit_get_loginuid(current), 0); | 2675 | audit_get_loginuid(current), |
| 2676 | audit_get_sessionid(current), 0); | ||
| 2671 | 2677 | ||
| 2672 | if (err) | 2678 | if (err) |
| 2673 | goto out; | 2679 | goto out; |
| @@ -2767,6 +2773,7 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
| 2767 | int err; | 2773 | int err; |
| 2768 | 2774 | ||
| 2769 | audit_info.loginuid = audit_get_loginuid(current); | 2775 | audit_info.loginuid = audit_get_loginuid(current); |
| 2776 | audit_info.sessionid = audit_get_sessionid(current); | ||
| 2770 | audit_info.secid = 0; | 2777 | audit_info.secid = 0; |
| 2771 | err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); | 2778 | err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); |
| 2772 | if (err) | 2779 | if (err) |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index d282ad1570a7..0099da5b2591 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
| @@ -1780,6 +1780,7 @@ int __init netlbl_unlabel_defconf(void) | |||
| 1780 | * messages so don't worry to much about these values. */ | 1780 | * messages so don't worry to much about these values. */ |
| 1781 | security_task_getsecid(current, &audit_info.secid); | 1781 | security_task_getsecid(current, &audit_info.secid); |
| 1782 | audit_info.loginuid = 0; | 1782 | audit_info.loginuid = 0; |
| 1783 | audit_info.sessionid = 0; | ||
| 1783 | 1784 | ||
| 1784 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | 1785 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
| 1785 | if (entry == NULL) | 1786 | if (entry == NULL) |
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index b17d4203806e..68706b4e3bf8 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c | |||
| @@ -107,7 +107,9 @@ struct audit_buffer *netlbl_audit_start_common(int type, | |||
| 107 | if (audit_buf == NULL) | 107 | if (audit_buf == NULL) |
| 108 | return NULL; | 108 | return NULL; |
| 109 | 109 | ||
| 110 | audit_log_format(audit_buf, "netlabel: auid=%u", audit_info->loginuid); | 110 | audit_log_format(audit_buf, "netlabel: auid=%u ses=%u", |
| 111 | audit_info->loginuid, | ||
| 112 | audit_info->sessionid); | ||
| 111 | 113 | ||
| 112 | if (audit_info->secid != 0 && | 114 | if (audit_info->secid != 0 && |
| 113 | security_secid_to_secctx(audit_info->secid, | 115 | security_secid_to_secctx(audit_info->secid, |
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index 6d7f4ab46c2b..6caef8b20611 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h | |||
| @@ -51,6 +51,7 @@ static inline void netlbl_netlink_auditinfo(struct sk_buff *skb, | |||
| 51 | { | 51 | { |
| 52 | audit_info->secid = NETLINK_CB(skb).sid; | 52 | audit_info->secid = NETLINK_CB(skb).sid; |
| 53 | audit_info->loginuid = NETLINK_CB(skb).loginuid; | 53 | audit_info->loginuid = NETLINK_CB(skb).loginuid; |
| 54 | audit_info->sessionid = NETLINK_CB(skb).sessionid; | ||
| 54 | } | 55 | } |
| 55 | 56 | ||
| 56 | /* NetLabel NETLINK I/O functions */ | 57 | /* NetLabel NETLINK I/O functions */ |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 46f3e44bb83a..9b97f8006c9c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -1248,6 +1248,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1248 | NETLINK_CB(skb).pid = nlk->pid; | 1248 | NETLINK_CB(skb).pid = nlk->pid; |
| 1249 | NETLINK_CB(skb).dst_group = dst_group; | 1249 | NETLINK_CB(skb).dst_group = dst_group; |
| 1250 | NETLINK_CB(skb).loginuid = audit_get_loginuid(current); | 1250 | NETLINK_CB(skb).loginuid = audit_get_loginuid(current); |
| 1251 | NETLINK_CB(skb).sessionid = audit_get_sessionid(current); | ||
| 1251 | security_task_getsecid(current, &(NETLINK_CB(skb).sid)); | 1252 | security_task_getsecid(current, &(NETLINK_CB(skb).sid)); |
| 1252 | memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); | 1253 | memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); |
| 1253 | 1254 | ||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index e0c0390613c0..cae9fd815543 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -762,6 +762,7 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | |||
| 762 | if (err) { | 762 | if (err) { |
| 763 | xfrm_audit_policy_delete(pol, 0, | 763 | xfrm_audit_policy_delete(pol, 0, |
| 764 | audit_info->loginuid, | 764 | audit_info->loginuid, |
| 765 | audit_info->sessionid, | ||
| 765 | audit_info->secid); | 766 | audit_info->secid); |
| 766 | return err; | 767 | return err; |
| 767 | } | 768 | } |
| @@ -777,6 +778,7 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | |||
| 777 | if (err) { | 778 | if (err) { |
| 778 | xfrm_audit_policy_delete(pol, 0, | 779 | xfrm_audit_policy_delete(pol, 0, |
| 779 | audit_info->loginuid, | 780 | audit_info->loginuid, |
| 781 | audit_info->sessionid, | ||
| 780 | audit_info->secid); | 782 | audit_info->secid); |
| 781 | return err; | 783 | return err; |
| 782 | } | 784 | } |
| @@ -819,6 +821,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | |||
| 819 | write_unlock_bh(&xfrm_policy_lock); | 821 | write_unlock_bh(&xfrm_policy_lock); |
| 820 | 822 | ||
| 821 | xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, | 823 | xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, |
| 824 | audit_info->sessionid, | ||
| 822 | audit_info->secid); | 825 | audit_info->secid); |
| 823 | 826 | ||
| 824 | xfrm_policy_kill(pol); | 827 | xfrm_policy_kill(pol); |
| @@ -841,6 +844,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | |||
| 841 | 844 | ||
| 842 | xfrm_audit_policy_delete(pol, 1, | 845 | xfrm_audit_policy_delete(pol, 1, |
| 843 | audit_info->loginuid, | 846 | audit_info->loginuid, |
| 847 | audit_info->sessionid, | ||
| 844 | audit_info->secid); | 848 | audit_info->secid); |
| 845 | xfrm_policy_kill(pol); | 849 | xfrm_policy_kill(pol); |
| 846 | killed++; | 850 | killed++; |
| @@ -2472,14 +2476,14 @@ static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp, | |||
| 2472 | } | 2476 | } |
| 2473 | 2477 | ||
| 2474 | void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | 2478 | void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, |
| 2475 | u32 auid, u32 secid) | 2479 | uid_t auid, u32 sessionid, u32 secid) |
| 2476 | { | 2480 | { |
| 2477 | struct audit_buffer *audit_buf; | 2481 | struct audit_buffer *audit_buf; |
| 2478 | 2482 | ||
| 2479 | audit_buf = xfrm_audit_start("SPD-add"); | 2483 | audit_buf = xfrm_audit_start("SPD-add"); |
| 2480 | if (audit_buf == NULL) | 2484 | if (audit_buf == NULL) |
| 2481 | return; | 2485 | return; |
| 2482 | xfrm_audit_helper_usrinfo(auid, secid, audit_buf); | 2486 | xfrm_audit_helper_usrinfo(auid, sessionid, secid, audit_buf); |
| 2483 | audit_log_format(audit_buf, " res=%u", result); | 2487 | audit_log_format(audit_buf, " res=%u", result); |
| 2484 | xfrm_audit_common_policyinfo(xp, audit_buf); | 2488 | xfrm_audit_common_policyinfo(xp, audit_buf); |
| 2485 | audit_log_end(audit_buf); | 2489 | audit_log_end(audit_buf); |
| @@ -2487,14 +2491,14 @@ void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | |||
| 2487 | EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); | 2491 | EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); |
| 2488 | 2492 | ||
| 2489 | void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, | 2493 | void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, |
| 2490 | u32 auid, u32 secid) | 2494 | uid_t auid, u32 sessionid, u32 secid) |
| 2491 | { | 2495 | { |
| 2492 | struct audit_buffer *audit_buf; | 2496 | struct audit_buffer *audit_buf; |
| 2493 | 2497 | ||
| 2494 | audit_buf = xfrm_audit_start("SPD-delete"); | 2498 | audit_buf = xfrm_audit_start("SPD-delete"); |
| 2495 | if (audit_buf == NULL) | 2499 | if (audit_buf == NULL) |
| 2496 | return; | 2500 | return; |
| 2497 | xfrm_audit_helper_usrinfo(auid, secid, audit_buf); | 2501 | xfrm_audit_helper_usrinfo(auid, sessionid, secid, audit_buf); |
| 2498 | audit_log_format(audit_buf, " res=%u", result); | 2502 | audit_log_format(audit_buf, " res=%u", result); |
| 2499 | xfrm_audit_common_policyinfo(xp, audit_buf); | 2503 | xfrm_audit_common_policyinfo(xp, audit_buf); |
| 2500 | audit_log_end(audit_buf); | 2504 | audit_log_end(audit_buf); |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index fac27ce770d5..72fddafd891a 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -496,7 +496,8 @@ expired: | |||
| 496 | km_state_expired(x, 1, 0); | 496 | km_state_expired(x, 1, 0); |
| 497 | 497 | ||
| 498 | xfrm_audit_state_delete(x, err ? 0 : 1, | 498 | xfrm_audit_state_delete(x, err ? 0 : 1, |
| 499 | audit_get_loginuid(current), 0); | 499 | audit_get_loginuid(current), |
| 500 | audit_get_sessionid(current), 0); | ||
| 500 | 501 | ||
| 501 | out: | 502 | out: |
| 502 | spin_unlock(&x->lock); | 503 | spin_unlock(&x->lock); |
| @@ -603,6 +604,7 @@ xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) | |||
| 603 | (err = security_xfrm_state_delete(x)) != 0) { | 604 | (err = security_xfrm_state_delete(x)) != 0) { |
| 604 | xfrm_audit_state_delete(x, 0, | 605 | xfrm_audit_state_delete(x, 0, |
| 605 | audit_info->loginuid, | 606 | audit_info->loginuid, |
| 607 | audit_info->sessionid, | ||
| 606 | audit_info->secid); | 608 | audit_info->secid); |
| 607 | return err; | 609 | return err; |
| 608 | } | 610 | } |
| @@ -641,6 +643,7 @@ restart: | |||
| 641 | err = xfrm_state_delete(x); | 643 | err = xfrm_state_delete(x); |
| 642 | xfrm_audit_state_delete(x, err ? 0 : 1, | 644 | xfrm_audit_state_delete(x, err ? 0 : 1, |
| 643 | audit_info->loginuid, | 645 | audit_info->loginuid, |
| 646 | audit_info->sessionid, | ||
| 644 | audit_info->secid); | 647 | audit_info->secid); |
| 645 | xfrm_state_put(x); | 648 | xfrm_state_put(x); |
| 646 | 649 | ||
| @@ -2123,14 +2126,14 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family, | |||
| 2123 | } | 2126 | } |
| 2124 | 2127 | ||
| 2125 | void xfrm_audit_state_add(struct xfrm_state *x, int result, | 2128 | void xfrm_audit_state_add(struct xfrm_state *x, int result, |
| 2126 | u32 auid, u32 secid) | 2129 | uid_t auid, u32 sessionid, u32 secid) |
| 2127 | { | 2130 | { |
| 2128 | struct audit_buffer *audit_buf; | 2131 | struct audit_buffer *audit_buf; |
| 2129 | 2132 | ||
| 2130 | audit_buf = xfrm_audit_start("SAD-add"); | 2133 | audit_buf = xfrm_audit_start("SAD-add"); |
| 2131 | if (audit_buf == NULL) | 2134 | if (audit_buf == NULL) |
| 2132 | return; | 2135 | return; |
| 2133 | xfrm_audit_helper_usrinfo(auid, secid, audit_buf); | 2136 | xfrm_audit_helper_usrinfo(auid, sessionid, secid, audit_buf); |
| 2134 | xfrm_audit_helper_sainfo(x, audit_buf); | 2137 | xfrm_audit_helper_sainfo(x, audit_buf); |
| 2135 | audit_log_format(audit_buf, " res=%u", result); | 2138 | audit_log_format(audit_buf, " res=%u", result); |
| 2136 | audit_log_end(audit_buf); | 2139 | audit_log_end(audit_buf); |
| @@ -2138,14 +2141,14 @@ void xfrm_audit_state_add(struct xfrm_state *x, int result, | |||
| 2138 | EXPORT_SYMBOL_GPL(xfrm_audit_state_add); | 2141 | EXPORT_SYMBOL_GPL(xfrm_audit_state_add); |
| 2139 | 2142 | ||
| 2140 | void xfrm_audit_state_delete(struct xfrm_state *x, int result, | 2143 | void xfrm_audit_state_delete(struct xfrm_state *x, int result, |
| 2141 | u32 auid, u32 secid) | 2144 | uid_t auid, u32 sessionid, u32 secid) |
| 2142 | { | 2145 | { |
| 2143 | struct audit_buffer *audit_buf; | 2146 | struct audit_buffer *audit_buf; |
| 2144 | 2147 | ||
| 2145 | audit_buf = xfrm_audit_start("SAD-delete"); | 2148 | audit_buf = xfrm_audit_start("SAD-delete"); |
| 2146 | if (audit_buf == NULL) | 2149 | if (audit_buf == NULL) |
| 2147 | return; | 2150 | return; |
| 2148 | xfrm_audit_helper_usrinfo(auid, secid, audit_buf); | 2151 | xfrm_audit_helper_usrinfo(auid, sessionid, secid, audit_buf); |
| 2149 | xfrm_audit_helper_sainfo(x, audit_buf); | 2152 | xfrm_audit_helper_sainfo(x, audit_buf); |
| 2150 | audit_log_format(audit_buf, " res=%u", result); | 2153 | audit_log_format(audit_buf, " res=%u", result); |
| 2151 | audit_log_end(audit_buf); | 2154 | audit_log_end(audit_buf); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 22a30ae582a2..a1b0fbe3ea35 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -407,6 +407,9 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 407 | struct xfrm_state *x; | 407 | struct xfrm_state *x; |
| 408 | int err; | 408 | int err; |
| 409 | struct km_event c; | 409 | struct km_event c; |
| 410 | uid_t loginuid = NETLINK_CB(skb).loginuid; | ||
| 411 | u32 sessionid = NETLINK_CB(skb).sessionid; | ||
| 412 | u32 sid = NETLINK_CB(skb).sid; | ||
| 410 | 413 | ||
| 411 | err = verify_newsa_info(p, attrs); | 414 | err = verify_newsa_info(p, attrs); |
| 412 | if (err) | 415 | if (err) |
| @@ -422,8 +425,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 422 | else | 425 | else |
| 423 | err = xfrm_state_update(x); | 426 | err = xfrm_state_update(x); |
| 424 | 427 | ||
| 425 | xfrm_audit_state_add(x, err ? 0 : 1, NETLINK_CB(skb).loginuid, | 428 | xfrm_audit_state_add(x, err ? 0 : 1, loginuid, sessionid, sid); |
| 426 | NETLINK_CB(skb).sid); | ||
| 427 | 429 | ||
| 428 | if (err < 0) { | 430 | if (err < 0) { |
| 429 | x->km.state = XFRM_STATE_DEAD; | 431 | x->km.state = XFRM_STATE_DEAD; |
| @@ -478,6 +480,9 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 478 | int err = -ESRCH; | 480 | int err = -ESRCH; |
| 479 | struct km_event c; | 481 | struct km_event c; |
| 480 | struct xfrm_usersa_id *p = nlmsg_data(nlh); | 482 | struct xfrm_usersa_id *p = nlmsg_data(nlh); |
| 483 | uid_t loginuid = NETLINK_CB(skb).loginuid; | ||
| 484 | u32 sessionid = NETLINK_CB(skb).sessionid; | ||
| 485 | u32 sid = NETLINK_CB(skb).sid; | ||
| 481 | 486 | ||
| 482 | x = xfrm_user_state_lookup(p, attrs, &err); | 487 | x = xfrm_user_state_lookup(p, attrs, &err); |
| 483 | if (x == NULL) | 488 | if (x == NULL) |
| @@ -502,8 +507,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 502 | km_state_notify(x, &c); | 507 | km_state_notify(x, &c); |
| 503 | 508 | ||
| 504 | out: | 509 | out: |
| 505 | xfrm_audit_state_delete(x, err ? 0 : 1, NETLINK_CB(skb).loginuid, | 510 | xfrm_audit_state_delete(x, err ? 0 : 1, loginuid, sessionid, sid); |
| 506 | NETLINK_CB(skb).sid); | ||
| 507 | xfrm_state_put(x); | 511 | xfrm_state_put(x); |
| 508 | return err; | 512 | return err; |
| 509 | } | 513 | } |
| @@ -1123,6 +1127,9 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1123 | struct km_event c; | 1127 | struct km_event c; |
| 1124 | int err; | 1128 | int err; |
| 1125 | int excl; | 1129 | int excl; |
| 1130 | uid_t loginuid = NETLINK_CB(skb).loginuid; | ||
| 1131 | u32 sessionid = NETLINK_CB(skb).sessionid; | ||
| 1132 | u32 sid = NETLINK_CB(skb).sid; | ||
| 1126 | 1133 | ||
| 1127 | err = verify_newpolicy_info(p); | 1134 | err = verify_newpolicy_info(p); |
| 1128 | if (err) | 1135 | if (err) |
| @@ -1141,8 +1148,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1141 | * a type XFRM_MSG_UPDPOLICY - JHS */ | 1148 | * a type XFRM_MSG_UPDPOLICY - JHS */ |
| 1142 | excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; | 1149 | excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; |
| 1143 | err = xfrm_policy_insert(p->dir, xp, excl); | 1150 | err = xfrm_policy_insert(p->dir, xp, excl); |
| 1144 | xfrm_audit_policy_add(xp, err ? 0 : 1, NETLINK_CB(skb).loginuid, | 1151 | xfrm_audit_policy_add(xp, err ? 0 : 1, loginuid, sessionid, sid); |
| 1145 | NETLINK_CB(skb).sid); | ||
| 1146 | 1152 | ||
| 1147 | if (err) { | 1153 | if (err) { |
| 1148 | security_xfrm_policy_free(xp->security); | 1154 | security_xfrm_policy_free(xp->security); |
| @@ -1371,9 +1377,12 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1371 | NETLINK_CB(skb).pid); | 1377 | NETLINK_CB(skb).pid); |
| 1372 | } | 1378 | } |
| 1373 | } else { | 1379 | } else { |
| 1374 | xfrm_audit_policy_delete(xp, err ? 0 : 1, | 1380 | uid_t loginuid = NETLINK_CB(skb).loginuid; |
| 1375 | NETLINK_CB(skb).loginuid, | 1381 | u32 sessionid = NETLINK_CB(skb).sessionid; |
| 1376 | NETLINK_CB(skb).sid); | 1382 | u32 sid = NETLINK_CB(skb).sid; |
| 1383 | |||
| 1384 | xfrm_audit_policy_delete(xp, err ? 0 : 1, loginuid, sessionid, | ||
| 1385 | sid); | ||
| 1377 | 1386 | ||
| 1378 | if (err != 0) | 1387 | if (err != 0) |
| 1379 | goto out; | 1388 | goto out; |
| @@ -1399,6 +1408,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1399 | int err; | 1408 | int err; |
| 1400 | 1409 | ||
| 1401 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1410 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
| 1411 | audit_info.sessionid = NETLINK_CB(skb).sessionid; | ||
| 1402 | audit_info.secid = NETLINK_CB(skb).sid; | 1412 | audit_info.secid = NETLINK_CB(skb).sid; |
| 1403 | err = xfrm_state_flush(p->proto, &audit_info); | 1413 | err = xfrm_state_flush(p->proto, &audit_info); |
| 1404 | if (err) | 1414 | if (err) |
| @@ -1546,6 +1556,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1546 | return err; | 1556 | return err; |
| 1547 | 1557 | ||
| 1548 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1558 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
| 1559 | audit_info.sessionid = NETLINK_CB(skb).sessionid; | ||
| 1549 | audit_info.secid = NETLINK_CB(skb).sid; | 1560 | audit_info.secid = NETLINK_CB(skb).sid; |
| 1550 | err = xfrm_policy_flush(type, &audit_info); | 1561 | err = xfrm_policy_flush(type, &audit_info); |
| 1551 | if (err) | 1562 | if (err) |
| @@ -1604,9 +1615,11 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1604 | read_unlock(&xp->lock); | 1615 | read_unlock(&xp->lock); |
| 1605 | err = 0; | 1616 | err = 0; |
| 1606 | if (up->hard) { | 1617 | if (up->hard) { |
| 1618 | uid_t loginuid = NETLINK_CB(skb).loginuid; | ||
| 1619 | uid_t sessionid = NETLINK_CB(skb).sessionid; | ||
| 1620 | u32 sid = NETLINK_CB(skb).sid; | ||
| 1607 | xfrm_policy_delete(xp, p->dir); | 1621 | xfrm_policy_delete(xp, p->dir); |
| 1608 | xfrm_audit_policy_delete(xp, 1, NETLINK_CB(skb).loginuid, | 1622 | xfrm_audit_policy_delete(xp, 1, loginuid, sessionid, sid); |
| 1609 | NETLINK_CB(skb).sid); | ||
| 1610 | 1623 | ||
| 1611 | } else { | 1624 | } else { |
| 1612 | // reset the timers here? | 1625 | // reset the timers here? |
| @@ -1640,9 +1653,11 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 1640 | km_state_expired(x, ue->hard, current->pid); | 1653 | km_state_expired(x, ue->hard, current->pid); |
| 1641 | 1654 | ||
| 1642 | if (ue->hard) { | 1655 | if (ue->hard) { |
| 1656 | uid_t loginuid = NETLINK_CB(skb).loginuid; | ||
| 1657 | uid_t sessionid = NETLINK_CB(skb).sessionid; | ||
| 1658 | u32 sid = NETLINK_CB(skb).sid; | ||
| 1643 | __xfrm_state_delete(x); | 1659 | __xfrm_state_delete(x); |
| 1644 | xfrm_audit_state_delete(x, 1, NETLINK_CB(skb).loginuid, | 1660 | xfrm_audit_state_delete(x, 1, loginuid, sessionid, sid); |
| 1645 | NETLINK_CB(skb).sid); | ||
| 1646 | } | 1661 | } |
| 1647 | err = 0; | 1662 | err = 0; |
| 1648 | out: | 1663 | out: |
diff --git a/security/dummy.c b/security/dummy.c index 48cf30226e16..f50c6c3c32c9 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
| @@ -968,7 +968,7 @@ static int dummy_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | |||
| 968 | return -EOPNOTSUPP; | 968 | return -EOPNOTSUPP; |
| 969 | } | 969 | } |
| 970 | 970 | ||
| 971 | static int dummy_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) | 971 | static int dummy_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) |
| 972 | { | 972 | { |
| 973 | return -EOPNOTSUPP; | 973 | return -EOPNOTSUPP; |
| 974 | } | 974 | } |
diff --git a/security/security.c b/security/security.c index 8e64a29dc55d..59838a99b80e 100644 --- a/security/security.c +++ b/security/security.c | |||
| @@ -886,7 +886,7 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | |||
| 886 | } | 886 | } |
| 887 | EXPORT_SYMBOL(security_secid_to_secctx); | 887 | EXPORT_SYMBOL(security_secid_to_secctx); |
| 888 | 888 | ||
| 889 | int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) | 889 | int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) |
| 890 | { | 890 | { |
| 891 | return security_ops->secctx_to_secid(secdata, seclen, secid); | 891 | return security_ops->secctx_to_secid(secdata, seclen, secid); |
| 892 | } | 892 | } |
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 95a8ef4a5073..114b4b4c97b2 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
| @@ -646,7 +646,7 @@ void avc_audit(u32 ssid, u32 tsid, | |||
| 646 | if (*p) | 646 | if (*p) |
| 647 | audit_log_untrustedstring(ab, p); | 647 | audit_log_untrustedstring(ab, p); |
| 648 | else | 648 | else |
| 649 | audit_log_hex(ab, p, len); | 649 | audit_log_n_hex(ab, p, len); |
| 650 | break; | 650 | break; |
| 651 | } | 651 | } |
| 652 | } | 652 | } |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4e4de98941ae..85a220465a8f 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -5238,7 +5238,7 @@ static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | |||
| 5238 | return security_sid_to_context(secid, secdata, seclen); | 5238 | return security_sid_to_context(secid, secdata, seclen); |
| 5239 | } | 5239 | } |
| 5240 | 5240 | ||
| 5241 | static int selinux_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) | 5241 | static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) |
| 5242 | { | 5242 | { |
| 5243 | return security_context_to_sid(secdata, seclen, secid); | 5243 | return security_context_to_sid(secdata, seclen, secid); |
| 5244 | } | 5244 | } |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index cdb14add27d2..ad30ac4273d6 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
| @@ -96,7 +96,7 @@ int security_sid_to_context(u32 sid, char **scontext, | |||
| 96 | int security_context_to_sid(const char *scontext, u32 scontext_len, | 96 | int security_context_to_sid(const char *scontext, u32 scontext_len, |
| 97 | u32 *out_sid); | 97 | u32 *out_sid); |
| 98 | 98 | ||
| 99 | int security_context_to_sid_default(char *scontext, u32 scontext_len, | 99 | int security_context_to_sid_default(const char *scontext, u32 scontext_len, |
| 100 | u32 *out_sid, u32 def_sid, gfp_t gfp_flags); | 100 | u32 *out_sid, u32 def_sid, gfp_t gfp_flags); |
| 101 | 101 | ||
| 102 | int security_get_user_sids(u32 callsid, char *username, | 102 | int security_get_user_sids(u32 callsid, char *username, |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 25cac5a2aa8e..dcc2e1c4fd83 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -858,8 +858,8 @@ int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid) | |||
| 858 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient | 858 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient |
| 859 | * memory is available, or 0 on success. | 859 | * memory is available, or 0 on success. |
| 860 | */ | 860 | */ |
| 861 | int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, | 861 | int security_context_to_sid_default(const char *scontext, u32 scontext_len, |
| 862 | u32 def_sid, gfp_t gfp_flags) | 862 | u32 *sid, u32 def_sid, gfp_t gfp_flags) |
| 863 | { | 863 | { |
| 864 | return security_context_to_sid_core(scontext, scontext_len, | 864 | return security_context_to_sid_core(scontext, scontext_len, |
| 865 | sid, def_sid, gfp_flags); | 865 | sid, def_sid, gfp_flags); |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 5d2ec5650e61..92baee53a7dc 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
| @@ -2406,7 +2406,7 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | |||
| 2406 | * | 2406 | * |
| 2407 | * Exists for audit and networking code. | 2407 | * Exists for audit and networking code. |
| 2408 | */ | 2408 | */ |
| 2409 | static int smack_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) | 2409 | static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) |
| 2410 | { | 2410 | { |
| 2411 | *secid = smack_to_secid(secdata); | 2411 | *secid = smack_to_secid(secdata); |
| 2412 | return 0; | 2412 | return 0; |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index a5da5a8cfe9b..271a835fbbe3 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
| @@ -324,6 +324,7 @@ static void smk_cipso_doi(void) | |||
| 324 | struct netlbl_audit audit_info; | 324 | struct netlbl_audit audit_info; |
| 325 | 325 | ||
| 326 | audit_info.loginuid = audit_get_loginuid(current); | 326 | audit_info.loginuid = audit_get_loginuid(current); |
| 327 | audit_info.sessionid = audit_get_sessionid(current); | ||
| 327 | audit_info.secid = smack_to_secid(current->security); | 328 | audit_info.secid = smack_to_secid(current->security); |
| 328 | 329 | ||
| 329 | rc = netlbl_cfg_map_del(NULL, &audit_info); | 330 | rc = netlbl_cfg_map_del(NULL, &audit_info); |
| @@ -356,6 +357,7 @@ static void smk_unlbl_ambient(char *oldambient) | |||
| 356 | struct netlbl_audit audit_info; | 357 | struct netlbl_audit audit_info; |
| 357 | 358 | ||
| 358 | audit_info.loginuid = audit_get_loginuid(current); | 359 | audit_info.loginuid = audit_get_loginuid(current); |
| 360 | audit_info.sessionid = audit_get_sessionid(current); | ||
| 359 | audit_info.secid = smack_to_secid(current->security); | 361 | audit_info.secid = smack_to_secid(current->security); |
| 360 | 362 | ||
| 361 | if (oldambient != NULL) { | 363 | if (oldambient != NULL) { |
