diff options
42 files changed, 667 insertions, 334 deletions
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts index 8c1febd7e3f2..c108bb451337 100644 --- a/arch/arm/boot/dts/imx6sx-sdb.dts +++ b/arch/arm/boot/dts/imx6sx-sdb.dts | |||
| @@ -166,12 +166,12 @@ | |||
| 166 | #address-cells = <1>; | 166 | #address-cells = <1>; |
| 167 | #size-cells = <0>; | 167 | #size-cells = <0>; |
| 168 | 168 | ||
| 169 | ethphy1: ethernet-phy@0 { | 169 | ethphy1: ethernet-phy@1 { |
| 170 | reg = <0>; | 170 | reg = <1>; |
| 171 | }; | 171 | }; |
| 172 | 172 | ||
| 173 | ethphy2: ethernet-phy@1 { | 173 | ethphy2: ethernet-phy@2 { |
| 174 | reg = <1>; | 174 | reg = <2>; |
| 175 | }; | 175 | }; |
| 176 | }; | 176 | }; |
| 177 | }; | 177 | }; |
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index f94a9fa60488..c672c4dcffac 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c | |||
| @@ -615,6 +615,9 @@ static void c_can_stop(struct net_device *dev) | |||
| 615 | 615 | ||
| 616 | c_can_irq_control(priv, false); | 616 | c_can_irq_control(priv, false); |
| 617 | 617 | ||
| 618 | /* put ctrl to init on stop to end ongoing transmission */ | ||
| 619 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_INIT); | ||
| 620 | |||
| 618 | /* deactivate pins */ | 621 | /* deactivate pins */ |
| 619 | pinctrl_pm_select_sleep_state(dev->dev.parent); | 622 | pinctrl_pm_select_sleep_state(dev->dev.parent); |
| 620 | priv->can.state = CAN_STATE_STOPPED; | 623 | priv->can.state = CAN_STATE_STOPPED; |
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index c32cd61073bc..7af379ca861b 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c | |||
| @@ -587,7 +587,7 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv, | |||
| 587 | usb_sndbulkpipe(dev->udev, | 587 | usb_sndbulkpipe(dev->udev, |
| 588 | dev->bulk_out->bEndpointAddress), | 588 | dev->bulk_out->bEndpointAddress), |
| 589 | buf, msg->len, | 589 | buf, msg->len, |
| 590 | kvaser_usb_simple_msg_callback, priv); | 590 | kvaser_usb_simple_msg_callback, netdev); |
| 591 | usb_anchor_urb(urb, &priv->tx_submitted); | 591 | usb_anchor_urb(urb, &priv->tx_submitted); |
| 592 | 592 | ||
| 593 | err = usb_submit_urb(urb, GFP_ATOMIC); | 593 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| @@ -662,11 +662,6 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
| 662 | priv = dev->nets[channel]; | 662 | priv = dev->nets[channel]; |
| 663 | stats = &priv->netdev->stats; | 663 | stats = &priv->netdev->stats; |
| 664 | 664 | ||
| 665 | if (status & M16C_STATE_BUS_RESET) { | ||
| 666 | kvaser_usb_unlink_tx_urbs(priv); | ||
| 667 | return; | ||
| 668 | } | ||
| 669 | |||
| 670 | skb = alloc_can_err_skb(priv->netdev, &cf); | 665 | skb = alloc_can_err_skb(priv->netdev, &cf); |
| 671 | if (!skb) { | 666 | if (!skb) { |
| 672 | stats->rx_dropped++; | 667 | stats->rx_dropped++; |
| @@ -677,7 +672,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
| 677 | 672 | ||
| 678 | netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status); | 673 | netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status); |
| 679 | 674 | ||
| 680 | if (status & M16C_STATE_BUS_OFF) { | 675 | if (status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) { |
| 681 | cf->can_id |= CAN_ERR_BUSOFF; | 676 | cf->can_id |= CAN_ERR_BUSOFF; |
| 682 | 677 | ||
| 683 | priv->can.can_stats.bus_off++; | 678 | priv->can.can_stats.bus_off++; |
| @@ -703,9 +698,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
| 703 | } | 698 | } |
| 704 | 699 | ||
| 705 | new_state = CAN_STATE_ERROR_PASSIVE; | 700 | new_state = CAN_STATE_ERROR_PASSIVE; |
| 706 | } | 701 | } else if (status & M16C_STATE_BUS_ERROR) { |
| 707 | |||
| 708 | if (status == M16C_STATE_BUS_ERROR) { | ||
| 709 | if ((priv->can.state < CAN_STATE_ERROR_WARNING) && | 702 | if ((priv->can.state < CAN_STATE_ERROR_WARNING) && |
| 710 | ((txerr >= 96) || (rxerr >= 96))) { | 703 | ((txerr >= 96) || (rxerr >= 96))) { |
| 711 | cf->can_id |= CAN_ERR_CRTL; | 704 | cf->can_id |= CAN_ERR_CRTL; |
| @@ -715,7 +708,8 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
| 715 | 708 | ||
| 716 | priv->can.can_stats.error_warning++; | 709 | priv->can.can_stats.error_warning++; |
| 717 | new_state = CAN_STATE_ERROR_WARNING; | 710 | new_state = CAN_STATE_ERROR_WARNING; |
| 718 | } else if (priv->can.state > CAN_STATE_ERROR_ACTIVE) { | 711 | } else if ((priv->can.state > CAN_STATE_ERROR_ACTIVE) && |
| 712 | ((txerr < 96) && (rxerr < 96))) { | ||
| 719 | cf->can_id |= CAN_ERR_PROT; | 713 | cf->can_id |= CAN_ERR_PROT; |
| 720 | cf->data[2] = CAN_ERR_PROT_ACTIVE; | 714 | cf->data[2] = CAN_ERR_PROT_ACTIVE; |
| 721 | 715 | ||
| @@ -1590,7 +1584,7 @@ static int kvaser_usb_probe(struct usb_interface *intf, | |||
| 1590 | { | 1584 | { |
| 1591 | struct kvaser_usb *dev; | 1585 | struct kvaser_usb *dev; |
| 1592 | int err = -ENOMEM; | 1586 | int err = -ENOMEM; |
| 1593 | int i; | 1587 | int i, retry = 3; |
| 1594 | 1588 | ||
| 1595 | dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); | 1589 | dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); |
| 1596 | if (!dev) | 1590 | if (!dev) |
| @@ -1608,7 +1602,15 @@ static int kvaser_usb_probe(struct usb_interface *intf, | |||
| 1608 | 1602 | ||
| 1609 | usb_set_intfdata(intf, dev); | 1603 | usb_set_intfdata(intf, dev); |
| 1610 | 1604 | ||
| 1611 | err = kvaser_usb_get_software_info(dev); | 1605 | /* On some x86 laptops, plugging a Kvaser device again after |
| 1606 | * an unplug makes the firmware always ignore the very first | ||
| 1607 | * command. For such a case, provide some room for retries | ||
| 1608 | * instead of completely exiting the driver. | ||
| 1609 | */ | ||
| 1610 | do { | ||
| 1611 | err = kvaser_usb_get_software_info(dev); | ||
| 1612 | } while (--retry && err == -ETIMEDOUT); | ||
| 1613 | |||
| 1612 | if (err) { | 1614 | if (err) { |
| 1613 | dev_err(&intf->dev, | 1615 | dev_err(&intf->dev, |
| 1614 | "Cannot get software infos, error %d\n", err); | 1616 | "Cannot get software infos, error %d\n", err); |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h index 75b08c63d39f..29a09271b64a 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h | |||
| @@ -767,16 +767,17 @@ | |||
| 767 | #define MTL_Q_RQOMR 0x40 | 767 | #define MTL_Q_RQOMR 0x40 |
| 768 | #define MTL_Q_RQMPOCR 0x44 | 768 | #define MTL_Q_RQMPOCR 0x44 |
| 769 | #define MTL_Q_RQDR 0x4c | 769 | #define MTL_Q_RQDR 0x4c |
| 770 | #define MTL_Q_RQFCR 0x50 | ||
| 770 | #define MTL_Q_IER 0x70 | 771 | #define MTL_Q_IER 0x70 |
| 771 | #define MTL_Q_ISR 0x74 | 772 | #define MTL_Q_ISR 0x74 |
| 772 | 773 | ||
| 773 | /* MTL queue register entry bit positions and sizes */ | 774 | /* MTL queue register entry bit positions and sizes */ |
| 775 | #define MTL_Q_RQFCR_RFA_INDEX 1 | ||
| 776 | #define MTL_Q_RQFCR_RFA_WIDTH 6 | ||
| 777 | #define MTL_Q_RQFCR_RFD_INDEX 17 | ||
| 778 | #define MTL_Q_RQFCR_RFD_WIDTH 6 | ||
| 774 | #define MTL_Q_RQOMR_EHFC_INDEX 7 | 779 | #define MTL_Q_RQOMR_EHFC_INDEX 7 |
| 775 | #define MTL_Q_RQOMR_EHFC_WIDTH 1 | 780 | #define MTL_Q_RQOMR_EHFC_WIDTH 1 |
| 776 | #define MTL_Q_RQOMR_RFA_INDEX 8 | ||
| 777 | #define MTL_Q_RQOMR_RFA_WIDTH 3 | ||
| 778 | #define MTL_Q_RQOMR_RFD_INDEX 13 | ||
| 779 | #define MTL_Q_RQOMR_RFD_WIDTH 3 | ||
| 780 | #define MTL_Q_RQOMR_RQS_INDEX 16 | 781 | #define MTL_Q_RQOMR_RQS_INDEX 16 |
| 781 | #define MTL_Q_RQOMR_RQS_WIDTH 9 | 782 | #define MTL_Q_RQOMR_RQS_WIDTH 9 |
| 782 | #define MTL_Q_RQOMR_RSF_INDEX 5 | 783 | #define MTL_Q_RQOMR_RSF_INDEX 5 |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 53f5f66ec2ee..4c66cd1d1e60 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c | |||
| @@ -2079,10 +2079,10 @@ static void xgbe_config_flow_control_threshold(struct xgbe_prv_data *pdata) | |||
| 2079 | 2079 | ||
| 2080 | for (i = 0; i < pdata->rx_q_count; i++) { | 2080 | for (i = 0; i < pdata->rx_q_count; i++) { |
| 2081 | /* Activate flow control when less than 4k left in fifo */ | 2081 | /* Activate flow control when less than 4k left in fifo */ |
| 2082 | XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFA, 2); | 2082 | XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQFCR, RFA, 2); |
| 2083 | 2083 | ||
| 2084 | /* De-activate flow control when more than 6k left in fifo */ | 2084 | /* De-activate flow control when more than 6k left in fifo */ |
| 2085 | XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFD, 4); | 2085 | XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQFCR, RFD, 4); |
| 2086 | } | 2086 | } |
| 2087 | } | 2087 | } |
| 2088 | 2088 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 1d1147c93d59..e468ed3f210f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
| @@ -3175,7 +3175,7 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) | |||
| 3175 | } | 3175 | } |
| 3176 | #endif | 3176 | #endif |
| 3177 | if (!bnx2x_fp_lock_napi(fp)) | 3177 | if (!bnx2x_fp_lock_napi(fp)) |
| 3178 | return work_done; | 3178 | return budget; |
| 3179 | 3179 | ||
| 3180 | for_each_cos_in_tx_queue(fp, cos) | 3180 | for_each_cos_in_tx_queue(fp, cos) |
| 3181 | if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos])) | 3181 | if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos])) |
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index b29e027c476e..e356afa44e7d 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c | |||
| @@ -1335,7 +1335,7 @@ static int enic_poll_msix_rq(struct napi_struct *napi, int budget) | |||
| 1335 | int err; | 1335 | int err; |
| 1336 | 1336 | ||
| 1337 | if (!enic_poll_lock_napi(&enic->rq[rq])) | 1337 | if (!enic_poll_lock_napi(&enic->rq[rq])) |
| 1338 | return work_done; | 1338 | return budget; |
| 1339 | /* Service RQ | 1339 | /* Service RQ |
| 1340 | */ | 1340 | */ |
| 1341 | 1341 | ||
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index a62fc38f045e..1c75829eb166 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c | |||
| @@ -192,6 +192,10 @@ static char mv643xx_eth_driver_version[] = "1.4"; | |||
| 192 | #define IS_TSO_HEADER(txq, addr) \ | 192 | #define IS_TSO_HEADER(txq, addr) \ |
| 193 | ((addr >= txq->tso_hdrs_dma) && \ | 193 | ((addr >= txq->tso_hdrs_dma) && \ |
| 194 | (addr < txq->tso_hdrs_dma + txq->tx_ring_size * TSO_HEADER_SIZE)) | 194 | (addr < txq->tso_hdrs_dma + txq->tx_ring_size * TSO_HEADER_SIZE)) |
| 195 | |||
| 196 | #define DESC_DMA_MAP_SINGLE 0 | ||
| 197 | #define DESC_DMA_MAP_PAGE 1 | ||
| 198 | |||
| 195 | /* | 199 | /* |
| 196 | * RX/TX descriptors. | 200 | * RX/TX descriptors. |
| 197 | */ | 201 | */ |
| @@ -362,6 +366,7 @@ struct tx_queue { | |||
| 362 | dma_addr_t tso_hdrs_dma; | 366 | dma_addr_t tso_hdrs_dma; |
| 363 | 367 | ||
| 364 | struct tx_desc *tx_desc_area; | 368 | struct tx_desc *tx_desc_area; |
| 369 | char *tx_desc_mapping; /* array to track the type of the dma mapping */ | ||
| 365 | dma_addr_t tx_desc_dma; | 370 | dma_addr_t tx_desc_dma; |
| 366 | int tx_desc_area_size; | 371 | int tx_desc_area_size; |
| 367 | 372 | ||
| @@ -750,6 +755,7 @@ txq_put_data_tso(struct net_device *dev, struct tx_queue *txq, | |||
| 750 | if (txq->tx_curr_desc == txq->tx_ring_size) | 755 | if (txq->tx_curr_desc == txq->tx_ring_size) |
| 751 | txq->tx_curr_desc = 0; | 756 | txq->tx_curr_desc = 0; |
| 752 | desc = &txq->tx_desc_area[tx_index]; | 757 | desc = &txq->tx_desc_area[tx_index]; |
| 758 | txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_SINGLE; | ||
| 753 | 759 | ||
| 754 | desc->l4i_chk = 0; | 760 | desc->l4i_chk = 0; |
| 755 | desc->byte_cnt = length; | 761 | desc->byte_cnt = length; |
| @@ -879,14 +885,13 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) | |||
| 879 | skb_frag_t *this_frag; | 885 | skb_frag_t *this_frag; |
| 880 | int tx_index; | 886 | int tx_index; |
| 881 | struct tx_desc *desc; | 887 | struct tx_desc *desc; |
| 882 | void *addr; | ||
| 883 | 888 | ||
| 884 | this_frag = &skb_shinfo(skb)->frags[frag]; | 889 | this_frag = &skb_shinfo(skb)->frags[frag]; |
| 885 | addr = page_address(this_frag->page.p) + this_frag->page_offset; | ||
| 886 | tx_index = txq->tx_curr_desc++; | 890 | tx_index = txq->tx_curr_desc++; |
| 887 | if (txq->tx_curr_desc == txq->tx_ring_size) | 891 | if (txq->tx_curr_desc == txq->tx_ring_size) |
| 888 | txq->tx_curr_desc = 0; | 892 | txq->tx_curr_desc = 0; |
| 889 | desc = &txq->tx_desc_area[tx_index]; | 893 | desc = &txq->tx_desc_area[tx_index]; |
| 894 | txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_PAGE; | ||
| 890 | 895 | ||
| 891 | /* | 896 | /* |
| 892 | * The last fragment will generate an interrupt | 897 | * The last fragment will generate an interrupt |
| @@ -902,8 +907,9 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) | |||
| 902 | 907 | ||
| 903 | desc->l4i_chk = 0; | 908 | desc->l4i_chk = 0; |
| 904 | desc->byte_cnt = skb_frag_size(this_frag); | 909 | desc->byte_cnt = skb_frag_size(this_frag); |
| 905 | desc->buf_ptr = dma_map_single(mp->dev->dev.parent, addr, | 910 | desc->buf_ptr = skb_frag_dma_map(mp->dev->dev.parent, |
| 906 | desc->byte_cnt, DMA_TO_DEVICE); | 911 | this_frag, 0, desc->byte_cnt, |
| 912 | DMA_TO_DEVICE); | ||
| 907 | } | 913 | } |
| 908 | } | 914 | } |
| 909 | 915 | ||
| @@ -936,6 +942,7 @@ static int txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb, | |||
| 936 | if (txq->tx_curr_desc == txq->tx_ring_size) | 942 | if (txq->tx_curr_desc == txq->tx_ring_size) |
| 937 | txq->tx_curr_desc = 0; | 943 | txq->tx_curr_desc = 0; |
| 938 | desc = &txq->tx_desc_area[tx_index]; | 944 | desc = &txq->tx_desc_area[tx_index]; |
| 945 | txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_SINGLE; | ||
| 939 | 946 | ||
| 940 | if (nr_frags) { | 947 | if (nr_frags) { |
| 941 | txq_submit_frag_skb(txq, skb); | 948 | txq_submit_frag_skb(txq, skb); |
| @@ -1047,9 +1054,12 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) | |||
| 1047 | int tx_index; | 1054 | int tx_index; |
| 1048 | struct tx_desc *desc; | 1055 | struct tx_desc *desc; |
| 1049 | u32 cmd_sts; | 1056 | u32 cmd_sts; |
| 1057 | char desc_dma_map; | ||
| 1050 | 1058 | ||
| 1051 | tx_index = txq->tx_used_desc; | 1059 | tx_index = txq->tx_used_desc; |
| 1052 | desc = &txq->tx_desc_area[tx_index]; | 1060 | desc = &txq->tx_desc_area[tx_index]; |
| 1061 | desc_dma_map = txq->tx_desc_mapping[tx_index]; | ||
| 1062 | |||
| 1053 | cmd_sts = desc->cmd_sts; | 1063 | cmd_sts = desc->cmd_sts; |
| 1054 | 1064 | ||
| 1055 | if (cmd_sts & BUFFER_OWNED_BY_DMA) { | 1065 | if (cmd_sts & BUFFER_OWNED_BY_DMA) { |
| @@ -1065,9 +1075,19 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) | |||
| 1065 | reclaimed++; | 1075 | reclaimed++; |
| 1066 | txq->tx_desc_count--; | 1076 | txq->tx_desc_count--; |
| 1067 | 1077 | ||
| 1068 | if (!IS_TSO_HEADER(txq, desc->buf_ptr)) | 1078 | if (!IS_TSO_HEADER(txq, desc->buf_ptr)) { |
| 1069 | dma_unmap_single(mp->dev->dev.parent, desc->buf_ptr, | 1079 | |
| 1070 | desc->byte_cnt, DMA_TO_DEVICE); | 1080 | if (desc_dma_map == DESC_DMA_MAP_PAGE) |
| 1081 | dma_unmap_page(mp->dev->dev.parent, | ||
| 1082 | desc->buf_ptr, | ||
| 1083 | desc->byte_cnt, | ||
| 1084 | DMA_TO_DEVICE); | ||
| 1085 | else | ||
| 1086 | dma_unmap_single(mp->dev->dev.parent, | ||
| 1087 | desc->buf_ptr, | ||
| 1088 | desc->byte_cnt, | ||
| 1089 | DMA_TO_DEVICE); | ||
| 1090 | } | ||
| 1071 | 1091 | ||
| 1072 | if (cmd_sts & TX_ENABLE_INTERRUPT) { | 1092 | if (cmd_sts & TX_ENABLE_INTERRUPT) { |
| 1073 | struct sk_buff *skb = __skb_dequeue(&txq->tx_skb); | 1093 | struct sk_buff *skb = __skb_dequeue(&txq->tx_skb); |
| @@ -1996,6 +2016,7 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) | |||
| 1996 | struct tx_queue *txq = mp->txq + index; | 2016 | struct tx_queue *txq = mp->txq + index; |
| 1997 | struct tx_desc *tx_desc; | 2017 | struct tx_desc *tx_desc; |
| 1998 | int size; | 2018 | int size; |
| 2019 | int ret; | ||
| 1999 | int i; | 2020 | int i; |
| 2000 | 2021 | ||
| 2001 | txq->index = index; | 2022 | txq->index = index; |
| @@ -2048,18 +2069,34 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) | |||
| 2048 | nexti * sizeof(struct tx_desc); | 2069 | nexti * sizeof(struct tx_desc); |
| 2049 | } | 2070 | } |
| 2050 | 2071 | ||
| 2072 | txq->tx_desc_mapping = kcalloc(txq->tx_ring_size, sizeof(char), | ||
| 2073 | GFP_KERNEL); | ||
| 2074 | if (!txq->tx_desc_mapping) { | ||
| 2075 | ret = -ENOMEM; | ||
| 2076 | goto err_free_desc_area; | ||
| 2077 | } | ||
| 2078 | |||
| 2051 | /* Allocate DMA buffers for TSO MAC/IP/TCP headers */ | 2079 | /* Allocate DMA buffers for TSO MAC/IP/TCP headers */ |
| 2052 | txq->tso_hdrs = dma_alloc_coherent(mp->dev->dev.parent, | 2080 | txq->tso_hdrs = dma_alloc_coherent(mp->dev->dev.parent, |
| 2053 | txq->tx_ring_size * TSO_HEADER_SIZE, | 2081 | txq->tx_ring_size * TSO_HEADER_SIZE, |
| 2054 | &txq->tso_hdrs_dma, GFP_KERNEL); | 2082 | &txq->tso_hdrs_dma, GFP_KERNEL); |
| 2055 | if (txq->tso_hdrs == NULL) { | 2083 | if (txq->tso_hdrs == NULL) { |
| 2056 | dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, | 2084 | ret = -ENOMEM; |
| 2057 | txq->tx_desc_area, txq->tx_desc_dma); | 2085 | goto err_free_desc_mapping; |
| 2058 | return -ENOMEM; | ||
| 2059 | } | 2086 | } |
| 2060 | skb_queue_head_init(&txq->tx_skb); | 2087 | skb_queue_head_init(&txq->tx_skb); |
| 2061 | 2088 | ||
| 2062 | return 0; | 2089 | return 0; |
| 2090 | |||
| 2091 | err_free_desc_mapping: | ||
| 2092 | kfree(txq->tx_desc_mapping); | ||
| 2093 | err_free_desc_area: | ||
| 2094 | if (index == 0 && size <= mp->tx_desc_sram_size) | ||
| 2095 | iounmap(txq->tx_desc_area); | ||
| 2096 | else | ||
| 2097 | dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, | ||
| 2098 | txq->tx_desc_area, txq->tx_desc_dma); | ||
| 2099 | return ret; | ||
| 2063 | } | 2100 | } |
| 2064 | 2101 | ||
| 2065 | static void txq_deinit(struct tx_queue *txq) | 2102 | static void txq_deinit(struct tx_queue *txq) |
| @@ -2077,6 +2114,8 @@ static void txq_deinit(struct tx_queue *txq) | |||
| 2077 | else | 2114 | else |
| 2078 | dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, | 2115 | dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, |
| 2079 | txq->tx_desc_area, txq->tx_desc_dma); | 2116 | txq->tx_desc_area, txq->tx_desc_dma); |
| 2117 | kfree(txq->tx_desc_mapping); | ||
| 2118 | |||
| 2080 | if (txq->tso_hdrs) | 2119 | if (txq->tso_hdrs) |
| 2081 | dma_free_coherent(mp->dev->dev.parent, | 2120 | dma_free_coherent(mp->dev->dev.parent, |
| 2082 | txq->tx_ring_size * TSO_HEADER_SIZE, | 2121 | txq->tx_ring_size * TSO_HEADER_SIZE, |
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 613037584d08..c531c8ae1be4 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | |||
| @@ -2388,7 +2388,10 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
| 2388 | 2388 | ||
| 2389 | work_done = netxen_process_rcv_ring(sds_ring, budget); | 2389 | work_done = netxen_process_rcv_ring(sds_ring, budget); |
| 2390 | 2390 | ||
| 2391 | if ((work_done < budget) && tx_complete) { | 2391 | if (!tx_complete) |
| 2392 | work_done = budget; | ||
| 2393 | |||
| 2394 | if (work_done < budget) { | ||
| 2392 | napi_complete(&sds_ring->napi); | 2395 | napi_complete(&sds_ring->napi); |
| 2393 | if (test_bit(__NX_DEV_UP, &adapter->state)) | 2396 | if (test_bit(__NX_DEV_UP, &adapter->state)) |
| 2394 | netxen_nic_enable_int(sds_ring); | 2397 | netxen_nic_enable_int(sds_ring); |
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 6576243222af..04283fe0e6a7 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
| @@ -396,6 +396,9 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { | |||
| 396 | [TSU_ADRL31] = 0x01fc, | 396 | [TSU_ADRL31] = 0x01fc, |
| 397 | }; | 397 | }; |
| 398 | 398 | ||
| 399 | static void sh_eth_rcv_snd_disable(struct net_device *ndev); | ||
| 400 | static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev); | ||
| 401 | |||
| 399 | static bool sh_eth_is_gether(struct sh_eth_private *mdp) | 402 | static bool sh_eth_is_gether(struct sh_eth_private *mdp) |
| 400 | { | 403 | { |
| 401 | return mdp->reg_offset == sh_eth_offset_gigabit; | 404 | return mdp->reg_offset == sh_eth_offset_gigabit; |
| @@ -1120,6 +1123,7 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
| 1120 | int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring; | 1123 | int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring; |
| 1121 | int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring; | 1124 | int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring; |
| 1122 | int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; | 1125 | int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; |
| 1126 | dma_addr_t dma_addr; | ||
| 1123 | 1127 | ||
| 1124 | mdp->cur_rx = 0; | 1128 | mdp->cur_rx = 0; |
| 1125 | mdp->cur_tx = 0; | 1129 | mdp->cur_tx = 0; |
| @@ -1133,7 +1137,6 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
| 1133 | /* skb */ | 1137 | /* skb */ |
| 1134 | mdp->rx_skbuff[i] = NULL; | 1138 | mdp->rx_skbuff[i] = NULL; |
| 1135 | skb = netdev_alloc_skb(ndev, skbuff_size); | 1139 | skb = netdev_alloc_skb(ndev, skbuff_size); |
| 1136 | mdp->rx_skbuff[i] = skb; | ||
| 1137 | if (skb == NULL) | 1140 | if (skb == NULL) |
| 1138 | break; | 1141 | break; |
| 1139 | sh_eth_set_receive_align(skb); | 1142 | sh_eth_set_receive_align(skb); |
| @@ -1142,9 +1145,15 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
| 1142 | rxdesc = &mdp->rx_ring[i]; | 1145 | rxdesc = &mdp->rx_ring[i]; |
| 1143 | /* The size of the buffer is a multiple of 16 bytes. */ | 1146 | /* The size of the buffer is a multiple of 16 bytes. */ |
| 1144 | rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); | 1147 | rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); |
| 1145 | dma_map_single(&ndev->dev, skb->data, rxdesc->buffer_length, | 1148 | dma_addr = dma_map_single(&ndev->dev, skb->data, |
| 1146 | DMA_FROM_DEVICE); | 1149 | rxdesc->buffer_length, |
| 1147 | rxdesc->addr = virt_to_phys(skb->data); | 1150 | DMA_FROM_DEVICE); |
| 1151 | if (dma_mapping_error(&ndev->dev, dma_addr)) { | ||
| 1152 | kfree_skb(skb); | ||
| 1153 | break; | ||
| 1154 | } | ||
| 1155 | mdp->rx_skbuff[i] = skb; | ||
| 1156 | rxdesc->addr = dma_addr; | ||
| 1148 | rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP); | 1157 | rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP); |
| 1149 | 1158 | ||
| 1150 | /* Rx descriptor address set */ | 1159 | /* Rx descriptor address set */ |
| @@ -1316,8 +1325,10 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start) | |||
| 1316 | RFLR); | 1325 | RFLR); |
| 1317 | 1326 | ||
| 1318 | sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR); | 1327 | sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR); |
| 1319 | if (start) | 1328 | if (start) { |
| 1329 | mdp->irq_enabled = true; | ||
| 1320 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); | 1330 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); |
| 1331 | } | ||
| 1321 | 1332 | ||
| 1322 | /* PAUSE Prohibition */ | 1333 | /* PAUSE Prohibition */ |
| 1323 | val = (sh_eth_read(ndev, ECMR) & ECMR_DM) | | 1334 | val = (sh_eth_read(ndev, ECMR) & ECMR_DM) | |
| @@ -1356,6 +1367,33 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start) | |||
| 1356 | return ret; | 1367 | return ret; |
| 1357 | } | 1368 | } |
| 1358 | 1369 | ||
| 1370 | static void sh_eth_dev_exit(struct net_device *ndev) | ||
| 1371 | { | ||
| 1372 | struct sh_eth_private *mdp = netdev_priv(ndev); | ||
| 1373 | int i; | ||
| 1374 | |||
| 1375 | /* Deactivate all TX descriptors, so DMA should stop at next | ||
| 1376 | * packet boundary if it's currently running | ||
| 1377 | */ | ||
| 1378 | for (i = 0; i < mdp->num_tx_ring; i++) | ||
| 1379 | mdp->tx_ring[i].status &= ~cpu_to_edmac(mdp, TD_TACT); | ||
| 1380 | |||
| 1381 | /* Disable TX FIFO egress to MAC */ | ||
| 1382 | sh_eth_rcv_snd_disable(ndev); | ||
| 1383 | |||
| 1384 | /* Stop RX DMA at next packet boundary */ | ||
| 1385 | sh_eth_write(ndev, 0, EDRRR); | ||
| 1386 | |||
| 1387 | /* Aside from TX DMA, we can't tell when the hardware is | ||
| 1388 | * really stopped, so we need to reset to make sure. | ||
| 1389 | * Before doing that, wait for long enough to *probably* | ||
| 1390 | * finish transmitting the last packet and poll stats. | ||
| 1391 | */ | ||
| 1392 | msleep(2); /* max frame time at 10 Mbps < 1250 us */ | ||
| 1393 | sh_eth_get_stats(ndev); | ||
| 1394 | sh_eth_reset(ndev); | ||
| 1395 | } | ||
| 1396 | |||
| 1359 | /* free Tx skb function */ | 1397 | /* free Tx skb function */ |
| 1360 | static int sh_eth_txfree(struct net_device *ndev) | 1398 | static int sh_eth_txfree(struct net_device *ndev) |
| 1361 | { | 1399 | { |
| @@ -1400,6 +1438,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) | |||
| 1400 | u16 pkt_len = 0; | 1438 | u16 pkt_len = 0; |
| 1401 | u32 desc_status; | 1439 | u32 desc_status; |
| 1402 | int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; | 1440 | int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; |
| 1441 | dma_addr_t dma_addr; | ||
| 1403 | 1442 | ||
| 1404 | boguscnt = min(boguscnt, *quota); | 1443 | boguscnt = min(boguscnt, *quota); |
| 1405 | limit = boguscnt; | 1444 | limit = boguscnt; |
| @@ -1447,9 +1486,9 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) | |||
| 1447 | mdp->rx_skbuff[entry] = NULL; | 1486 | mdp->rx_skbuff[entry] = NULL; |
| 1448 | if (mdp->cd->rpadir) | 1487 | if (mdp->cd->rpadir) |
| 1449 | skb_reserve(skb, NET_IP_ALIGN); | 1488 | skb_reserve(skb, NET_IP_ALIGN); |
| 1450 | dma_sync_single_for_cpu(&ndev->dev, rxdesc->addr, | 1489 | dma_unmap_single(&ndev->dev, rxdesc->addr, |
| 1451 | ALIGN(mdp->rx_buf_sz, 16), | 1490 | ALIGN(mdp->rx_buf_sz, 16), |
| 1452 | DMA_FROM_DEVICE); | 1491 | DMA_FROM_DEVICE); |
| 1453 | skb_put(skb, pkt_len); | 1492 | skb_put(skb, pkt_len); |
| 1454 | skb->protocol = eth_type_trans(skb, ndev); | 1493 | skb->protocol = eth_type_trans(skb, ndev); |
| 1455 | netif_receive_skb(skb); | 1494 | netif_receive_skb(skb); |
| @@ -1469,15 +1508,20 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) | |||
| 1469 | 1508 | ||
| 1470 | if (mdp->rx_skbuff[entry] == NULL) { | 1509 | if (mdp->rx_skbuff[entry] == NULL) { |
| 1471 | skb = netdev_alloc_skb(ndev, skbuff_size); | 1510 | skb = netdev_alloc_skb(ndev, skbuff_size); |
| 1472 | mdp->rx_skbuff[entry] = skb; | ||
| 1473 | if (skb == NULL) | 1511 | if (skb == NULL) |
| 1474 | break; /* Better luck next round. */ | 1512 | break; /* Better luck next round. */ |
| 1475 | sh_eth_set_receive_align(skb); | 1513 | sh_eth_set_receive_align(skb); |
| 1476 | dma_map_single(&ndev->dev, skb->data, | 1514 | dma_addr = dma_map_single(&ndev->dev, skb->data, |
| 1477 | rxdesc->buffer_length, DMA_FROM_DEVICE); | 1515 | rxdesc->buffer_length, |
| 1516 | DMA_FROM_DEVICE); | ||
| 1517 | if (dma_mapping_error(&ndev->dev, dma_addr)) { | ||
| 1518 | kfree_skb(skb); | ||
| 1519 | break; | ||
| 1520 | } | ||
| 1521 | mdp->rx_skbuff[entry] = skb; | ||
| 1478 | 1522 | ||
| 1479 | skb_checksum_none_assert(skb); | 1523 | skb_checksum_none_assert(skb); |
| 1480 | rxdesc->addr = virt_to_phys(skb->data); | 1524 | rxdesc->addr = dma_addr; |
| 1481 | } | 1525 | } |
| 1482 | if (entry >= mdp->num_rx_ring - 1) | 1526 | if (entry >= mdp->num_rx_ring - 1) |
| 1483 | rxdesc->status |= | 1527 | rxdesc->status |= |
| @@ -1573,7 +1617,6 @@ ignore_link: | |||
| 1573 | if (intr_status & EESR_RFRMER) { | 1617 | if (intr_status & EESR_RFRMER) { |
| 1574 | /* Receive Frame Overflow int */ | 1618 | /* Receive Frame Overflow int */ |
| 1575 | ndev->stats.rx_frame_errors++; | 1619 | ndev->stats.rx_frame_errors++; |
| 1576 | netif_err(mdp, rx_err, ndev, "Receive Abort\n"); | ||
| 1577 | } | 1620 | } |
| 1578 | } | 1621 | } |
| 1579 | 1622 | ||
| @@ -1592,13 +1635,11 @@ ignore_link: | |||
| 1592 | if (intr_status & EESR_RDE) { | 1635 | if (intr_status & EESR_RDE) { |
| 1593 | /* Receive Descriptor Empty int */ | 1636 | /* Receive Descriptor Empty int */ |
| 1594 | ndev->stats.rx_over_errors++; | 1637 | ndev->stats.rx_over_errors++; |
| 1595 | netif_err(mdp, rx_err, ndev, "Receive Descriptor Empty\n"); | ||
| 1596 | } | 1638 | } |
| 1597 | 1639 | ||
| 1598 | if (intr_status & EESR_RFE) { | 1640 | if (intr_status & EESR_RFE) { |
| 1599 | /* Receive FIFO Overflow int */ | 1641 | /* Receive FIFO Overflow int */ |
| 1600 | ndev->stats.rx_fifo_errors++; | 1642 | ndev->stats.rx_fifo_errors++; |
| 1601 | netif_err(mdp, rx_err, ndev, "Receive FIFO Overflow\n"); | ||
| 1602 | } | 1643 | } |
| 1603 | 1644 | ||
| 1604 | if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) { | 1645 | if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) { |
| @@ -1653,7 +1694,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) | |||
| 1653 | if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check)) | 1694 | if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check)) |
| 1654 | ret = IRQ_HANDLED; | 1695 | ret = IRQ_HANDLED; |
| 1655 | else | 1696 | else |
| 1656 | goto other_irq; | 1697 | goto out; |
| 1698 | |||
| 1699 | if (!likely(mdp->irq_enabled)) { | ||
| 1700 | sh_eth_write(ndev, 0, EESIPR); | ||
| 1701 | goto out; | ||
| 1702 | } | ||
| 1657 | 1703 | ||
| 1658 | if (intr_status & EESR_RX_CHECK) { | 1704 | if (intr_status & EESR_RX_CHECK) { |
| 1659 | if (napi_schedule_prep(&mdp->napi)) { | 1705 | if (napi_schedule_prep(&mdp->napi)) { |
| @@ -1684,7 +1730,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) | |||
| 1684 | sh_eth_error(ndev, intr_status); | 1730 | sh_eth_error(ndev, intr_status); |
| 1685 | } | 1731 | } |
| 1686 | 1732 | ||
| 1687 | other_irq: | 1733 | out: |
| 1688 | spin_unlock(&mdp->lock); | 1734 | spin_unlock(&mdp->lock); |
| 1689 | 1735 | ||
| 1690 | return ret; | 1736 | return ret; |
| @@ -1712,7 +1758,8 @@ static int sh_eth_poll(struct napi_struct *napi, int budget) | |||
| 1712 | napi_complete(napi); | 1758 | napi_complete(napi); |
| 1713 | 1759 | ||
| 1714 | /* Reenable Rx interrupts */ | 1760 | /* Reenable Rx interrupts */ |
| 1715 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); | 1761 | if (mdp->irq_enabled) |
| 1762 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); | ||
| 1716 | out: | 1763 | out: |
| 1717 | return budget - quota; | 1764 | return budget - quota; |
| 1718 | } | 1765 | } |
| @@ -1968,40 +2015,50 @@ static int sh_eth_set_ringparam(struct net_device *ndev, | |||
| 1968 | return -EINVAL; | 2015 | return -EINVAL; |
| 1969 | 2016 | ||
| 1970 | if (netif_running(ndev)) { | 2017 | if (netif_running(ndev)) { |
| 2018 | netif_device_detach(ndev); | ||
| 1971 | netif_tx_disable(ndev); | 2019 | netif_tx_disable(ndev); |
| 1972 | /* Disable interrupts by clearing the interrupt mask. */ | 2020 | |
| 1973 | sh_eth_write(ndev, 0x0000, EESIPR); | 2021 | /* Serialise with the interrupt handler and NAPI, then |
| 1974 | /* Stop the chip's Tx and Rx processes. */ | 2022 | * disable interrupts. We have to clear the |
| 1975 | sh_eth_write(ndev, 0, EDTRR); | 2023 | * irq_enabled flag first to ensure that interrupts |
| 1976 | sh_eth_write(ndev, 0, EDRRR); | 2024 | * won't be re-enabled. |
| 2025 | */ | ||
| 2026 | mdp->irq_enabled = false; | ||
| 1977 | synchronize_irq(ndev->irq); | 2027 | synchronize_irq(ndev->irq); |
| 1978 | } | 2028 | napi_synchronize(&mdp->napi); |
| 2029 | sh_eth_write(ndev, 0x0000, EESIPR); | ||
| 1979 | 2030 | ||
| 1980 | /* Free all the skbuffs in the Rx queue. */ | 2031 | sh_eth_dev_exit(ndev); |
| 1981 | sh_eth_ring_free(ndev); | 2032 | |
| 1982 | /* Free DMA buffer */ | 2033 | /* Free all the skbuffs in the Rx queue. */ |
| 1983 | sh_eth_free_dma_buffer(mdp); | 2034 | sh_eth_ring_free(ndev); |
| 2035 | /* Free DMA buffer */ | ||
| 2036 | sh_eth_free_dma_buffer(mdp); | ||
| 2037 | } | ||
| 1984 | 2038 | ||
| 1985 | /* Set new parameters */ | 2039 | /* Set new parameters */ |
| 1986 | mdp->num_rx_ring = ring->rx_pending; | 2040 | mdp->num_rx_ring = ring->rx_pending; |
| 1987 | mdp->num_tx_ring = ring->tx_pending; | 2041 | mdp->num_tx_ring = ring->tx_pending; |
| 1988 | 2042 | ||
| 1989 | ret = sh_eth_ring_init(ndev); | ||
| 1990 | if (ret < 0) { | ||
| 1991 | netdev_err(ndev, "%s: sh_eth_ring_init failed.\n", __func__); | ||
| 1992 | return ret; | ||
| 1993 | } | ||
| 1994 | ret = sh_eth_dev_init(ndev, false); | ||
| 1995 | if (ret < 0) { | ||
| 1996 | netdev_err(ndev, "%s: sh_eth_dev_init failed.\n", __func__); | ||
| 1997 | return ret; | ||
| 1998 | } | ||
| 1999 | |||
| 2000 | if (netif_running(ndev)) { | 2043 | if (netif_running(ndev)) { |
| 2044 | ret = sh_eth_ring_init(ndev); | ||
| 2045 | if (ret < 0) { | ||
| 2046 | netdev_err(ndev, "%s: sh_eth_ring_init failed.\n", | ||
| 2047 | __func__); | ||
| 2048 | return ret; | ||
| 2049 | } | ||
| 2050 | ret = sh_eth_dev_init(ndev, false); | ||
| 2051 | if (ret < 0) { | ||
| 2052 | netdev_err(ndev, "%s: sh_eth_dev_init failed.\n", | ||
| 2053 | __func__); | ||
| 2054 | return ret; | ||
| 2055 | } | ||
| 2056 | |||
| 2057 | mdp->irq_enabled = true; | ||
| 2001 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); | 2058 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); |
| 2002 | /* Setting the Rx mode will start the Rx process. */ | 2059 | /* Setting the Rx mode will start the Rx process. */ |
| 2003 | sh_eth_write(ndev, EDRRR_R, EDRRR); | 2060 | sh_eth_write(ndev, EDRRR_R, EDRRR); |
| 2004 | netif_wake_queue(ndev); | 2061 | netif_device_attach(ndev); |
| 2005 | } | 2062 | } |
| 2006 | 2063 | ||
| 2007 | return 0; | 2064 | return 0; |
| @@ -2117,6 +2174,9 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
| 2117 | } | 2174 | } |
| 2118 | spin_unlock_irqrestore(&mdp->lock, flags); | 2175 | spin_unlock_irqrestore(&mdp->lock, flags); |
| 2119 | 2176 | ||
| 2177 | if (skb_padto(skb, ETH_ZLEN)) | ||
| 2178 | return NETDEV_TX_OK; | ||
| 2179 | |||
| 2120 | entry = mdp->cur_tx % mdp->num_tx_ring; | 2180 | entry = mdp->cur_tx % mdp->num_tx_ring; |
| 2121 | mdp->tx_skbuff[entry] = skb; | 2181 | mdp->tx_skbuff[entry] = skb; |
| 2122 | txdesc = &mdp->tx_ring[entry]; | 2182 | txdesc = &mdp->tx_ring[entry]; |
| @@ -2126,10 +2186,11 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
| 2126 | skb->len + 2); | 2186 | skb->len + 2); |
| 2127 | txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len, | 2187 | txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len, |
| 2128 | DMA_TO_DEVICE); | 2188 | DMA_TO_DEVICE); |
| 2129 | if (skb->len < ETH_ZLEN) | 2189 | if (dma_mapping_error(&ndev->dev, txdesc->addr)) { |
| 2130 | txdesc->buffer_length = ETH_ZLEN; | 2190 | kfree_skb(skb); |
| 2131 | else | 2191 | return NETDEV_TX_OK; |
| 2132 | txdesc->buffer_length = skb->len; | 2192 | } |
| 2193 | txdesc->buffer_length = skb->len; | ||
| 2133 | 2194 | ||
| 2134 | if (entry >= mdp->num_tx_ring - 1) | 2195 | if (entry >= mdp->num_tx_ring - 1) |
| 2135 | txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE); | 2196 | txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE); |
| @@ -2181,14 +2242,17 @@ static int sh_eth_close(struct net_device *ndev) | |||
| 2181 | 2242 | ||
| 2182 | netif_stop_queue(ndev); | 2243 | netif_stop_queue(ndev); |
| 2183 | 2244 | ||
| 2184 | /* Disable interrupts by clearing the interrupt mask. */ | 2245 | /* Serialise with the interrupt handler and NAPI, then disable |
| 2246 | * interrupts. We have to clear the irq_enabled flag first to | ||
| 2247 | * ensure that interrupts won't be re-enabled. | ||
| 2248 | */ | ||
| 2249 | mdp->irq_enabled = false; | ||
| 2250 | synchronize_irq(ndev->irq); | ||
| 2251 | napi_disable(&mdp->napi); | ||
| 2185 | sh_eth_write(ndev, 0x0000, EESIPR); | 2252 | sh_eth_write(ndev, 0x0000, EESIPR); |
| 2186 | 2253 | ||
| 2187 | /* Stop the chip's Tx and Rx processes. */ | 2254 | sh_eth_dev_exit(ndev); |
| 2188 | sh_eth_write(ndev, 0, EDTRR); | ||
| 2189 | sh_eth_write(ndev, 0, EDRRR); | ||
| 2190 | 2255 | ||
| 2191 | sh_eth_get_stats(ndev); | ||
| 2192 | /* PHY Disconnect */ | 2256 | /* PHY Disconnect */ |
| 2193 | if (mdp->phydev) { | 2257 | if (mdp->phydev) { |
| 2194 | phy_stop(mdp->phydev); | 2258 | phy_stop(mdp->phydev); |
| @@ -2198,8 +2262,6 @@ static int sh_eth_close(struct net_device *ndev) | |||
| 2198 | 2262 | ||
| 2199 | free_irq(ndev->irq, ndev); | 2263 | free_irq(ndev->irq, ndev); |
| 2200 | 2264 | ||
| 2201 | napi_disable(&mdp->napi); | ||
| 2202 | |||
| 2203 | /* Free all the skbuffs in the Rx queue. */ | 2265 | /* Free all the skbuffs in the Rx queue. */ |
| 2204 | sh_eth_ring_free(ndev); | 2266 | sh_eth_ring_free(ndev); |
| 2205 | 2267 | ||
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 71f5de1171bd..332d3c16d483 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h | |||
| @@ -513,6 +513,7 @@ struct sh_eth_private { | |||
| 513 | u32 rx_buf_sz; /* Based on MTU+slack. */ | 513 | u32 rx_buf_sz; /* Based on MTU+slack. */ |
| 514 | int edmac_endian; | 514 | int edmac_endian; |
| 515 | struct napi_struct napi; | 515 | struct napi_struct napi; |
| 516 | bool irq_enabled; | ||
| 516 | /* MII transceiver section. */ | 517 | /* MII transceiver section. */ |
| 517 | u32 phy_id; /* PHY ID */ | 518 | u32 phy_id; /* PHY ID */ |
| 518 | struct mii_bus *mii_bus; /* MDIO bus control */ | 519 | struct mii_bus *mii_bus; /* MDIO bus control */ |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 8c6b7c1651e5..cf62ff4c8c56 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
| @@ -2778,6 +2778,9 @@ static int stmmac_hw_init(struct stmmac_priv *priv) | |||
| 2778 | * @addr: iobase memory address | 2778 | * @addr: iobase memory address |
| 2779 | * Description: this is the main probe function used to | 2779 | * Description: this is the main probe function used to |
| 2780 | * call the alloc_etherdev, allocate the priv structure. | 2780 | * call the alloc_etherdev, allocate the priv structure. |
| 2781 | * Return: | ||
| 2782 | * on success the new private structure is returned, otherwise the error | ||
| 2783 | * pointer. | ||
| 2781 | */ | 2784 | */ |
| 2782 | struct stmmac_priv *stmmac_dvr_probe(struct device *device, | 2785 | struct stmmac_priv *stmmac_dvr_probe(struct device *device, |
| 2783 | struct plat_stmmacenet_data *plat_dat, | 2786 | struct plat_stmmacenet_data *plat_dat, |
| @@ -2789,7 +2792,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, | |||
| 2789 | 2792 | ||
| 2790 | ndev = alloc_etherdev(sizeof(struct stmmac_priv)); | 2793 | ndev = alloc_etherdev(sizeof(struct stmmac_priv)); |
| 2791 | if (!ndev) | 2794 | if (!ndev) |
| 2792 | return NULL; | 2795 | return ERR_PTR(-ENOMEM); |
| 2793 | 2796 | ||
| 2794 | SET_NETDEV_DEV(ndev, device); | 2797 | SET_NETDEV_DEV(ndev, device); |
| 2795 | 2798 | ||
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index e068d48b0f21..a39131f494ec 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
| @@ -1683,6 +1683,19 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, | |||
| 1683 | if (vid == priv->data.default_vlan) | 1683 | if (vid == priv->data.default_vlan) |
| 1684 | return 0; | 1684 | return 0; |
| 1685 | 1685 | ||
| 1686 | if (priv->data.dual_emac) { | ||
| 1687 | /* In dual EMAC, reserved VLAN id should not be used for | ||
| 1688 | * creating VLAN interfaces as this can break the dual | ||
| 1689 | * EMAC port separation | ||
| 1690 | */ | ||
| 1691 | int i; | ||
| 1692 | |||
| 1693 | for (i = 0; i < priv->data.slaves; i++) { | ||
| 1694 | if (vid == priv->slaves[i].port_vlan) | ||
| 1695 | return -EINVAL; | ||
| 1696 | } | ||
| 1697 | } | ||
| 1698 | |||
| 1686 | dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid); | 1699 | dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid); |
| 1687 | return cpsw_add_vlan_ale_entry(priv, vid); | 1700 | return cpsw_add_vlan_ale_entry(priv, vid); |
| 1688 | } | 1701 | } |
| @@ -1696,6 +1709,15 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, | |||
| 1696 | if (vid == priv->data.default_vlan) | 1709 | if (vid == priv->data.default_vlan) |
| 1697 | return 0; | 1710 | return 0; |
| 1698 | 1711 | ||
| 1712 | if (priv->data.dual_emac) { | ||
| 1713 | int i; | ||
| 1714 | |||
| 1715 | for (i = 0; i < priv->data.slaves; i++) { | ||
| 1716 | if (vid == priv->slaves[i].port_vlan) | ||
| 1717 | return -EINVAL; | ||
| 1718 | } | ||
| 1719 | } | ||
| 1720 | |||
| 1699 | dev_info(priv->dev, "removing vlanid %d from vlan filter\n", vid); | 1721 | dev_info(priv->dev, "removing vlanid %d from vlan filter\n", vid); |
| 1700 | ret = cpsw_ale_del_vlan(priv->ale, vid, 0); | 1722 | ret = cpsw_ale_del_vlan(priv->ale, vid, 0); |
| 1701 | if (ret != 0) | 1723 | if (ret != 0) |
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index a14d87783245..2e195289ddf4 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c | |||
| @@ -377,9 +377,11 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) | |||
| 377 | }; | 377 | }; |
| 378 | 378 | ||
| 379 | dst = ip6_route_output(dev_net(dev), NULL, &fl6); | 379 | dst = ip6_route_output(dev_net(dev), NULL, &fl6); |
| 380 | if (IS_ERR(dst)) | 380 | if (dst->error) { |
| 381 | ret = dst->error; | ||
| 382 | dst_release(dst); | ||
| 381 | goto err; | 383 | goto err; |
| 382 | 384 | } | |
| 383 | skb_dst_drop(skb); | 385 | skb_dst_drop(skb); |
| 384 | skb_dst_set(skb, dst); | 386 | skb_dst_set(skb, dst); |
| 385 | err = ip6_local_out(skb); | 387 | err = ip6_local_out(skb); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9a72640237cb..62b0bf4fdf6b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -285,6 +285,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) | |||
| 285 | 285 | ||
| 286 | __ath_cancel_work(sc); | 286 | __ath_cancel_work(sc); |
| 287 | 287 | ||
| 288 | disable_irq(sc->irq); | ||
| 288 | tasklet_disable(&sc->intr_tq); | 289 | tasklet_disable(&sc->intr_tq); |
| 289 | tasklet_disable(&sc->bcon_tasklet); | 290 | tasklet_disable(&sc->bcon_tasklet); |
| 290 | spin_lock_bh(&sc->sc_pcu_lock); | 291 | spin_lock_bh(&sc->sc_pcu_lock); |
| @@ -331,6 +332,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) | |||
| 331 | r = -EIO; | 332 | r = -EIO; |
| 332 | 333 | ||
| 333 | out: | 334 | out: |
| 335 | enable_irq(sc->irq); | ||
| 334 | spin_unlock_bh(&sc->sc_pcu_lock); | 336 | spin_unlock_bh(&sc->sc_pcu_lock); |
| 335 | tasklet_enable(&sc->bcon_tasklet); | 337 | tasklet_enable(&sc->bcon_tasklet); |
| 336 | tasklet_enable(&sc->intr_tq); | 338 | tasklet_enable(&sc->intr_tq); |
| @@ -512,9 +514,6 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
| 512 | if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags)) | 514 | if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags)) |
| 513 | return IRQ_NONE; | 515 | return IRQ_NONE; |
| 514 | 516 | ||
| 515 | if (!AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags)) | ||
| 516 | return IRQ_NONE; | ||
| 517 | |||
| 518 | /* shared irq, not for us */ | 517 | /* shared irq, not for us */ |
| 519 | if (!ath9k_hw_intrpend(ah)) | 518 | if (!ath9k_hw_intrpend(ah)) |
| 520 | return IRQ_NONE; | 519 | return IRQ_NONE; |
| @@ -529,7 +528,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
| 529 | ath9k_debug_sync_cause(sc, sync_cause); | 528 | ath9k_debug_sync_cause(sc, sync_cause); |
| 530 | status &= ah->imask; /* discard unasked-for bits */ | 529 | status &= ah->imask; /* discard unasked-for bits */ |
| 531 | 530 | ||
| 532 | if (AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags)) | 531 | if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) |
| 533 | return IRQ_HANDLED; | 532 | return IRQ_HANDLED; |
| 534 | 533 | ||
| 535 | /* | 534 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 1bbe4fc47b97..660ddb1b7d8a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
| @@ -246,6 +246,7 @@ enum iwl_ucode_tlv_flag { | |||
| 246 | * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, | 246 | * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, |
| 247 | * regardless of the band or the number of the probes. FW will calculate | 247 | * regardless of the band or the number of the probes. FW will calculate |
| 248 | * the actual dwell time. | 248 | * the actual dwell time. |
| 249 | * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too. | ||
| 249 | */ | 250 | */ |
| 250 | enum iwl_ucode_tlv_api { | 251 | enum iwl_ucode_tlv_api { |
| 251 | IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), | 252 | IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), |
| @@ -257,6 +258,7 @@ enum iwl_ucode_tlv_api { | |||
| 257 | IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), | 258 | IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), |
| 258 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), | 259 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), |
| 259 | IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13), | 260 | IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13), |
| 261 | IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16), | ||
| 260 | }; | 262 | }; |
| 261 | 263 | ||
| 262 | /** | 264 | /** |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 201846de94e7..cfc0e65b34a5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
| @@ -653,8 +653,11 @@ enum iwl_scan_channel_flags { | |||
| 653 | }; | 653 | }; |
| 654 | 654 | ||
| 655 | /* iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S | 655 | /* iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S |
| 656 | * @flags: enum iwl_scan_channel_flgs | 656 | * @flags: enum iwl_scan_channel_flags |
| 657 | * @non_ebs_ratio: how many regular scan iteration before EBS | 657 | * @non_ebs_ratio: defines the ratio of number of scan iterations where EBS is |
| 658 | * involved. | ||
| 659 | * 1 - EBS is disabled. | ||
| 660 | * 2 - every second scan will be full scan(and so on). | ||
| 658 | */ | 661 | */ |
| 659 | struct iwl_scan_channel_opt { | 662 | struct iwl_scan_channel_opt { |
| 660 | __le16 flags; | 663 | __le16 flags; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index e880f9d4717b..20915587c820 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -3343,18 +3343,16 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, | |||
| 3343 | msk |= mvmsta->tfd_queue_msk; | 3343 | msk |= mvmsta->tfd_queue_msk; |
| 3344 | } | 3344 | } |
| 3345 | 3345 | ||
| 3346 | if (drop) { | 3346 | msk &= ~BIT(vif->hw_queue[IEEE80211_AC_VO]); |
| 3347 | if (iwl_mvm_flush_tx_path(mvm, msk, true)) | ||
| 3348 | IWL_ERR(mvm, "flush request fail\n"); | ||
| 3349 | mutex_unlock(&mvm->mutex); | ||
| 3350 | } else { | ||
| 3351 | mutex_unlock(&mvm->mutex); | ||
| 3352 | 3347 | ||
| 3353 | /* this can take a while, and we may need/want other operations | 3348 | if (iwl_mvm_flush_tx_path(mvm, msk, true)) |
| 3354 | * to succeed while doing this, so do it without the mutex held | 3349 | IWL_ERR(mvm, "flush request fail\n"); |
| 3355 | */ | 3350 | mutex_unlock(&mvm->mutex); |
| 3356 | iwl_trans_wait_tx_queue_empty(mvm->trans, msk); | 3351 | |
| 3357 | } | 3352 | /* this can take a while, and we may need/want other operations |
| 3353 | * to succeed while doing this, so do it without the mutex held | ||
| 3354 | */ | ||
| 3355 | iwl_trans_wait_tx_queue_empty(mvm->trans, msk); | ||
| 3358 | } | 3356 | } |
| 3359 | 3357 | ||
| 3360 | const struct ieee80211_ops iwl_mvm_hw_ops = { | 3358 | const struct ieee80211_ops iwl_mvm_hw_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index ec9a8e7bae1d..844bf7c4c8de 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
| @@ -72,6 +72,8 @@ | |||
| 72 | 72 | ||
| 73 | #define IWL_PLCP_QUIET_THRESH 1 | 73 | #define IWL_PLCP_QUIET_THRESH 1 |
| 74 | #define IWL_ACTIVE_QUIET_TIME 10 | 74 | #define IWL_ACTIVE_QUIET_TIME 10 |
| 75 | #define IWL_DENSE_EBS_SCAN_RATIO 5 | ||
| 76 | #define IWL_SPARSE_EBS_SCAN_RATIO 1 | ||
| 75 | 77 | ||
| 76 | struct iwl_mvm_scan_params { | 78 | struct iwl_mvm_scan_params { |
| 77 | u32 max_out_time; | 79 | u32 max_out_time; |
| @@ -1105,6 +1107,12 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) | |||
| 1105 | return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN, | 1107 | return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN, |
| 1106 | notify); | 1108 | notify); |
| 1107 | 1109 | ||
| 1110 | if (mvm->scan_status == IWL_MVM_SCAN_NONE) | ||
| 1111 | return 0; | ||
| 1112 | |||
| 1113 | if (iwl_mvm_is_radio_killed(mvm)) | ||
| 1114 | goto out; | ||
| 1115 | |||
| 1108 | if (mvm->scan_status != IWL_MVM_SCAN_SCHED && | 1116 | if (mvm->scan_status != IWL_MVM_SCAN_SCHED && |
| 1109 | (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || | 1117 | (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || |
| 1110 | mvm->scan_status != IWL_MVM_SCAN_OS)) { | 1118 | mvm->scan_status != IWL_MVM_SCAN_OS)) { |
| @@ -1141,6 +1149,7 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) | |||
| 1141 | if (mvm->scan_status == IWL_MVM_SCAN_OS) | 1149 | if (mvm->scan_status == IWL_MVM_SCAN_OS) |
| 1142 | iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); | 1150 | iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); |
| 1143 | 1151 | ||
| 1152 | out: | ||
| 1144 | mvm->scan_status = IWL_MVM_SCAN_NONE; | 1153 | mvm->scan_status = IWL_MVM_SCAN_NONE; |
| 1145 | 1154 | ||
| 1146 | if (notify) { | 1155 | if (notify) { |
| @@ -1297,18 +1306,6 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm, | |||
| 1297 | cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); | 1306 | cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); |
| 1298 | cmd->iter_num = cpu_to_le32(1); | 1307 | cmd->iter_num = cpu_to_le32(1); |
| 1299 | 1308 | ||
| 1300 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && | ||
| 1301 | mvm->last_ebs_successful) { | ||
| 1302 | cmd->channel_opt[0].flags = | ||
| 1303 | cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | ||
| 1304 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | ||
| 1305 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | ||
| 1306 | cmd->channel_opt[1].flags = | ||
| 1307 | cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | ||
| 1308 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | ||
| 1309 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | ||
| 1310 | } | ||
| 1311 | |||
| 1312 | if (iwl_mvm_rrm_scan_needed(mvm)) | 1309 | if (iwl_mvm_rrm_scan_needed(mvm)) |
| 1313 | cmd->scan_flags |= | 1310 | cmd->scan_flags |= |
| 1314 | cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); | 1311 | cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); |
| @@ -1383,6 +1380,22 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, | |||
| 1383 | cmd->schedule[1].iterations = 0; | 1380 | cmd->schedule[1].iterations = 0; |
| 1384 | cmd->schedule[1].full_scan_mul = 0; | 1381 | cmd->schedule[1].full_scan_mul = 0; |
| 1385 | 1382 | ||
| 1383 | if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS && | ||
| 1384 | mvm->last_ebs_successful) { | ||
| 1385 | cmd->channel_opt[0].flags = | ||
| 1386 | cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | ||
| 1387 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | ||
| 1388 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | ||
| 1389 | cmd->channel_opt[0].non_ebs_ratio = | ||
| 1390 | cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); | ||
| 1391 | cmd->channel_opt[1].flags = | ||
| 1392 | cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | ||
| 1393 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | ||
| 1394 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | ||
| 1395 | cmd->channel_opt[1].non_ebs_ratio = | ||
| 1396 | cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); | ||
| 1397 | } | ||
| 1398 | |||
| 1386 | for (i = 1; i <= req->req.n_ssids; i++) | 1399 | for (i = 1; i <= req->req.n_ssids; i++) |
| 1387 | ssid_bitmap |= BIT(i); | 1400 | ssid_bitmap |= BIT(i); |
| 1388 | 1401 | ||
| @@ -1483,6 +1496,22 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, | |||
| 1483 | cmd->schedule[1].iterations = 0xff; | 1496 | cmd->schedule[1].iterations = 0xff; |
| 1484 | cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER; | 1497 | cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER; |
| 1485 | 1498 | ||
| 1499 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && | ||
| 1500 | mvm->last_ebs_successful) { | ||
| 1501 | cmd->channel_opt[0].flags = | ||
| 1502 | cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | ||
| 1503 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | ||
| 1504 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | ||
| 1505 | cmd->channel_opt[0].non_ebs_ratio = | ||
| 1506 | cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); | ||
| 1507 | cmd->channel_opt[1].flags = | ||
| 1508 | cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | ||
| 1509 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | ||
| 1510 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | ||
| 1511 | cmd->channel_opt[1].non_ebs_ratio = | ||
| 1512 | cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); | ||
| 1513 | } | ||
| 1514 | |||
| 1486 | iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels, | 1515 | iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels, |
| 1487 | ssid_bitmap, cmd); | 1516 | ssid_bitmap, cmd); |
| 1488 | 1517 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 4333306ccdee..c59d07567d90 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
| @@ -90,8 +90,6 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
| 90 | 90 | ||
| 91 | if (ieee80211_is_probe_resp(fc)) | 91 | if (ieee80211_is_probe_resp(fc)) |
| 92 | tx_flags |= TX_CMD_FLG_TSF; | 92 | tx_flags |= TX_CMD_FLG_TSF; |
| 93 | else if (ieee80211_is_back_req(fc)) | ||
| 94 | tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; | ||
| 95 | 93 | ||
| 96 | if (ieee80211_has_morefrags(fc)) | 94 | if (ieee80211_has_morefrags(fc)) |
| 97 | tx_flags |= TX_CMD_FLG_MORE_FRAG; | 95 | tx_flags |= TX_CMD_FLG_MORE_FRAG; |
| @@ -100,6 +98,15 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
| 100 | u8 *qc = ieee80211_get_qos_ctl(hdr); | 98 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
| 101 | tx_cmd->tid_tspec = qc[0] & 0xf; | 99 | tx_cmd->tid_tspec = qc[0] & 0xf; |
| 102 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL; | 100 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL; |
| 101 | } else if (ieee80211_is_back_req(fc)) { | ||
| 102 | struct ieee80211_bar *bar = (void *)skb->data; | ||
| 103 | u16 control = le16_to_cpu(bar->control); | ||
| 104 | |||
| 105 | tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; | ||
| 106 | tx_cmd->tid_tspec = (control & | ||
| 107 | IEEE80211_BAR_CTRL_TID_INFO_MASK) >> | ||
| 108 | IEEE80211_BAR_CTRL_TID_INFO_SHIFT; | ||
| 109 | WARN_ON_ONCE(tx_cmd->tid_tspec >= IWL_MAX_TID_COUNT); | ||
| 103 | } else { | 110 | } else { |
| 104 | tx_cmd->tid_tspec = IWL_TID_NON_QOS; | 111 | tx_cmd->tid_tspec = IWL_TID_NON_QOS; |
| 105 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) | 112 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index f407e3763432..642c77c76b84 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
| @@ -1784,6 +1784,8 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel, | |||
| 1784 | QETH_DBF_TEXT(SETUP, 2, "idxanswr"); | 1784 | QETH_DBF_TEXT(SETUP, 2, "idxanswr"); |
| 1785 | card = CARD_FROM_CDEV(channel->ccwdev); | 1785 | card = CARD_FROM_CDEV(channel->ccwdev); |
| 1786 | iob = qeth_get_buffer(channel); | 1786 | iob = qeth_get_buffer(channel); |
| 1787 | if (!iob) | ||
| 1788 | return -ENOMEM; | ||
| 1787 | iob->callback = idx_reply_cb; | 1789 | iob->callback = idx_reply_cb; |
| 1788 | memcpy(&channel->ccw, READ_CCW, sizeof(struct ccw1)); | 1790 | memcpy(&channel->ccw, READ_CCW, sizeof(struct ccw1)); |
| 1789 | channel->ccw.count = QETH_BUFSIZE; | 1791 | channel->ccw.count = QETH_BUFSIZE; |
| @@ -1834,6 +1836,8 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, | |||
| 1834 | QETH_DBF_TEXT(SETUP, 2, "idxactch"); | 1836 | QETH_DBF_TEXT(SETUP, 2, "idxactch"); |
| 1835 | 1837 | ||
| 1836 | iob = qeth_get_buffer(channel); | 1838 | iob = qeth_get_buffer(channel); |
| 1839 | if (!iob) | ||
| 1840 | return -ENOMEM; | ||
| 1837 | iob->callback = idx_reply_cb; | 1841 | iob->callback = idx_reply_cb; |
| 1838 | memcpy(&channel->ccw, WRITE_CCW, sizeof(struct ccw1)); | 1842 | memcpy(&channel->ccw, WRITE_CCW, sizeof(struct ccw1)); |
| 1839 | channel->ccw.count = IDX_ACTIVATE_SIZE; | 1843 | channel->ccw.count = IDX_ACTIVATE_SIZE; |
| @@ -2021,10 +2025,36 @@ void qeth_prepare_control_data(struct qeth_card *card, int len, | |||
| 2021 | } | 2025 | } |
| 2022 | EXPORT_SYMBOL_GPL(qeth_prepare_control_data); | 2026 | EXPORT_SYMBOL_GPL(qeth_prepare_control_data); |
| 2023 | 2027 | ||
| 2028 | /** | ||
| 2029 | * qeth_send_control_data() - send control command to the card | ||
| 2030 | * @card: qeth_card structure pointer | ||
| 2031 | * @len: size of the command buffer | ||
| 2032 | * @iob: qeth_cmd_buffer pointer | ||
| 2033 | * @reply_cb: callback function pointer | ||
| 2034 | * @cb_card: pointer to the qeth_card structure | ||
| 2035 | * @cb_reply: pointer to the qeth_reply structure | ||
| 2036 | * @cb_cmd: pointer to the original iob for non-IPA | ||
| 2037 | * commands, or to the qeth_ipa_cmd structure | ||
| 2038 | * for the IPA commands. | ||
| 2039 | * @reply_param: private pointer passed to the callback | ||
| 2040 | * | ||
| 2041 | * Returns the value of the `return_code' field of the response | ||
| 2042 | * block returned from the hardware, or other error indication. | ||
| 2043 | * Value of zero indicates successful execution of the command. | ||
| 2044 | * | ||
| 2045 | * Callback function gets called one or more times, with cb_cmd | ||
| 2046 | * pointing to the response returned by the hardware. Callback | ||
| 2047 | * function must return non-zero if more reply blocks are expected, | ||
| 2048 | * and zero if the last or only reply block is received. Callback | ||
| 2049 | * function can get the value of the reply_param pointer from the | ||
| 2050 | * field 'param' of the structure qeth_reply. | ||
| 2051 | */ | ||
| 2052 | |||
| 2024 | int qeth_send_control_data(struct qeth_card *card, int len, | 2053 | int qeth_send_control_data(struct qeth_card *card, int len, |
| 2025 | struct qeth_cmd_buffer *iob, | 2054 | struct qeth_cmd_buffer *iob, |
| 2026 | int (*reply_cb)(struct qeth_card *, struct qeth_reply *, | 2055 | int (*reply_cb)(struct qeth_card *cb_card, |
| 2027 | unsigned long), | 2056 | struct qeth_reply *cb_reply, |
| 2057 | unsigned long cb_cmd), | ||
| 2028 | void *reply_param) | 2058 | void *reply_param) |
| 2029 | { | 2059 | { |
| 2030 | int rc; | 2060 | int rc; |
| @@ -2914,9 +2944,16 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card, | |||
| 2914 | struct qeth_cmd_buffer *iob; | 2944 | struct qeth_cmd_buffer *iob; |
| 2915 | struct qeth_ipa_cmd *cmd; | 2945 | struct qeth_ipa_cmd *cmd; |
| 2916 | 2946 | ||
| 2917 | iob = qeth_wait_for_buffer(&card->write); | 2947 | iob = qeth_get_buffer(&card->write); |
| 2918 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 2948 | if (iob) { |
| 2919 | qeth_fill_ipacmd_header(card, cmd, ipacmd, prot); | 2949 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 2950 | qeth_fill_ipacmd_header(card, cmd, ipacmd, prot); | ||
| 2951 | } else { | ||
| 2952 | dev_warn(&card->gdev->dev, | ||
| 2953 | "The qeth driver ran out of channel command buffers\n"); | ||
| 2954 | QETH_DBF_MESSAGE(1, "%s The qeth driver ran out of channel command buffers", | ||
| 2955 | dev_name(&card->gdev->dev)); | ||
| 2956 | } | ||
| 2920 | 2957 | ||
| 2921 | return iob; | 2958 | return iob; |
| 2922 | } | 2959 | } |
| @@ -2932,6 +2969,12 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, | |||
| 2932 | } | 2969 | } |
| 2933 | EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd); | 2970 | EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd); |
| 2934 | 2971 | ||
| 2972 | /** | ||
| 2973 | * qeth_send_ipa_cmd() - send an IPA command | ||
| 2974 | * | ||
| 2975 | * See qeth_send_control_data() for explanation of the arguments. | ||
| 2976 | */ | ||
| 2977 | |||
| 2935 | int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, | 2978 | int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, |
| 2936 | int (*reply_cb)(struct qeth_card *, struct qeth_reply*, | 2979 | int (*reply_cb)(struct qeth_card *, struct qeth_reply*, |
| 2937 | unsigned long), | 2980 | unsigned long), |
| @@ -2968,6 +3011,8 @@ int qeth_send_startlan(struct qeth_card *card) | |||
| 2968 | QETH_DBF_TEXT(SETUP, 2, "strtlan"); | 3011 | QETH_DBF_TEXT(SETUP, 2, "strtlan"); |
| 2969 | 3012 | ||
| 2970 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_STARTLAN, 0); | 3013 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_STARTLAN, 0); |
| 3014 | if (!iob) | ||
| 3015 | return -ENOMEM; | ||
| 2971 | rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); | 3016 | rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); |
| 2972 | return rc; | 3017 | return rc; |
| 2973 | } | 3018 | } |
| @@ -3013,11 +3058,13 @@ static struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card, | |||
| 3013 | 3058 | ||
| 3014 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETADAPTERPARMS, | 3059 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETADAPTERPARMS, |
| 3015 | QETH_PROT_IPV4); | 3060 | QETH_PROT_IPV4); |
| 3016 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 3061 | if (iob) { |
| 3017 | cmd->data.setadapterparms.hdr.cmdlength = cmdlen; | 3062 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 3018 | cmd->data.setadapterparms.hdr.command_code = command; | 3063 | cmd->data.setadapterparms.hdr.cmdlength = cmdlen; |
| 3019 | cmd->data.setadapterparms.hdr.used_total = 1; | 3064 | cmd->data.setadapterparms.hdr.command_code = command; |
| 3020 | cmd->data.setadapterparms.hdr.seq_no = 1; | 3065 | cmd->data.setadapterparms.hdr.used_total = 1; |
| 3066 | cmd->data.setadapterparms.hdr.seq_no = 1; | ||
| 3067 | } | ||
| 3021 | 3068 | ||
| 3022 | return iob; | 3069 | return iob; |
| 3023 | } | 3070 | } |
| @@ -3030,6 +3077,8 @@ int qeth_query_setadapterparms(struct qeth_card *card) | |||
| 3030 | QETH_CARD_TEXT(card, 3, "queryadp"); | 3077 | QETH_CARD_TEXT(card, 3, "queryadp"); |
| 3031 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_COMMANDS_SUPPORTED, | 3078 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_COMMANDS_SUPPORTED, |
| 3032 | sizeof(struct qeth_ipacmd_setadpparms)); | 3079 | sizeof(struct qeth_ipacmd_setadpparms)); |
| 3080 | if (!iob) | ||
| 3081 | return -ENOMEM; | ||
| 3033 | rc = qeth_send_ipa_cmd(card, iob, qeth_query_setadapterparms_cb, NULL); | 3082 | rc = qeth_send_ipa_cmd(card, iob, qeth_query_setadapterparms_cb, NULL); |
| 3034 | return rc; | 3083 | return rc; |
| 3035 | } | 3084 | } |
| @@ -3080,6 +3129,8 @@ int qeth_query_ipassists(struct qeth_card *card, enum qeth_prot_versions prot) | |||
| 3080 | 3129 | ||
| 3081 | QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot); | 3130 | QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot); |
| 3082 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot); | 3131 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot); |
| 3132 | if (!iob) | ||
| 3133 | return -ENOMEM; | ||
| 3083 | rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL); | 3134 | rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL); |
| 3084 | return rc; | 3135 | return rc; |
| 3085 | } | 3136 | } |
| @@ -3119,6 +3170,8 @@ int qeth_query_switch_attributes(struct qeth_card *card, | |||
| 3119 | return -ENOMEDIUM; | 3170 | return -ENOMEDIUM; |
| 3120 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES, | 3171 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES, |
| 3121 | sizeof(struct qeth_ipacmd_setadpparms_hdr)); | 3172 | sizeof(struct qeth_ipacmd_setadpparms_hdr)); |
| 3173 | if (!iob) | ||
| 3174 | return -ENOMEM; | ||
| 3122 | return qeth_send_ipa_cmd(card, iob, | 3175 | return qeth_send_ipa_cmd(card, iob, |
| 3123 | qeth_query_switch_attributes_cb, sw_info); | 3176 | qeth_query_switch_attributes_cb, sw_info); |
| 3124 | } | 3177 | } |
| @@ -3146,6 +3199,8 @@ static int qeth_query_setdiagass(struct qeth_card *card) | |||
| 3146 | 3199 | ||
| 3147 | QETH_DBF_TEXT(SETUP, 2, "qdiagass"); | 3200 | QETH_DBF_TEXT(SETUP, 2, "qdiagass"); |
| 3148 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); | 3201 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); |
| 3202 | if (!iob) | ||
| 3203 | return -ENOMEM; | ||
| 3149 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 3204 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 3150 | cmd->data.diagass.subcmd_len = 16; | 3205 | cmd->data.diagass.subcmd_len = 16; |
| 3151 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY; | 3206 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY; |
| @@ -3197,6 +3252,8 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action) | |||
| 3197 | 3252 | ||
| 3198 | QETH_DBF_TEXT(SETUP, 2, "diagtrap"); | 3253 | QETH_DBF_TEXT(SETUP, 2, "diagtrap"); |
| 3199 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); | 3254 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); |
| 3255 | if (!iob) | ||
| 3256 | return -ENOMEM; | ||
| 3200 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 3257 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 3201 | cmd->data.diagass.subcmd_len = 80; | 3258 | cmd->data.diagass.subcmd_len = 80; |
| 3202 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP; | 3259 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP; |
| @@ -4162,6 +4219,8 @@ void qeth_setadp_promisc_mode(struct qeth_card *card) | |||
| 4162 | 4219 | ||
| 4163 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE, | 4220 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE, |
| 4164 | sizeof(struct qeth_ipacmd_setadpparms)); | 4221 | sizeof(struct qeth_ipacmd_setadpparms)); |
| 4222 | if (!iob) | ||
| 4223 | return; | ||
| 4165 | cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); | 4224 | cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); |
| 4166 | cmd->data.setadapterparms.data.mode = mode; | 4225 | cmd->data.setadapterparms.data.mode = mode; |
| 4167 | qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL); | 4226 | qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL); |
| @@ -4232,6 +4291,8 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card) | |||
| 4232 | 4291 | ||
| 4233 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_ALTER_MAC_ADDRESS, | 4292 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_ALTER_MAC_ADDRESS, |
| 4234 | sizeof(struct qeth_ipacmd_setadpparms)); | 4293 | sizeof(struct qeth_ipacmd_setadpparms)); |
| 4294 | if (!iob) | ||
| 4295 | return -ENOMEM; | ||
| 4235 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 4296 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 4236 | cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC; | 4297 | cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC; |
| 4237 | cmd->data.setadapterparms.data.change_addr.addr_size = OSA_ADDR_LEN; | 4298 | cmd->data.setadapterparms.data.change_addr.addr_size = OSA_ADDR_LEN; |
| @@ -4345,6 +4406,8 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card, | |||
| 4345 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL, | 4406 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL, |
| 4346 | sizeof(struct qeth_ipacmd_setadpparms_hdr) + | 4407 | sizeof(struct qeth_ipacmd_setadpparms_hdr) + |
| 4347 | sizeof(struct qeth_set_access_ctrl)); | 4408 | sizeof(struct qeth_set_access_ctrl)); |
| 4409 | if (!iob) | ||
| 4410 | return -ENOMEM; | ||
| 4348 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 4411 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 4349 | access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl; | 4412 | access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl; |
| 4350 | access_ctrl_req->subcmd_code = isolation; | 4413 | access_ctrl_req->subcmd_code = isolation; |
| @@ -4588,6 +4651,10 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) | |||
| 4588 | 4651 | ||
| 4589 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, | 4652 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, |
| 4590 | QETH_SNMP_SETADP_CMDLENGTH + req_len); | 4653 | QETH_SNMP_SETADP_CMDLENGTH + req_len); |
| 4654 | if (!iob) { | ||
| 4655 | rc = -ENOMEM; | ||
| 4656 | goto out; | ||
| 4657 | } | ||
| 4591 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 4658 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 4592 | memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len); | 4659 | memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len); |
| 4593 | rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len, | 4660 | rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len, |
| @@ -4599,7 +4666,7 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) | |||
| 4599 | if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) | 4666 | if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) |
| 4600 | rc = -EFAULT; | 4667 | rc = -EFAULT; |
| 4601 | } | 4668 | } |
| 4602 | 4669 | out: | |
| 4603 | kfree(ureq); | 4670 | kfree(ureq); |
| 4604 | kfree(qinfo.udata); | 4671 | kfree(qinfo.udata); |
| 4605 | return rc; | 4672 | return rc; |
| @@ -4670,6 +4737,10 @@ int qeth_query_oat_command(struct qeth_card *card, char __user *udata) | |||
| 4670 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT, | 4737 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT, |
| 4671 | sizeof(struct qeth_ipacmd_setadpparms_hdr) + | 4738 | sizeof(struct qeth_ipacmd_setadpparms_hdr) + |
| 4672 | sizeof(struct qeth_query_oat)); | 4739 | sizeof(struct qeth_query_oat)); |
| 4740 | if (!iob) { | ||
| 4741 | rc = -ENOMEM; | ||
| 4742 | goto out_free; | ||
| 4743 | } | ||
| 4673 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 4744 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 4674 | oat_req = &cmd->data.setadapterparms.data.query_oat; | 4745 | oat_req = &cmd->data.setadapterparms.data.query_oat; |
| 4675 | oat_req->subcmd_code = oat_data.command; | 4746 | oat_req->subcmd_code = oat_data.command; |
| @@ -4735,6 +4806,8 @@ static int qeth_query_card_info(struct qeth_card *card, | |||
| 4735 | return -EOPNOTSUPP; | 4806 | return -EOPNOTSUPP; |
| 4736 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_CARD_INFO, | 4807 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_CARD_INFO, |
| 4737 | sizeof(struct qeth_ipacmd_setadpparms_hdr)); | 4808 | sizeof(struct qeth_ipacmd_setadpparms_hdr)); |
| 4809 | if (!iob) | ||
| 4810 | return -ENOMEM; | ||
| 4738 | return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb, | 4811 | return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb, |
| 4739 | (void *)carrier_info); | 4812 | (void *)carrier_info); |
| 4740 | } | 4813 | } |
| @@ -5060,11 +5133,23 @@ retriable: | |||
| 5060 | card->options.adp.supported_funcs = 0; | 5133 | card->options.adp.supported_funcs = 0; |
| 5061 | card->options.sbp.supported_funcs = 0; | 5134 | card->options.sbp.supported_funcs = 0; |
| 5062 | card->info.diagass_support = 0; | 5135 | card->info.diagass_support = 0; |
| 5063 | qeth_query_ipassists(card, QETH_PROT_IPV4); | 5136 | rc = qeth_query_ipassists(card, QETH_PROT_IPV4); |
| 5064 | if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) | 5137 | if (rc == -ENOMEM) |
| 5065 | qeth_query_setadapterparms(card); | 5138 | goto out; |
| 5066 | if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) | 5139 | if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) { |
| 5067 | qeth_query_setdiagass(card); | 5140 | rc = qeth_query_setadapterparms(card); |
| 5141 | if (rc < 0) { | ||
| 5142 | QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); | ||
| 5143 | goto out; | ||
| 5144 | } | ||
| 5145 | } | ||
| 5146 | if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) { | ||
| 5147 | rc = qeth_query_setdiagass(card); | ||
| 5148 | if (rc < 0) { | ||
| 5149 | QETH_DBF_TEXT_(SETUP, 2, "7err%d", rc); | ||
| 5150 | goto out; | ||
| 5151 | } | ||
| 5152 | } | ||
| 5068 | return 0; | 5153 | return 0; |
| 5069 | out: | 5154 | out: |
| 5070 | dev_warn(&card->gdev->dev, "The qeth device driver failed to recover " | 5155 | dev_warn(&card->gdev->dev, "The qeth device driver failed to recover " |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index d02cd1a67943..ce87ae72edbd 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
| @@ -27,10 +27,7 @@ static int qeth_l2_set_offline(struct ccwgroup_device *); | |||
| 27 | static int qeth_l2_stop(struct net_device *); | 27 | static int qeth_l2_stop(struct net_device *); |
| 28 | static int qeth_l2_send_delmac(struct qeth_card *, __u8 *); | 28 | static int qeth_l2_send_delmac(struct qeth_card *, __u8 *); |
| 29 | static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *, | 29 | static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *, |
| 30 | enum qeth_ipa_cmds, | 30 | enum qeth_ipa_cmds); |
| 31 | int (*reply_cb) (struct qeth_card *, | ||
| 32 | struct qeth_reply*, | ||
| 33 | unsigned long)); | ||
| 34 | static void qeth_l2_set_multicast_list(struct net_device *); | 31 | static void qeth_l2_set_multicast_list(struct net_device *); |
| 35 | static int qeth_l2_recover(void *); | 32 | static int qeth_l2_recover(void *); |
| 36 | static void qeth_bridgeport_query_support(struct qeth_card *card); | 33 | static void qeth_bridgeport_query_support(struct qeth_card *card); |
| @@ -130,56 +127,71 @@ static struct net_device *qeth_l2_netdev_by_devno(unsigned char *read_dev_no) | |||
| 130 | return ndev; | 127 | return ndev; |
| 131 | } | 128 | } |
| 132 | 129 | ||
| 133 | static int qeth_l2_send_setgroupmac_cb(struct qeth_card *card, | 130 | static int qeth_setdel_makerc(struct qeth_card *card, int retcode) |
| 134 | struct qeth_reply *reply, | ||
| 135 | unsigned long data) | ||
| 136 | { | 131 | { |
| 137 | struct qeth_ipa_cmd *cmd; | 132 | int rc; |
| 138 | __u8 *mac; | ||
| 139 | 133 | ||
| 140 | QETH_CARD_TEXT(card, 2, "L2Sgmacb"); | 134 | if (retcode) |
| 141 | cmd = (struct qeth_ipa_cmd *) data; | 135 | QETH_CARD_TEXT_(card, 2, "err%04x", retcode); |
| 142 | mac = &cmd->data.setdelmac.mac[0]; | 136 | switch (retcode) { |
| 143 | /* MAC already registered, needed in couple/uncouple case */ | 137 | case IPA_RC_SUCCESS: |
| 144 | if (cmd->hdr.return_code == IPA_RC_L2_DUP_MAC) { | 138 | rc = 0; |
| 145 | QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s \n", | 139 | break; |
| 146 | mac, QETH_CARD_IFNAME(card)); | 140 | case IPA_RC_L2_UNSUPPORTED_CMD: |
| 147 | cmd->hdr.return_code = 0; | 141 | rc = -ENOSYS; |
| 142 | break; | ||
| 143 | case IPA_RC_L2_ADDR_TABLE_FULL: | ||
| 144 | rc = -ENOSPC; | ||
| 145 | break; | ||
| 146 | case IPA_RC_L2_DUP_MAC: | ||
| 147 | case IPA_RC_L2_DUP_LAYER3_MAC: | ||
| 148 | rc = -EEXIST; | ||
| 149 | break; | ||
| 150 | case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: | ||
| 151 | case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: | ||
| 152 | rc = -EPERM; | ||
| 153 | break; | ||
| 154 | case IPA_RC_L2_MAC_NOT_FOUND: | ||
| 155 | rc = -ENOENT; | ||
| 156 | break; | ||
| 157 | case -ENOMEM: | ||
| 158 | rc = -ENOMEM; | ||
| 159 | break; | ||
| 160 | default: | ||
| 161 | rc = -EIO; | ||
| 162 | break; | ||
| 148 | } | 163 | } |
| 149 | if (cmd->hdr.return_code) | 164 | return rc; |
| 150 | QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %x\n", | ||
| 151 | mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code); | ||
| 152 | return 0; | ||
| 153 | } | 165 | } |
| 154 | 166 | ||
| 155 | static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac) | 167 | static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac) |
| 156 | { | 168 | { |
| 157 | QETH_CARD_TEXT(card, 2, "L2Sgmac"); | 169 | int rc; |
| 158 | return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETGMAC, | ||
| 159 | qeth_l2_send_setgroupmac_cb); | ||
| 160 | } | ||
| 161 | |||
| 162 | static int qeth_l2_send_delgroupmac_cb(struct qeth_card *card, | ||
| 163 | struct qeth_reply *reply, | ||
| 164 | unsigned long data) | ||
| 165 | { | ||
| 166 | struct qeth_ipa_cmd *cmd; | ||
| 167 | __u8 *mac; | ||
| 168 | 170 | ||
| 169 | QETH_CARD_TEXT(card, 2, "L2Dgmacb"); | 171 | QETH_CARD_TEXT(card, 2, "L2Sgmac"); |
| 170 | cmd = (struct qeth_ipa_cmd *) data; | 172 | rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, |
| 171 | mac = &cmd->data.setdelmac.mac[0]; | 173 | IPA_CMD_SETGMAC)); |
| 172 | if (cmd->hdr.return_code) | 174 | if (rc == -EEXIST) |
| 173 | QETH_DBF_MESSAGE(2, "Could not delete group MAC %pM on %s: %x\n", | 175 | QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s\n", |
| 174 | mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code); | 176 | mac, QETH_CARD_IFNAME(card)); |
| 175 | return 0; | 177 | else if (rc) |
| 178 | QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %d\n", | ||
| 179 | mac, QETH_CARD_IFNAME(card), rc); | ||
| 180 | return rc; | ||
| 176 | } | 181 | } |
| 177 | 182 | ||
| 178 | static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac) | 183 | static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac) |
| 179 | { | 184 | { |
| 185 | int rc; | ||
| 186 | |||
| 180 | QETH_CARD_TEXT(card, 2, "L2Dgmac"); | 187 | QETH_CARD_TEXT(card, 2, "L2Dgmac"); |
| 181 | return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELGMAC, | 188 | rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, |
| 182 | qeth_l2_send_delgroupmac_cb); | 189 | IPA_CMD_DELGMAC)); |
| 190 | if (rc) | ||
| 191 | QETH_DBF_MESSAGE(2, | ||
| 192 | "Could not delete group MAC %pM on %s: %d\n", | ||
| 193 | mac, QETH_CARD_IFNAME(card), rc); | ||
| 194 | return rc; | ||
| 183 | } | 195 | } |
| 184 | 196 | ||
| 185 | static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac) | 197 | static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac) |
| @@ -197,10 +209,11 @@ static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac) | |||
| 197 | mc->is_vmac = vmac; | 209 | mc->is_vmac = vmac; |
| 198 | 210 | ||
| 199 | if (vmac) { | 211 | if (vmac) { |
| 200 | rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC, | 212 | rc = qeth_setdel_makerc(card, |
| 201 | NULL); | 213 | qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC)); |
| 202 | } else { | 214 | } else { |
| 203 | rc = qeth_l2_send_setgroupmac(card, mac); | 215 | rc = qeth_setdel_makerc(card, |
| 216 | qeth_l2_send_setgroupmac(card, mac)); | ||
| 204 | } | 217 | } |
| 205 | 218 | ||
| 206 | if (!rc) | 219 | if (!rc) |
| @@ -218,7 +231,7 @@ static void qeth_l2_del_all_mc(struct qeth_card *card, int del) | |||
| 218 | if (del) { | 231 | if (del) { |
| 219 | if (mc->is_vmac) | 232 | if (mc->is_vmac) |
| 220 | qeth_l2_send_setdelmac(card, mc->mc_addr, | 233 | qeth_l2_send_setdelmac(card, mc->mc_addr, |
| 221 | IPA_CMD_DELVMAC, NULL); | 234 | IPA_CMD_DELVMAC); |
| 222 | else | 235 | else |
| 223 | qeth_l2_send_delgroupmac(card, mc->mc_addr); | 236 | qeth_l2_send_delgroupmac(card, mc->mc_addr); |
| 224 | } | 237 | } |
| @@ -291,6 +304,8 @@ static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i, | |||
| 291 | 304 | ||
| 292 | QETH_CARD_TEXT_(card, 4, "L2sdv%x", ipacmd); | 305 | QETH_CARD_TEXT_(card, 4, "L2sdv%x", ipacmd); |
| 293 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); | 306 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); |
| 307 | if (!iob) | ||
| 308 | return -ENOMEM; | ||
| 294 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 309 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 295 | cmd->data.setdelvlan.vlan_id = i; | 310 | cmd->data.setdelvlan.vlan_id = i; |
| 296 | return qeth_send_ipa_cmd(card, iob, | 311 | return qeth_send_ipa_cmd(card, iob, |
| @@ -313,6 +328,7 @@ static int qeth_l2_vlan_rx_add_vid(struct net_device *dev, | |||
| 313 | { | 328 | { |
| 314 | struct qeth_card *card = dev->ml_priv; | 329 | struct qeth_card *card = dev->ml_priv; |
| 315 | struct qeth_vlan_vid *id; | 330 | struct qeth_vlan_vid *id; |
| 331 | int rc; | ||
| 316 | 332 | ||
| 317 | QETH_CARD_TEXT_(card, 4, "aid:%d", vid); | 333 | QETH_CARD_TEXT_(card, 4, "aid:%d", vid); |
| 318 | if (!vid) | 334 | if (!vid) |
| @@ -328,7 +344,11 @@ static int qeth_l2_vlan_rx_add_vid(struct net_device *dev, | |||
| 328 | id = kmalloc(sizeof(struct qeth_vlan_vid), GFP_ATOMIC); | 344 | id = kmalloc(sizeof(struct qeth_vlan_vid), GFP_ATOMIC); |
| 329 | if (id) { | 345 | if (id) { |
| 330 | id->vid = vid; | 346 | id->vid = vid; |
| 331 | qeth_l2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN); | 347 | rc = qeth_l2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN); |
| 348 | if (rc) { | ||
| 349 | kfree(id); | ||
| 350 | return rc; | ||
| 351 | } | ||
| 332 | spin_lock_bh(&card->vlanlock); | 352 | spin_lock_bh(&card->vlanlock); |
| 333 | list_add_tail(&id->list, &card->vid_list); | 353 | list_add_tail(&id->list, &card->vid_list); |
| 334 | spin_unlock_bh(&card->vlanlock); | 354 | spin_unlock_bh(&card->vlanlock); |
| @@ -343,6 +363,7 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev, | |||
| 343 | { | 363 | { |
| 344 | struct qeth_vlan_vid *id, *tmpid = NULL; | 364 | struct qeth_vlan_vid *id, *tmpid = NULL; |
| 345 | struct qeth_card *card = dev->ml_priv; | 365 | struct qeth_card *card = dev->ml_priv; |
| 366 | int rc = 0; | ||
| 346 | 367 | ||
| 347 | QETH_CARD_TEXT_(card, 4, "kid:%d", vid); | 368 | QETH_CARD_TEXT_(card, 4, "kid:%d", vid); |
| 348 | if (card->info.type == QETH_CARD_TYPE_OSM) { | 369 | if (card->info.type == QETH_CARD_TYPE_OSM) { |
| @@ -363,11 +384,11 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev, | |||
| 363 | } | 384 | } |
| 364 | spin_unlock_bh(&card->vlanlock); | 385 | spin_unlock_bh(&card->vlanlock); |
| 365 | if (tmpid) { | 386 | if (tmpid) { |
| 366 | qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN); | 387 | rc = qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN); |
| 367 | kfree(tmpid); | 388 | kfree(tmpid); |
| 368 | } | 389 | } |
| 369 | qeth_l2_set_multicast_list(card->dev); | 390 | qeth_l2_set_multicast_list(card->dev); |
| 370 | return 0; | 391 | return rc; |
| 371 | } | 392 | } |
| 372 | 393 | ||
| 373 | static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) | 394 | static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) |
| @@ -539,91 +560,62 @@ out: | |||
| 539 | } | 560 | } |
| 540 | 561 | ||
| 541 | static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, | 562 | static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, |
| 542 | enum qeth_ipa_cmds ipacmd, | 563 | enum qeth_ipa_cmds ipacmd) |
| 543 | int (*reply_cb) (struct qeth_card *, | ||
| 544 | struct qeth_reply*, | ||
| 545 | unsigned long)) | ||
| 546 | { | 564 | { |
| 547 | struct qeth_ipa_cmd *cmd; | 565 | struct qeth_ipa_cmd *cmd; |
| 548 | struct qeth_cmd_buffer *iob; | 566 | struct qeth_cmd_buffer *iob; |
| 549 | 567 | ||
| 550 | QETH_CARD_TEXT(card, 2, "L2sdmac"); | 568 | QETH_CARD_TEXT(card, 2, "L2sdmac"); |
| 551 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); | 569 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); |
| 570 | if (!iob) | ||
| 571 | return -ENOMEM; | ||
| 552 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 572 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 553 | cmd->data.setdelmac.mac_length = OSA_ADDR_LEN; | 573 | cmd->data.setdelmac.mac_length = OSA_ADDR_LEN; |
| 554 | memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN); | 574 | memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN); |
| 555 | return qeth_send_ipa_cmd(card, iob, reply_cb, NULL); | 575 | return qeth_send_ipa_cmd(card, iob, NULL, NULL); |
| 556 | } | 576 | } |
| 557 | 577 | ||
| 558 | static int qeth_l2_send_setmac_cb(struct qeth_card *card, | 578 | static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) |
| 559 | struct qeth_reply *reply, | ||
| 560 | unsigned long data) | ||
| 561 | { | 579 | { |
| 562 | struct qeth_ipa_cmd *cmd; | 580 | int rc; |
| 563 | 581 | ||
| 564 | QETH_CARD_TEXT(card, 2, "L2Smaccb"); | 582 | QETH_CARD_TEXT(card, 2, "L2Setmac"); |
| 565 | cmd = (struct qeth_ipa_cmd *) data; | 583 | rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, |
| 566 | if (cmd->hdr.return_code) { | 584 | IPA_CMD_SETVMAC)); |
| 567 | QETH_CARD_TEXT_(card, 2, "L2er%x", cmd->hdr.return_code); | 585 | if (rc == 0) { |
| 586 | card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; | ||
| 587 | memcpy(card->dev->dev_addr, mac, OSA_ADDR_LEN); | ||
| 588 | dev_info(&card->gdev->dev, | ||
| 589 | "MAC address %pM successfully registered on device %s\n", | ||
| 590 | card->dev->dev_addr, card->dev->name); | ||
| 591 | } else { | ||
| 568 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; | 592 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; |
| 569 | switch (cmd->hdr.return_code) { | 593 | switch (rc) { |
| 570 | case IPA_RC_L2_DUP_MAC: | 594 | case -EEXIST: |
| 571 | case IPA_RC_L2_DUP_LAYER3_MAC: | ||
| 572 | dev_warn(&card->gdev->dev, | 595 | dev_warn(&card->gdev->dev, |
| 573 | "MAC address %pM already exists\n", | 596 | "MAC address %pM already exists\n", mac); |
| 574 | cmd->data.setdelmac.mac); | ||
| 575 | break; | 597 | break; |
| 576 | case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: | 598 | case -EPERM: |
| 577 | case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: | ||
| 578 | dev_warn(&card->gdev->dev, | 599 | dev_warn(&card->gdev->dev, |
| 579 | "MAC address %pM is not authorized\n", | 600 | "MAC address %pM is not authorized\n", mac); |
| 580 | cmd->data.setdelmac.mac); | ||
| 581 | break; | ||
| 582 | default: | ||
| 583 | break; | 601 | break; |
| 584 | } | 602 | } |
| 585 | } else { | ||
| 586 | card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; | ||
| 587 | memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac, | ||
| 588 | OSA_ADDR_LEN); | ||
| 589 | dev_info(&card->gdev->dev, | ||
| 590 | "MAC address %pM successfully registered on device %s\n", | ||
| 591 | card->dev->dev_addr, card->dev->name); | ||
| 592 | } | ||
| 593 | return 0; | ||
| 594 | } | ||
| 595 | |||
| 596 | static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) | ||
| 597 | { | ||
| 598 | QETH_CARD_TEXT(card, 2, "L2Setmac"); | ||
| 599 | return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC, | ||
| 600 | qeth_l2_send_setmac_cb); | ||
| 601 | } | ||
| 602 | |||
| 603 | static int qeth_l2_send_delmac_cb(struct qeth_card *card, | ||
| 604 | struct qeth_reply *reply, | ||
| 605 | unsigned long data) | ||
| 606 | { | ||
| 607 | struct qeth_ipa_cmd *cmd; | ||
| 608 | |||
| 609 | QETH_CARD_TEXT(card, 2, "L2Dmaccb"); | ||
| 610 | cmd = (struct qeth_ipa_cmd *) data; | ||
| 611 | if (cmd->hdr.return_code) { | ||
| 612 | QETH_CARD_TEXT_(card, 2, "err%d", cmd->hdr.return_code); | ||
| 613 | return 0; | ||
| 614 | } | 603 | } |
| 615 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; | 604 | return rc; |
| 616 | |||
| 617 | return 0; | ||
| 618 | } | 605 | } |
| 619 | 606 | ||
| 620 | static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac) | 607 | static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac) |
| 621 | { | 608 | { |
| 609 | int rc; | ||
| 610 | |||
| 622 | QETH_CARD_TEXT(card, 2, "L2Delmac"); | 611 | QETH_CARD_TEXT(card, 2, "L2Delmac"); |
| 623 | if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)) | 612 | if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)) |
| 624 | return 0; | 613 | return 0; |
| 625 | return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELVMAC, | 614 | rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, |
| 626 | qeth_l2_send_delmac_cb); | 615 | IPA_CMD_DELVMAC)); |
| 616 | if (rc == 0) | ||
| 617 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; | ||
| 618 | return rc; | ||
| 627 | } | 619 | } |
| 628 | 620 | ||
| 629 | static int qeth_l2_request_initial_mac(struct qeth_card *card) | 621 | static int qeth_l2_request_initial_mac(struct qeth_card *card) |
| @@ -651,7 +643,7 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) | |||
| 651 | if (rc) { | 643 | if (rc) { |
| 652 | QETH_DBF_MESSAGE(2, "couldn't get MAC address on " | 644 | QETH_DBF_MESSAGE(2, "couldn't get MAC address on " |
| 653 | "device %s: x%x\n", CARD_BUS_ID(card), rc); | 645 | "device %s: x%x\n", CARD_BUS_ID(card), rc); |
| 654 | QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); | 646 | QETH_DBF_TEXT_(SETUP, 2, "1err%04x", rc); |
| 655 | return rc; | 647 | return rc; |
| 656 | } | 648 | } |
| 657 | QETH_DBF_HEX(SETUP, 2, card->dev->dev_addr, OSA_ADDR_LEN); | 649 | QETH_DBF_HEX(SETUP, 2, card->dev->dev_addr, OSA_ADDR_LEN); |
| @@ -687,7 +679,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) | |||
| 687 | return -ERESTARTSYS; | 679 | return -ERESTARTSYS; |
| 688 | } | 680 | } |
| 689 | rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); | 681 | rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); |
| 690 | if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND)) | 682 | if (!rc || (rc == -ENOENT)) |
| 691 | rc = qeth_l2_send_setmac(card, addr->sa_data); | 683 | rc = qeth_l2_send_setmac(card, addr->sa_data); |
| 692 | return rc ? -EINVAL : 0; | 684 | return rc ? -EINVAL : 0; |
| 693 | } | 685 | } |
| @@ -996,7 +988,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
| 996 | recover_flag = card->state; | 988 | recover_flag = card->state; |
| 997 | rc = qeth_core_hardsetup_card(card); | 989 | rc = qeth_core_hardsetup_card(card); |
| 998 | if (rc) { | 990 | if (rc) { |
| 999 | QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); | 991 | QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); |
| 1000 | rc = -ENODEV; | 992 | rc = -ENODEV; |
| 1001 | goto out_remove; | 993 | goto out_remove; |
| 1002 | } | 994 | } |
| @@ -1730,6 +1722,8 @@ static void qeth_bridgeport_query_support(struct qeth_card *card) | |||
| 1730 | 1722 | ||
| 1731 | QETH_CARD_TEXT(card, 2, "brqsuppo"); | 1723 | QETH_CARD_TEXT(card, 2, "brqsuppo"); |
| 1732 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); | 1724 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); |
| 1725 | if (!iob) | ||
| 1726 | return; | ||
| 1733 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1727 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1734 | cmd->data.sbp.hdr.cmdlength = | 1728 | cmd->data.sbp.hdr.cmdlength = |
| 1735 | sizeof(struct qeth_ipacmd_sbp_hdr) + | 1729 | sizeof(struct qeth_ipacmd_sbp_hdr) + |
| @@ -1805,6 +1799,8 @@ int qeth_bridgeport_query_ports(struct qeth_card *card, | |||
| 1805 | if (!(card->options.sbp.supported_funcs & IPA_SBP_QUERY_BRIDGE_PORTS)) | 1799 | if (!(card->options.sbp.supported_funcs & IPA_SBP_QUERY_BRIDGE_PORTS)) |
| 1806 | return -EOPNOTSUPP; | 1800 | return -EOPNOTSUPP; |
| 1807 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); | 1801 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); |
| 1802 | if (!iob) | ||
| 1803 | return -ENOMEM; | ||
| 1808 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1804 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1809 | cmd->data.sbp.hdr.cmdlength = | 1805 | cmd->data.sbp.hdr.cmdlength = |
| 1810 | sizeof(struct qeth_ipacmd_sbp_hdr); | 1806 | sizeof(struct qeth_ipacmd_sbp_hdr); |
| @@ -1817,9 +1813,7 @@ int qeth_bridgeport_query_ports(struct qeth_card *card, | |||
| 1817 | if (rc) | 1813 | if (rc) |
| 1818 | return rc; | 1814 | return rc; |
| 1819 | rc = qeth_bridgeport_makerc(card, &cbctl, IPA_SBP_QUERY_BRIDGE_PORTS); | 1815 | rc = qeth_bridgeport_makerc(card, &cbctl, IPA_SBP_QUERY_BRIDGE_PORTS); |
| 1820 | if (rc) | 1816 | return rc; |
| 1821 | return rc; | ||
| 1822 | return 0; | ||
| 1823 | } | 1817 | } |
| 1824 | EXPORT_SYMBOL_GPL(qeth_bridgeport_query_ports); | 1818 | EXPORT_SYMBOL_GPL(qeth_bridgeport_query_ports); |
| 1825 | 1819 | ||
| @@ -1873,6 +1867,8 @@ int qeth_bridgeport_setrole(struct qeth_card *card, enum qeth_sbp_roles role) | |||
| 1873 | if (!(card->options.sbp.supported_funcs & setcmd)) | 1867 | if (!(card->options.sbp.supported_funcs & setcmd)) |
| 1874 | return -EOPNOTSUPP; | 1868 | return -EOPNOTSUPP; |
| 1875 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); | 1869 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); |
| 1870 | if (!iob) | ||
| 1871 | return -ENOMEM; | ||
| 1876 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1872 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1877 | cmd->data.sbp.hdr.cmdlength = cmdlength; | 1873 | cmd->data.sbp.hdr.cmdlength = cmdlength; |
| 1878 | cmd->data.sbp.hdr.command_code = setcmd; | 1874 | cmd->data.sbp.hdr.command_code = setcmd; |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 625227ad16ee..e2a0ee845399 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
| @@ -549,6 +549,8 @@ static int qeth_l3_send_setdelmc(struct qeth_card *card, | |||
| 549 | QETH_CARD_TEXT(card, 4, "setdelmc"); | 549 | QETH_CARD_TEXT(card, 4, "setdelmc"); |
| 550 | 550 | ||
| 551 | iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); | 551 | iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); |
| 552 | if (!iob) | ||
| 553 | return -ENOMEM; | ||
| 552 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 554 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 553 | memcpy(&cmd->data.setdelipm.mac, addr->mac, OSA_ADDR_LEN); | 555 | memcpy(&cmd->data.setdelipm.mac, addr->mac, OSA_ADDR_LEN); |
| 554 | if (addr->proto == QETH_PROT_IPV6) | 556 | if (addr->proto == QETH_PROT_IPV6) |
| @@ -588,6 +590,8 @@ static int qeth_l3_send_setdelip(struct qeth_card *card, | |||
| 588 | QETH_CARD_TEXT_(card, 4, "flags%02X", flags); | 590 | QETH_CARD_TEXT_(card, 4, "flags%02X", flags); |
| 589 | 591 | ||
| 590 | iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); | 592 | iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); |
| 593 | if (!iob) | ||
| 594 | return -ENOMEM; | ||
| 591 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 595 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 592 | if (addr->proto == QETH_PROT_IPV6) { | 596 | if (addr->proto == QETH_PROT_IPV6) { |
| 593 | memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr, | 597 | memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr, |
| @@ -616,6 +620,8 @@ static int qeth_l3_send_setrouting(struct qeth_card *card, | |||
| 616 | 620 | ||
| 617 | QETH_CARD_TEXT(card, 4, "setroutg"); | 621 | QETH_CARD_TEXT(card, 4, "setroutg"); |
| 618 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot); | 622 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot); |
| 623 | if (!iob) | ||
| 624 | return -ENOMEM; | ||
| 619 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 625 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 620 | cmd->data.setrtg.type = (type); | 626 | cmd->data.setrtg.type = (type); |
| 621 | rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); | 627 | rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); |
| @@ -1049,12 +1055,14 @@ static struct qeth_cmd_buffer *qeth_l3_get_setassparms_cmd( | |||
| 1049 | QETH_CARD_TEXT(card, 4, "getasscm"); | 1055 | QETH_CARD_TEXT(card, 4, "getasscm"); |
| 1050 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot); | 1056 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot); |
| 1051 | 1057 | ||
| 1052 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1058 | if (iob) { |
| 1053 | cmd->data.setassparms.hdr.assist_no = ipa_func; | 1059 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1054 | cmd->data.setassparms.hdr.length = 8 + len; | 1060 | cmd->data.setassparms.hdr.assist_no = ipa_func; |
| 1055 | cmd->data.setassparms.hdr.command_code = cmd_code; | 1061 | cmd->data.setassparms.hdr.length = 8 + len; |
| 1056 | cmd->data.setassparms.hdr.return_code = 0; | 1062 | cmd->data.setassparms.hdr.command_code = cmd_code; |
| 1057 | cmd->data.setassparms.hdr.seq_no = 0; | 1063 | cmd->data.setassparms.hdr.return_code = 0; |
| 1064 | cmd->data.setassparms.hdr.seq_no = 0; | ||
| 1065 | } | ||
| 1058 | 1066 | ||
| 1059 | return iob; | 1067 | return iob; |
| 1060 | } | 1068 | } |
| @@ -1090,6 +1098,8 @@ static int qeth_l3_send_simple_setassparms_ipv6(struct qeth_card *card, | |||
| 1090 | QETH_CARD_TEXT(card, 4, "simassp6"); | 1098 | QETH_CARD_TEXT(card, 4, "simassp6"); |
| 1091 | iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, | 1099 | iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, |
| 1092 | 0, QETH_PROT_IPV6); | 1100 | 0, QETH_PROT_IPV6); |
| 1101 | if (!iob) | ||
| 1102 | return -ENOMEM; | ||
| 1093 | rc = qeth_l3_send_setassparms(card, iob, 0, 0, | 1103 | rc = qeth_l3_send_setassparms(card, iob, 0, 0, |
| 1094 | qeth_l3_default_setassparms_cb, NULL); | 1104 | qeth_l3_default_setassparms_cb, NULL); |
| 1095 | return rc; | 1105 | return rc; |
| @@ -1108,6 +1118,8 @@ static int qeth_l3_send_simple_setassparms(struct qeth_card *card, | |||
| 1108 | length = sizeof(__u32); | 1118 | length = sizeof(__u32); |
| 1109 | iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, | 1119 | iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, |
| 1110 | length, QETH_PROT_IPV4); | 1120 | length, QETH_PROT_IPV4); |
| 1121 | if (!iob) | ||
| 1122 | return -ENOMEM; | ||
| 1111 | rc = qeth_l3_send_setassparms(card, iob, length, data, | 1123 | rc = qeth_l3_send_setassparms(card, iob, length, data, |
| 1112 | qeth_l3_default_setassparms_cb, NULL); | 1124 | qeth_l3_default_setassparms_cb, NULL); |
| 1113 | return rc; | 1125 | return rc; |
| @@ -1494,6 +1506,8 @@ static int qeth_l3_iqd_read_initial_mac(struct qeth_card *card) | |||
| 1494 | 1506 | ||
| 1495 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, | 1507 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, |
| 1496 | QETH_PROT_IPV6); | 1508 | QETH_PROT_IPV6); |
| 1509 | if (!iob) | ||
| 1510 | return -ENOMEM; | ||
| 1497 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1511 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1498 | *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = | 1512 | *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = |
| 1499 | card->info.unique_id; | 1513 | card->info.unique_id; |
| @@ -1537,6 +1551,8 @@ static int qeth_l3_get_unique_id(struct qeth_card *card) | |||
| 1537 | 1551 | ||
| 1538 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, | 1552 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, |
| 1539 | QETH_PROT_IPV6); | 1553 | QETH_PROT_IPV6); |
| 1554 | if (!iob) | ||
| 1555 | return -ENOMEM; | ||
| 1540 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1556 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1541 | *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = | 1557 | *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = |
| 1542 | card->info.unique_id; | 1558 | card->info.unique_id; |
| @@ -1611,6 +1627,8 @@ qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd) | |||
| 1611 | QETH_DBF_TEXT(SETUP, 2, "diagtrac"); | 1627 | QETH_DBF_TEXT(SETUP, 2, "diagtrac"); |
| 1612 | 1628 | ||
| 1613 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); | 1629 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); |
| 1630 | if (!iob) | ||
| 1631 | return -ENOMEM; | ||
| 1614 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1632 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 1615 | cmd->data.diagass.subcmd_len = 16; | 1633 | cmd->data.diagass.subcmd_len = 16; |
| 1616 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE; | 1634 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE; |
| @@ -2442,6 +2460,8 @@ static int qeth_l3_query_arp_cache_info(struct qeth_card *card, | |||
| 2442 | IPA_CMD_ASS_ARP_QUERY_INFO, | 2460 | IPA_CMD_ASS_ARP_QUERY_INFO, |
| 2443 | sizeof(struct qeth_arp_query_data) - sizeof(char), | 2461 | sizeof(struct qeth_arp_query_data) - sizeof(char), |
| 2444 | prot); | 2462 | prot); |
| 2463 | if (!iob) | ||
| 2464 | return -ENOMEM; | ||
| 2445 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 2465 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
| 2446 | cmd->data.setassparms.data.query_arp.request_bits = 0x000F; | 2466 | cmd->data.setassparms.data.query_arp.request_bits = 0x000F; |
| 2447 | cmd->data.setassparms.data.query_arp.reply_bits = 0; | 2467 | cmd->data.setassparms.data.query_arp.reply_bits = 0; |
| @@ -2535,6 +2555,8 @@ static int qeth_l3_arp_add_entry(struct qeth_card *card, | |||
| 2535 | IPA_CMD_ASS_ARP_ADD_ENTRY, | 2555 | IPA_CMD_ASS_ARP_ADD_ENTRY, |
| 2536 | sizeof(struct qeth_arp_cache_entry), | 2556 | sizeof(struct qeth_arp_cache_entry), |
| 2537 | QETH_PROT_IPV4); | 2557 | QETH_PROT_IPV4); |
| 2558 | if (!iob) | ||
| 2559 | return -ENOMEM; | ||
| 2538 | rc = qeth_l3_send_setassparms(card, iob, | 2560 | rc = qeth_l3_send_setassparms(card, iob, |
| 2539 | sizeof(struct qeth_arp_cache_entry), | 2561 | sizeof(struct qeth_arp_cache_entry), |
| 2540 | (unsigned long) entry, | 2562 | (unsigned long) entry, |
| @@ -2574,6 +2596,8 @@ static int qeth_l3_arp_remove_entry(struct qeth_card *card, | |||
| 2574 | IPA_CMD_ASS_ARP_REMOVE_ENTRY, | 2596 | IPA_CMD_ASS_ARP_REMOVE_ENTRY, |
| 2575 | 12, | 2597 | 12, |
| 2576 | QETH_PROT_IPV4); | 2598 | QETH_PROT_IPV4); |
| 2599 | if (!iob) | ||
| 2600 | return -ENOMEM; | ||
| 2577 | rc = qeth_l3_send_setassparms(card, iob, | 2601 | rc = qeth_l3_send_setassparms(card, iob, |
| 2578 | 12, (unsigned long)buf, | 2602 | 12, (unsigned long)buf, |
| 2579 | qeth_l3_default_setassparms_cb, NULL); | 2603 | qeth_l3_default_setassparms_cb, NULL); |
| @@ -3262,6 +3286,8 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { | |||
| 3262 | 3286 | ||
| 3263 | static int qeth_l3_setup_netdev(struct qeth_card *card) | 3287 | static int qeth_l3_setup_netdev(struct qeth_card *card) |
| 3264 | { | 3288 | { |
| 3289 | int rc; | ||
| 3290 | |||
| 3265 | if (card->info.type == QETH_CARD_TYPE_OSD || | 3291 | if (card->info.type == QETH_CARD_TYPE_OSD || |
| 3266 | card->info.type == QETH_CARD_TYPE_OSX) { | 3292 | card->info.type == QETH_CARD_TYPE_OSX) { |
| 3267 | if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || | 3293 | if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || |
| @@ -3293,7 +3319,9 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) | |||
| 3293 | return -ENODEV; | 3319 | return -ENODEV; |
| 3294 | card->dev->flags |= IFF_NOARP; | 3320 | card->dev->flags |= IFF_NOARP; |
| 3295 | card->dev->netdev_ops = &qeth_l3_netdev_ops; | 3321 | card->dev->netdev_ops = &qeth_l3_netdev_ops; |
| 3296 | qeth_l3_iqd_read_initial_mac(card); | 3322 | rc = qeth_l3_iqd_read_initial_mac(card); |
| 3323 | if (rc) | ||
| 3324 | return rc; | ||
| 3297 | if (card->options.hsuid[0]) | 3325 | if (card->options.hsuid[0]) |
| 3298 | memcpy(card->dev->perm_addr, card->options.hsuid, 9); | 3326 | memcpy(card->dev->perm_addr, card->options.hsuid, 9); |
| 3299 | } else | 3327 | } else |
| @@ -3360,7 +3388,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
| 3360 | recover_flag = card->state; | 3388 | recover_flag = card->state; |
| 3361 | rc = qeth_core_hardsetup_card(card); | 3389 | rc = qeth_core_hardsetup_card(card); |
| 3362 | if (rc) { | 3390 | if (rc) { |
| 3363 | QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); | 3391 | QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); |
| 3364 | rc = -ENODEV; | 3392 | rc = -ENODEV; |
| 3365 | goto out_remove; | 3393 | goto out_remove; |
| 3366 | } | 3394 | } |
| @@ -3401,7 +3429,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
| 3401 | contin: | 3429 | contin: |
| 3402 | rc = qeth_l3_setadapter_parms(card); | 3430 | rc = qeth_l3_setadapter_parms(card); |
| 3403 | if (rc) | 3431 | if (rc) |
| 3404 | QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); | 3432 | QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); |
| 3405 | if (!card->options.sniffer) { | 3433 | if (!card->options.sniffer) { |
| 3406 | rc = qeth_l3_start_ipassists(card); | 3434 | rc = qeth_l3_start_ipassists(card); |
| 3407 | if (rc) { | 3435 | if (rc) { |
| @@ -3410,10 +3438,10 @@ contin: | |||
| 3410 | } | 3438 | } |
| 3411 | rc = qeth_l3_setrouting_v4(card); | 3439 | rc = qeth_l3_setrouting_v4(card); |
| 3412 | if (rc) | 3440 | if (rc) |
| 3413 | QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); | 3441 | QETH_DBF_TEXT_(SETUP, 2, "4err%04x", rc); |
| 3414 | rc = qeth_l3_setrouting_v6(card); | 3442 | rc = qeth_l3_setrouting_v6(card); |
| 3415 | if (rc) | 3443 | if (rc) |
| 3416 | QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); | 3444 | QETH_DBF_TEXT_(SETUP, 2, "5err%04x", rc); |
| 3417 | } | 3445 | } |
| 3418 | netif_tx_disable(card->dev); | 3446 | netif_tx_disable(card->dev); |
| 3419 | 3447 | ||
diff --git a/include/net/ip.h b/include/net/ip.h index 0bb620702929..f7cbd703d15d 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
| @@ -39,11 +39,12 @@ struct inet_skb_parm { | |||
| 39 | struct ip_options opt; /* Compiled IP options */ | 39 | struct ip_options opt; /* Compiled IP options */ |
| 40 | unsigned char flags; | 40 | unsigned char flags; |
| 41 | 41 | ||
| 42 | #define IPSKB_FORWARDED 1 | 42 | #define IPSKB_FORWARDED BIT(0) |
| 43 | #define IPSKB_XFRM_TUNNEL_SIZE 2 | 43 | #define IPSKB_XFRM_TUNNEL_SIZE BIT(1) |
| 44 | #define IPSKB_XFRM_TRANSFORMED 4 | 44 | #define IPSKB_XFRM_TRANSFORMED BIT(2) |
| 45 | #define IPSKB_FRAG_COMPLETE 8 | 45 | #define IPSKB_FRAG_COMPLETE BIT(3) |
| 46 | #define IPSKB_REROUTED 16 | 46 | #define IPSKB_REROUTED BIT(4) |
| 47 | #define IPSKB_DOREDIRECT BIT(5) | ||
| 47 | 48 | ||
| 48 | u16 frag_max_size; | 49 | u16 frag_max_size; |
| 49 | }; | 50 | }; |
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 088ac0b1b106..536edc2be307 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
| @@ -150,7 +150,7 @@ static int map_lookup_elem(union bpf_attr *attr) | |||
| 150 | int ufd = attr->map_fd; | 150 | int ufd = attr->map_fd; |
| 151 | struct fd f = fdget(ufd); | 151 | struct fd f = fdget(ufd); |
| 152 | struct bpf_map *map; | 152 | struct bpf_map *map; |
| 153 | void *key, *value; | 153 | void *key, *value, *ptr; |
| 154 | int err; | 154 | int err; |
| 155 | 155 | ||
| 156 | if (CHECK_ATTR(BPF_MAP_LOOKUP_ELEM)) | 156 | if (CHECK_ATTR(BPF_MAP_LOOKUP_ELEM)) |
| @@ -169,20 +169,29 @@ static int map_lookup_elem(union bpf_attr *attr) | |||
| 169 | if (copy_from_user(key, ukey, map->key_size) != 0) | 169 | if (copy_from_user(key, ukey, map->key_size) != 0) |
| 170 | goto free_key; | 170 | goto free_key; |
| 171 | 171 | ||
| 172 | err = -ENOENT; | 172 | err = -ENOMEM; |
| 173 | rcu_read_lock(); | 173 | value = kmalloc(map->value_size, GFP_USER); |
| 174 | value = map->ops->map_lookup_elem(map, key); | ||
| 175 | if (!value) | 174 | if (!value) |
| 176 | goto err_unlock; | 175 | goto free_key; |
| 176 | |||
| 177 | rcu_read_lock(); | ||
| 178 | ptr = map->ops->map_lookup_elem(map, key); | ||
| 179 | if (ptr) | ||
| 180 | memcpy(value, ptr, map->value_size); | ||
| 181 | rcu_read_unlock(); | ||
| 182 | |||
| 183 | err = -ENOENT; | ||
| 184 | if (!ptr) | ||
| 185 | goto free_value; | ||
| 177 | 186 | ||
| 178 | err = -EFAULT; | 187 | err = -EFAULT; |
| 179 | if (copy_to_user(uvalue, value, map->value_size) != 0) | 188 | if (copy_to_user(uvalue, value, map->value_size) != 0) |
| 180 | goto err_unlock; | 189 | goto free_value; |
| 181 | 190 | ||
| 182 | err = 0; | 191 | err = 0; |
| 183 | 192 | ||
| 184 | err_unlock: | 193 | free_value: |
| 185 | rcu_read_unlock(); | 194 | kfree(value); |
| 186 | free_key: | 195 | free_key: |
| 187 | kfree(key); | 196 | kfree(key); |
| 188 | err_put: | 197 | err_put: |
diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 515569ffde8a..589aafd01fc5 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c | |||
| @@ -46,6 +46,7 @@ void dsa_slave_mii_bus_init(struct dsa_switch *ds) | |||
| 46 | snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "dsa-%d:%.2x", | 46 | snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "dsa-%d:%.2x", |
| 47 | ds->index, ds->pd->sw_addr); | 47 | ds->index, ds->pd->sw_addr); |
| 48 | ds->slave_mii_bus->parent = ds->master_dev; | 48 | ds->slave_mii_bus->parent = ds->master_dev; |
| 49 | ds->slave_mii_bus->phy_mask = ~ds->phys_mii_mask; | ||
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | 52 | ||
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index 3a83ce5efa80..787b3c294ce6 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c | |||
| @@ -129,7 +129,8 @@ int ip_forward(struct sk_buff *skb) | |||
| 129 | * We now generate an ICMP HOST REDIRECT giving the route | 129 | * We now generate an ICMP HOST REDIRECT giving the route |
| 130 | * we calculated. | 130 | * we calculated. |
| 131 | */ | 131 | */ |
| 132 | if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr && !skb_sec_path(skb)) | 132 | if (IPCB(skb)->flags & IPSKB_DOREDIRECT && !opt->srr && |
| 133 | !skb_sec_path(skb)) | ||
| 133 | ip_rt_send_redirect(skb); | 134 | ip_rt_send_redirect(skb); |
| 134 | 135 | ||
| 135 | skb->priority = rt_tos2priority(iph->tos); | 136 | skb->priority = rt_tos2priority(iph->tos); |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index c0d82f78d364..2a3720fb5a5f 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
| @@ -966,8 +966,11 @@ bool ping_rcv(struct sk_buff *skb) | |||
| 966 | 966 | ||
| 967 | sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id)); | 967 | sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id)); |
| 968 | if (sk != NULL) { | 968 | if (sk != NULL) { |
| 969 | struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); | ||
| 970 | |||
| 969 | pr_debug("rcv on socket %p\n", sk); | 971 | pr_debug("rcv on socket %p\n", sk); |
| 970 | ping_queue_rcv_skb(sk, skb_get(skb)); | 972 | if (skb2) |
| 973 | ping_queue_rcv_skb(sk, skb2); | ||
| 971 | sock_put(sk); | 974 | sock_put(sk); |
| 972 | return true; | 975 | return true; |
| 973 | } | 976 | } |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 6a2155b02602..d58dd0ec3e53 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1554,11 +1554,10 @@ static int __mkroute_input(struct sk_buff *skb, | |||
| 1554 | 1554 | ||
| 1555 | do_cache = res->fi && !itag; | 1555 | do_cache = res->fi && !itag; |
| 1556 | if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) && | 1556 | if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) && |
| 1557 | skb->protocol == htons(ETH_P_IP) && | ||
| 1557 | (IN_DEV_SHARED_MEDIA(out_dev) || | 1558 | (IN_DEV_SHARED_MEDIA(out_dev) || |
| 1558 | inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) { | 1559 | inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) |
| 1559 | flags |= RTCF_DOREDIRECT; | 1560 | IPCB(skb)->flags |= IPSKB_DOREDIRECT; |
| 1560 | do_cache = false; | ||
| 1561 | } | ||
| 1562 | 1561 | ||
| 1563 | if (skb->protocol != htons(ETH_P_IP)) { | 1562 | if (skb->protocol != htons(ETH_P_IP)) { |
| 1564 | /* Not IP (i.e. ARP). Do not create route, if it is | 1563 | /* Not IP (i.e. ARP). Do not create route, if it is |
| @@ -2303,6 +2302,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, | |||
| 2303 | r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED; | 2302 | r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED; |
| 2304 | if (rt->rt_flags & RTCF_NOTIFY) | 2303 | if (rt->rt_flags & RTCF_NOTIFY) |
| 2305 | r->rtm_flags |= RTM_F_NOTIFY; | 2304 | r->rtm_flags |= RTM_F_NOTIFY; |
| 2305 | if (IPCB(skb)->flags & IPSKB_DOREDIRECT) | ||
| 2306 | r->rtm_flags |= RTCF_DOREDIRECT; | ||
| 2306 | 2307 | ||
| 2307 | if (nla_put_be32(skb, RTA_DST, dst)) | 2308 | if (nla_put_be32(skb, RTA_DST, dst)) |
| 2308 | goto nla_put_failure; | 2309 | goto nla_put_failure; |
diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c index 7927db0a9279..4a000f1dd757 100644 --- a/net/ipv4/udp_diag.c +++ b/net/ipv4/udp_diag.c | |||
| @@ -99,11 +99,13 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlin | |||
| 99 | s_slot = cb->args[0]; | 99 | s_slot = cb->args[0]; |
| 100 | num = s_num = cb->args[1]; | 100 | num = s_num = cb->args[1]; |
| 101 | 101 | ||
| 102 | for (slot = s_slot; slot <= table->mask; num = s_num = 0, slot++) { | 102 | for (slot = s_slot; slot <= table->mask; s_num = 0, slot++) { |
| 103 | struct sock *sk; | 103 | struct sock *sk; |
| 104 | struct hlist_nulls_node *node; | 104 | struct hlist_nulls_node *node; |
| 105 | struct udp_hslot *hslot = &table->hash[slot]; | 105 | struct udp_hslot *hslot = &table->hash[slot]; |
| 106 | 106 | ||
| 107 | num = 0; | ||
| 108 | |||
| 107 | if (hlist_nulls_empty(&hslot->head)) | 109 | if (hlist_nulls_empty(&hslot->head)) |
| 108 | continue; | 110 | continue; |
| 109 | 111 | ||
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index b2d1838897c9..f1c6d5e98322 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
| @@ -659,6 +659,29 @@ static int fib6_commit_metrics(struct dst_entry *dst, | |||
| 659 | return 0; | 659 | return 0; |
| 660 | } | 660 | } |
| 661 | 661 | ||
| 662 | static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn, | ||
| 663 | struct net *net) | ||
| 664 | { | ||
| 665 | if (atomic_read(&rt->rt6i_ref) != 1) { | ||
| 666 | /* This route is used as dummy address holder in some split | ||
| 667 | * nodes. It is not leaked, but it still holds other resources, | ||
| 668 | * which must be released in time. So, scan ascendant nodes | ||
| 669 | * and replace dummy references to this route with references | ||
| 670 | * to still alive ones. | ||
| 671 | */ | ||
| 672 | while (fn) { | ||
| 673 | if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) { | ||
| 674 | fn->leaf = fib6_find_prefix(net, fn); | ||
| 675 | atomic_inc(&fn->leaf->rt6i_ref); | ||
| 676 | rt6_release(rt); | ||
| 677 | } | ||
| 678 | fn = fn->parent; | ||
| 679 | } | ||
| 680 | /* No more references are possible at this point. */ | ||
| 681 | BUG_ON(atomic_read(&rt->rt6i_ref) != 1); | ||
| 682 | } | ||
| 683 | } | ||
| 684 | |||
| 662 | /* | 685 | /* |
| 663 | * Insert routing information in a node. | 686 | * Insert routing information in a node. |
| 664 | */ | 687 | */ |
| @@ -807,11 +830,12 @@ add: | |||
| 807 | rt->dst.rt6_next = iter->dst.rt6_next; | 830 | rt->dst.rt6_next = iter->dst.rt6_next; |
| 808 | atomic_inc(&rt->rt6i_ref); | 831 | atomic_inc(&rt->rt6i_ref); |
| 809 | inet6_rt_notify(RTM_NEWROUTE, rt, info); | 832 | inet6_rt_notify(RTM_NEWROUTE, rt, info); |
| 810 | rt6_release(iter); | ||
| 811 | if (!(fn->fn_flags & RTN_RTINFO)) { | 833 | if (!(fn->fn_flags & RTN_RTINFO)) { |
| 812 | info->nl_net->ipv6.rt6_stats->fib_route_nodes++; | 834 | info->nl_net->ipv6.rt6_stats->fib_route_nodes++; |
| 813 | fn->fn_flags |= RTN_RTINFO; | 835 | fn->fn_flags |= RTN_RTINFO; |
| 814 | } | 836 | } |
| 837 | fib6_purge_rt(iter, fn, info->nl_net); | ||
| 838 | rt6_release(iter); | ||
| 815 | } | 839 | } |
| 816 | 840 | ||
| 817 | return 0; | 841 | return 0; |
| @@ -1322,24 +1346,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, | |||
| 1322 | fn = fib6_repair_tree(net, fn); | 1346 | fn = fib6_repair_tree(net, fn); |
| 1323 | } | 1347 | } |
| 1324 | 1348 | ||
| 1325 | if (atomic_read(&rt->rt6i_ref) != 1) { | 1349 | fib6_purge_rt(rt, fn, net); |
| 1326 | /* This route is used as dummy address holder in some split | ||
| 1327 | * nodes. It is not leaked, but it still holds other resources, | ||
| 1328 | * which must be released in time. So, scan ascendant nodes | ||
| 1329 | * and replace dummy references to this route with references | ||
| 1330 | * to still alive ones. | ||
| 1331 | */ | ||
| 1332 | while (fn) { | ||
| 1333 | if (!(fn->fn_flags & RTN_RTINFO) && fn->leaf == rt) { | ||
| 1334 | fn->leaf = fib6_find_prefix(net, fn); | ||
| 1335 | atomic_inc(&fn->leaf->rt6i_ref); | ||
| 1336 | rt6_release(rt); | ||
| 1337 | } | ||
| 1338 | fn = fn->parent; | ||
| 1339 | } | ||
| 1340 | /* No more references are possible at this point. */ | ||
| 1341 | BUG_ON(atomic_read(&rt->rt6i_ref) != 1); | ||
| 1342 | } | ||
| 1343 | 1350 | ||
| 1344 | inet6_rt_notify(RTM_DELROUTE, rt, info); | 1351 | inet6_rt_notify(RTM_DELROUTE, rt, info); |
| 1345 | rt6_release(rt); | 1352 | rt6_release(rt); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 166e33bed222..495965358d22 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -1242,12 +1242,16 @@ restart: | |||
| 1242 | rt = net->ipv6.ip6_null_entry; | 1242 | rt = net->ipv6.ip6_null_entry; |
| 1243 | else if (rt->dst.error) { | 1243 | else if (rt->dst.error) { |
| 1244 | rt = net->ipv6.ip6_null_entry; | 1244 | rt = net->ipv6.ip6_null_entry; |
| 1245 | } else if (rt == net->ipv6.ip6_null_entry) { | 1245 | goto out; |
| 1246 | } | ||
| 1247 | |||
| 1248 | if (rt == net->ipv6.ip6_null_entry) { | ||
| 1246 | fn = fib6_backtrack(fn, &fl6->saddr); | 1249 | fn = fib6_backtrack(fn, &fl6->saddr); |
| 1247 | if (fn) | 1250 | if (fn) |
| 1248 | goto restart; | 1251 | goto restart; |
| 1249 | } | 1252 | } |
| 1250 | 1253 | ||
| 1254 | out: | ||
| 1251 | dst_hold(&rt->dst); | 1255 | dst_hold(&rt->dst); |
| 1252 | 1256 | ||
| 1253 | read_unlock_bh(&table->tb6_lock); | 1257 | read_unlock_bh(&table->tb6_lock); |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 5f983644373a..48bf5a06847b 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
| @@ -130,12 +130,18 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 130 | { | 130 | { |
| 131 | struct flowi6 *fl6 = &fl->u.ip6; | 131 | struct flowi6 *fl6 = &fl->u.ip6; |
| 132 | int onlyproto = 0; | 132 | int onlyproto = 0; |
| 133 | u16 offset = skb_network_header_len(skb); | ||
| 134 | const struct ipv6hdr *hdr = ipv6_hdr(skb); | 133 | const struct ipv6hdr *hdr = ipv6_hdr(skb); |
| 134 | u16 offset = sizeof(*hdr); | ||
| 135 | struct ipv6_opt_hdr *exthdr; | 135 | struct ipv6_opt_hdr *exthdr; |
| 136 | const unsigned char *nh = skb_network_header(skb); | 136 | const unsigned char *nh = skb_network_header(skb); |
| 137 | u8 nexthdr = nh[IP6CB(skb)->nhoff]; | 137 | u16 nhoff = IP6CB(skb)->nhoff; |
| 138 | int oif = 0; | 138 | int oif = 0; |
| 139 | u8 nexthdr; | ||
| 140 | |||
| 141 | if (!nhoff) | ||
| 142 | nhoff = offsetof(struct ipv6hdr, nexthdr); | ||
| 143 | |||
| 144 | nexthdr = nh[nhoff]; | ||
| 139 | 145 | ||
| 140 | if (skb_dst(skb)) | 146 | if (skb_dst(skb)) |
| 141 | oif = skb_dst(skb)->dev->ifindex; | 147 | oif = skb_dst(skb)->dev->ifindex; |
diff --git a/net/llc/sysctl_net_llc.c b/net/llc/sysctl_net_llc.c index 612a5ddaf93b..799bafc2af39 100644 --- a/net/llc/sysctl_net_llc.c +++ b/net/llc/sysctl_net_llc.c | |||
| @@ -18,28 +18,28 @@ static struct ctl_table llc2_timeout_table[] = { | |||
| 18 | { | 18 | { |
| 19 | .procname = "ack", | 19 | .procname = "ack", |
| 20 | .data = &sysctl_llc2_ack_timeout, | 20 | .data = &sysctl_llc2_ack_timeout, |
| 21 | .maxlen = sizeof(long), | 21 | .maxlen = sizeof(sysctl_llc2_ack_timeout), |
| 22 | .mode = 0644, | 22 | .mode = 0644, |
| 23 | .proc_handler = proc_dointvec_jiffies, | 23 | .proc_handler = proc_dointvec_jiffies, |
| 24 | }, | 24 | }, |
| 25 | { | 25 | { |
| 26 | .procname = "busy", | 26 | .procname = "busy", |
| 27 | .data = &sysctl_llc2_busy_timeout, | 27 | .data = &sysctl_llc2_busy_timeout, |
| 28 | .maxlen = sizeof(long), | 28 | .maxlen = sizeof(sysctl_llc2_busy_timeout), |
| 29 | .mode = 0644, | 29 | .mode = 0644, |
| 30 | .proc_handler = proc_dointvec_jiffies, | 30 | .proc_handler = proc_dointvec_jiffies, |
| 31 | }, | 31 | }, |
| 32 | { | 32 | { |
| 33 | .procname = "p", | 33 | .procname = "p", |
| 34 | .data = &sysctl_llc2_p_timeout, | 34 | .data = &sysctl_llc2_p_timeout, |
| 35 | .maxlen = sizeof(long), | 35 | .maxlen = sizeof(sysctl_llc2_p_timeout), |
| 36 | .mode = 0644, | 36 | .mode = 0644, |
| 37 | .proc_handler = proc_dointvec_jiffies, | 37 | .proc_handler = proc_dointvec_jiffies, |
| 38 | }, | 38 | }, |
| 39 | { | 39 | { |
| 40 | .procname = "rej", | 40 | .procname = "rej", |
| 41 | .data = &sysctl_llc2_rej_timeout, | 41 | .data = &sysctl_llc2_rej_timeout, |
| 42 | .maxlen = sizeof(long), | 42 | .maxlen = sizeof(sysctl_llc2_rej_timeout), |
| 43 | .mode = 0644, | 43 | .mode = 0644, |
| 44 | .proc_handler = proc_dointvec_jiffies, | 44 | .proc_handler = proc_dointvec_jiffies, |
| 45 | }, | 45 | }, |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 4c5192e0d66c..4a95fe3cffbc 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
| @@ -86,20 +86,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
| 86 | } | 86 | } |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | /* tear down aggregation sessions and remove STAs */ | ||
| 90 | mutex_lock(&local->sta_mtx); | ||
| 91 | list_for_each_entry(sta, &local->sta_list, list) { | ||
| 92 | if (sta->uploaded) { | ||
| 93 | enum ieee80211_sta_state state; | ||
| 94 | |||
| 95 | state = sta->sta_state; | ||
| 96 | for (; state > IEEE80211_STA_NOTEXIST; state--) | ||
| 97 | WARN_ON(drv_sta_state(local, sta->sdata, sta, | ||
| 98 | state, state - 1)); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | mutex_unlock(&local->sta_mtx); | ||
| 102 | |||
| 103 | /* remove all interfaces that were created in the driver */ | 89 | /* remove all interfaces that were created in the driver */ |
| 104 | list_for_each_entry(sdata, &local->interfaces, list) { | 90 | list_for_each_entry(sdata, &local->interfaces, list) { |
| 105 | if (!ieee80211_sdata_running(sdata)) | 91 | if (!ieee80211_sdata_running(sdata)) |
| @@ -111,6 +97,21 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
| 111 | case NL80211_IFTYPE_STATION: | 97 | case NL80211_IFTYPE_STATION: |
| 112 | ieee80211_mgd_quiesce(sdata); | 98 | ieee80211_mgd_quiesce(sdata); |
| 113 | break; | 99 | break; |
| 100 | case NL80211_IFTYPE_WDS: | ||
| 101 | /* tear down aggregation sessions and remove STAs */ | ||
| 102 | mutex_lock(&local->sta_mtx); | ||
| 103 | sta = sdata->u.wds.sta; | ||
| 104 | if (sta && sta->uploaded) { | ||
| 105 | enum ieee80211_sta_state state; | ||
| 106 | |||
| 107 | state = sta->sta_state; | ||
| 108 | for (; state > IEEE80211_STA_NOTEXIST; state--) | ||
| 109 | WARN_ON(drv_sta_state(local, sta->sdata, | ||
| 110 | sta, state, | ||
| 111 | state - 1)); | ||
| 112 | } | ||
| 113 | mutex_unlock(&local->sta_mtx); | ||
| 114 | break; | ||
| 114 | default: | 115 | default: |
| 115 | break; | 116 | break; |
| 116 | } | 117 | } |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 683b10f46505..d69ca513848e 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -272,7 +272,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
| 272 | else if (rate && rate->flags & IEEE80211_RATE_ERP_G) | 272 | else if (rate && rate->flags & IEEE80211_RATE_ERP_G) |
| 273 | channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ; | 273 | channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ; |
| 274 | else if (rate) | 274 | else if (rate) |
| 275 | channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ; | 275 | channel_flags |= IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ; |
| 276 | else | 276 | else |
| 277 | channel_flags |= IEEE80211_CHAN_2GHZ; | 277 | channel_flags |= IEEE80211_CHAN_2GHZ; |
| 278 | put_unaligned_le16(channel_flags, pos); | 278 | put_unaligned_le16(channel_flags, pos); |
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index 84c8219c3e1c..f59adf8a4cd7 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c | |||
| @@ -180,6 +180,11 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp, | |||
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | bpf_size = bpf_len * sizeof(*bpf_ops); | 182 | bpf_size = bpf_len * sizeof(*bpf_ops); |
| 183 | if (bpf_size != nla_len(tb[TCA_BPF_OPS])) { | ||
| 184 | ret = -EINVAL; | ||
| 185 | goto errout; | ||
| 186 | } | ||
| 187 | |||
| 183 | bpf_ops = kzalloc(bpf_size, GFP_KERNEL); | 188 | bpf_ops = kzalloc(bpf_size, GFP_KERNEL); |
| 184 | if (bpf_ops == NULL) { | 189 | if (bpf_ops == NULL) { |
| 185 | ret = -ENOMEM; | 190 | ret = -ENOMEM; |
| @@ -215,15 +220,21 @@ static u32 cls_bpf_grab_new_handle(struct tcf_proto *tp, | |||
| 215 | struct cls_bpf_head *head) | 220 | struct cls_bpf_head *head) |
| 216 | { | 221 | { |
| 217 | unsigned int i = 0x80000000; | 222 | unsigned int i = 0x80000000; |
| 223 | u32 handle; | ||
| 218 | 224 | ||
| 219 | do { | 225 | do { |
| 220 | if (++head->hgen == 0x7FFFFFFF) | 226 | if (++head->hgen == 0x7FFFFFFF) |
| 221 | head->hgen = 1; | 227 | head->hgen = 1; |
| 222 | } while (--i > 0 && cls_bpf_get(tp, head->hgen)); | 228 | } while (--i > 0 && cls_bpf_get(tp, head->hgen)); |
| 223 | if (i == 0) | 229 | |
| 230 | if (unlikely(i == 0)) { | ||
| 224 | pr_err("Insufficient number of handles\n"); | 231 | pr_err("Insufficient number of handles\n"); |
| 232 | handle = 0; | ||
| 233 | } else { | ||
| 234 | handle = head->hgen; | ||
| 235 | } | ||
| 225 | 236 | ||
| 226 | return i; | 237 | return handle; |
| 227 | } | 238 | } |
| 228 | 239 | ||
| 229 | static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, | 240 | static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index f791edd64d6c..26d06dbcc1c8 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -1182,7 +1182,6 @@ void sctp_assoc_update(struct sctp_association *asoc, | |||
| 1182 | asoc->peer.peer_hmacs = new->peer.peer_hmacs; | 1182 | asoc->peer.peer_hmacs = new->peer.peer_hmacs; |
| 1183 | new->peer.peer_hmacs = NULL; | 1183 | new->peer.peer_hmacs = NULL; |
| 1184 | 1184 | ||
| 1185 | sctp_auth_key_put(asoc->asoc_shared_key); | ||
| 1186 | sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC); | 1185 | sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC); |
| 1187 | } | 1186 | } |
| 1188 | 1187 | ||
diff --git a/net/socket.c b/net/socket.c index a2c33a4dc7ba..418795caa897 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -869,9 +869,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, | |||
| 869 | static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb, | 869 | static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb, |
| 870 | struct sock_iocb *siocb) | 870 | struct sock_iocb *siocb) |
| 871 | { | 871 | { |
| 872 | if (!is_sync_kiocb(iocb)) | ||
| 873 | BUG(); | ||
| 874 | |||
| 875 | siocb->kiocb = iocb; | 872 | siocb->kiocb = iocb; |
| 876 | iocb->private = siocb; | 873 | iocb->private = siocb; |
| 877 | return siocb; | 874 | return siocb; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7ca4b5133123..8887c6e5fca8 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -2854,6 +2854,9 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) | |||
| 2854 | if (!rdev->ops->get_key) | 2854 | if (!rdev->ops->get_key) |
| 2855 | return -EOPNOTSUPP; | 2855 | return -EOPNOTSUPP; |
| 2856 | 2856 | ||
| 2857 | if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) | ||
| 2858 | return -ENOENT; | ||
| 2859 | |||
| 2857 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 2860 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
| 2858 | if (!msg) | 2861 | if (!msg) |
| 2859 | return -ENOMEM; | 2862 | return -ENOMEM; |
| @@ -2873,10 +2876,6 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) | |||
| 2873 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) | 2876 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) |
| 2874 | goto nla_put_failure; | 2877 | goto nla_put_failure; |
| 2875 | 2878 | ||
| 2876 | if (pairwise && mac_addr && | ||
| 2877 | !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) | ||
| 2878 | return -ENOENT; | ||
| 2879 | |||
| 2880 | err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie, | 2879 | err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie, |
| 2881 | get_key_callback); | 2880 | get_key_callback); |
| 2882 | 2881 | ||
| @@ -3047,7 +3046,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) | |||
| 3047 | wdev_lock(dev->ieee80211_ptr); | 3046 | wdev_lock(dev->ieee80211_ptr); |
| 3048 | err = nl80211_key_allowed(dev->ieee80211_ptr); | 3047 | err = nl80211_key_allowed(dev->ieee80211_ptr); |
| 3049 | 3048 | ||
| 3050 | if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr && | 3049 | if (key.type == NL80211_KEYTYPE_GROUP && mac_addr && |
| 3051 | !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) | 3050 | !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) |
| 3052 | err = -ENOENT; | 3051 | err = -ENOENT; |
| 3053 | 3052 | ||
diff --git a/net/wireless/util.c b/net/wireless/util.c index d0ac795445b7..5488c3662f7d 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
| @@ -308,6 +308,12 @@ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc) | |||
| 308 | goto out; | 308 | goto out; |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | if (ieee80211_is_mgmt(fc)) { | ||
| 312 | if (ieee80211_has_order(fc)) | ||
| 313 | hdrlen += IEEE80211_HT_CTL_LEN; | ||
| 314 | goto out; | ||
| 315 | } | ||
| 316 | |||
| 311 | if (ieee80211_is_ctl(fc)) { | 317 | if (ieee80211_is_ctl(fc)) { |
| 312 | /* | 318 | /* |
| 313 | * ACK and CTS are 10 bytes, all others 16. To see how | 319 | * ACK and CTS are 10 bytes, all others 16. To see how |
diff --git a/samples/bpf/test_maps.c b/samples/bpf/test_maps.c index e286b42307f3..6299ee95cd11 100644 --- a/samples/bpf/test_maps.c +++ b/samples/bpf/test_maps.c | |||
| @@ -69,9 +69,9 @@ static void test_hashmap_sanity(int i, void *data) | |||
| 69 | 69 | ||
| 70 | /* iterate over two elements */ | 70 | /* iterate over two elements */ |
| 71 | assert(bpf_get_next_key(map_fd, &key, &next_key) == 0 && | 71 | assert(bpf_get_next_key(map_fd, &key, &next_key) == 0 && |
| 72 | next_key == 2); | 72 | (next_key == 1 || next_key == 2)); |
| 73 | assert(bpf_get_next_key(map_fd, &next_key, &next_key) == 0 && | 73 | assert(bpf_get_next_key(map_fd, &next_key, &next_key) == 0 && |
| 74 | next_key == 1); | 74 | (next_key == 1 || next_key == 2)); |
| 75 | assert(bpf_get_next_key(map_fd, &next_key, &next_key) == -1 && | 75 | assert(bpf_get_next_key(map_fd, &next_key, &next_key) == -1 && |
| 76 | errno == ENOENT); | 76 | errno == ENOENT); |
| 77 | 77 | ||
