summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic/qla3xxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/qlogic/qla3xxx.c')
-rw-r--r--drivers/net/ethernet/qlogic/qla3xxx.c60
1 files changed, 32 insertions, 28 deletions
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index 5c100ab86c00..2991179c2fd0 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -1707,23 +1707,30 @@ static int ql_get_full_dup(struct ql3_adapter *qdev)
return status;
}
-static int ql_get_settings(struct net_device *ndev, struct ethtool_cmd *ecmd)
+static int ql_get_link_ksettings(struct net_device *ndev,
+ struct ethtool_link_ksettings *cmd)
{
struct ql3_adapter *qdev = netdev_priv(ndev);
+ u32 supported, advertising;
- ecmd->transceiver = XCVR_INTERNAL;
- ecmd->supported = ql_supported_modes(qdev);
+ supported = ql_supported_modes(qdev);
if (test_bit(QL_LINK_OPTICAL, &qdev->flags)) {
- ecmd->port = PORT_FIBRE;
+ cmd->base.port = PORT_FIBRE;
} else {
- ecmd->port = PORT_TP;
- ecmd->phy_address = qdev->PHYAddr;
+ cmd->base.port = PORT_TP;
+ cmd->base.phy_address = qdev->PHYAddr;
}
- ecmd->advertising = ql_supported_modes(qdev);
- ecmd->autoneg = ql_get_auto_cfg_status(qdev);
- ethtool_cmd_speed_set(ecmd, ql_get_speed(qdev));
- ecmd->duplex = ql_get_full_dup(qdev);
+ advertising = ql_supported_modes(qdev);
+ cmd->base.autoneg = ql_get_auto_cfg_status(qdev);
+ cmd->base.speed = ql_get_speed(qdev);
+ cmd->base.duplex = ql_get_full_dup(qdev);
+
+ ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
+ supported);
+ ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
+ advertising);
+
return 0;
}
@@ -1769,12 +1776,12 @@ static void ql_get_pauseparam(struct net_device *ndev,
}
static const struct ethtool_ops ql3xxx_ethtool_ops = {
- .get_settings = ql_get_settings,
.get_drvinfo = ql_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_msglevel = ql_get_msglevel,
.set_msglevel = ql_set_msglevel,
.get_pauseparam = ql_get_pauseparam,
+ .get_link_ksettings = ql_get_link_ksettings,
};
static int ql_populate_free_queue(struct ql3_adapter *qdev)
@@ -2025,7 +2032,7 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev,
skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, qdev->ndev);
- netif_receive_skb(skb);
+ napi_gro_receive(&qdev->napi, skb);
lrg_buf_cb2->skb = NULL;
if (qdev->device_id == QL3022_DEVICE_ID)
@@ -2095,7 +2102,7 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev,
}
skb2->protocol = eth_type_trans(skb2, qdev->ndev);
- netif_receive_skb(skb2);
+ napi_gro_receive(&qdev->napi, skb2);
ndev->stats.rx_packets++;
ndev->stats.rx_bytes += length;
lrg_buf_cb2->skb = NULL;
@@ -2105,8 +2112,7 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev,
ql_release_to_lrg_buf_free_list(qdev, lrg_buf_cb2);
}
-static int ql_tx_rx_clean(struct ql3_adapter *qdev,
- int *tx_cleaned, int *rx_cleaned, int work_to_do)
+static int ql_tx_rx_clean(struct ql3_adapter *qdev, int budget)
{
struct net_rsp_iocb *net_rsp;
struct net_device *ndev = qdev->ndev;
@@ -2114,7 +2120,7 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev,
/* While there are entries in the completion queue. */
while ((le32_to_cpu(*(qdev->prsp_producer_index)) !=
- qdev->rsp_consumer_index) && (work_done < work_to_do)) {
+ qdev->rsp_consumer_index) && (work_done < budget)) {
net_rsp = qdev->rsp_current;
rmb();
@@ -2130,21 +2136,20 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev,
case OPCODE_OB_MAC_IOCB_FN2:
ql_process_mac_tx_intr(qdev, (struct ob_mac_iocb_rsp *)
net_rsp);
- (*tx_cleaned)++;
break;
case OPCODE_IB_MAC_IOCB:
case OPCODE_IB_3032_MAC_IOCB:
ql_process_mac_rx_intr(qdev, (struct ib_mac_iocb_rsp *)
net_rsp);
- (*rx_cleaned)++;
+ work_done++;
break;
case OPCODE_IB_IP_IOCB:
case OPCODE_IB_3032_IP_IOCB:
ql_process_macip_rx_intr(qdev, (struct ib_ip_iocb_rsp *)
net_rsp);
- (*rx_cleaned)++;
+ work_done++;
break;
default: {
u32 *tmp = (u32 *)net_rsp;
@@ -2169,7 +2174,6 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev,
qdev->rsp_current++;
}
- work_done = *tx_cleaned + *rx_cleaned;
}
return work_done;
@@ -2178,25 +2182,25 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev,
static int ql_poll(struct napi_struct *napi, int budget)
{
struct ql3_adapter *qdev = container_of(napi, struct ql3_adapter, napi);
- int rx_cleaned = 0, tx_cleaned = 0;
- unsigned long hw_flags;
struct ql3xxx_port_registers __iomem *port_regs =
qdev->mem_map_registers;
+ int work_done;
- ql_tx_rx_clean(qdev, &tx_cleaned, &rx_cleaned, budget);
+ work_done = ql_tx_rx_clean(qdev, budget);
- if (tx_cleaned + rx_cleaned != budget) {
- spin_lock_irqsave(&qdev->hw_lock, hw_flags);
- __napi_complete(napi);
+ if (work_done < budget && napi_complete_done(napi, work_done)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&qdev->hw_lock, flags);
ql_update_small_bufq_prod_index(qdev);
ql_update_lrg_bufq_prod_index(qdev);
writel(qdev->rsp_consumer_index,
&port_regs->CommonRegs.rspQConsumerIndex);
- spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
+ spin_unlock_irqrestore(&qdev->hw_lock, flags);
ql_enable_interrupts(qdev);
}
- return tx_cleaned + rx_cleaned;
+ return work_done;
}
static irqreturn_t ql3xxx_isr(int irq, void *dev_id)