diff options
Diffstat (limited to 'drivers/net/ethernet/microchip/lan743x_main.c')
-rw-r--r-- | drivers/net/ethernet/microchip/lan743x_main.c | 120 |
1 files changed, 48 insertions, 72 deletions
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c index b319c22c211c..3804310c853a 100644 --- a/drivers/net/ethernet/microchip/lan743x_main.c +++ b/drivers/net/ethernet/microchip/lan743x_main.c @@ -140,18 +140,14 @@ clean_up: return result; } -static void lan743x_intr_software_isr(void *context) +static void lan743x_intr_software_isr(struct lan743x_adapter *adapter) { - struct lan743x_adapter *adapter = context; struct lan743x_intr *intr = &adapter->intr; - u32 int_sts; - int_sts = lan743x_csr_read(adapter, INT_STS); - if (int_sts & INT_BIT_SW_GP_) { - /* disable the interrupt to prevent repeated re-triggering */ - lan743x_csr_write(adapter, INT_EN_CLR, INT_BIT_SW_GP_); - intr->software_isr_flag = 1; - } + /* disable the interrupt to prevent repeated re-triggering */ + lan743x_csr_write(adapter, INT_EN_CLR, INT_BIT_SW_GP_); + intr->software_isr_flag = true; + wake_up(&intr->software_isr_wq); } static void lan743x_tx_isr(void *context, u32 int_sts, u32 flags) @@ -348,27 +344,22 @@ irq_done: static int lan743x_intr_test_isr(struct lan743x_adapter *adapter) { struct lan743x_intr *intr = &adapter->intr; - int result = -ENODEV; - int timeout = 10; + int ret; - intr->software_isr_flag = 0; + intr->software_isr_flag = false; - /* enable interrupt */ + /* enable and activate test interrupt */ lan743x_csr_write(adapter, INT_EN_SET, INT_BIT_SW_GP_); - - /* activate interrupt here */ lan743x_csr_write(adapter, INT_SET, INT_BIT_SW_GP_); - while ((timeout > 0) && (!(intr->software_isr_flag))) { - usleep_range(1000, 20000); - timeout--; - } - if (intr->software_isr_flag) - result = 0; + ret = wait_event_timeout(intr->software_isr_wq, + intr->software_isr_flag, + msecs_to_jiffies(200)); - /* disable interrupts */ + /* disable test interrupt */ lan743x_csr_write(adapter, INT_EN_CLR, INT_BIT_SW_GP_); - return result; + + return ret > 0 ? 0 : -ENODEV; } static int lan743x_intr_register_isr(struct lan743x_adapter *adapter, @@ -542,6 +533,8 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) flags |= LAN743X_VECTOR_FLAG_SOURCE_ENABLE_R2C; } + init_waitqueue_head(&intr->software_isr_wq); + ret = lan743x_intr_register_isr(adapter, 0, flags, INT_BIT_ALL_RX_ | INT_BIT_ALL_TX_ | INT_BIT_ALL_OTHER_, @@ -830,14 +823,13 @@ static int lan743x_mac_init(struct lan743x_adapter *adapter) static int lan743x_mac_open(struct lan743x_adapter *adapter) { - int ret = 0; u32 temp; temp = lan743x_csr_read(adapter, MAC_RX); lan743x_csr_write(adapter, MAC_RX, temp | MAC_RX_RXEN_); temp = lan743x_csr_read(adapter, MAC_TX); lan743x_csr_write(adapter, MAC_TX, temp | MAC_TX_TXEN_); - return ret; + return 0; } static void lan743x_mac_close(struct lan743x_adapter *adapter) @@ -958,7 +950,7 @@ static void lan743x_phy_link_status_change(struct net_device *netdev) data = lan743x_csr_read(adapter, MAC_CR); /* set interface mode */ - if (phy_interface_mode_is_rgmii(adapter->phy_mode)) + if (phy_interface_is_rgmii(phydev)) /* RGMII */ data &= ~MAC_CR_MII_EN_; else @@ -1014,33 +1006,14 @@ static void lan743x_phy_close(struct lan743x_adapter *adapter) static int lan743x_phy_open(struct lan743x_adapter *adapter) { + struct net_device *netdev = adapter->netdev; struct lan743x_phy *phy = &adapter->phy; - struct phy_device *phydev = NULL; - struct device_node *phynode; - struct net_device *netdev; + struct phy_device *phydev; int ret = -EIO; - netdev = adapter->netdev; - phynode = of_node_get(adapter->pdev->dev.of_node); - - if (phynode) { - /* try devicetree phy, or fixed link */ - of_get_phy_mode(phynode, &adapter->phy_mode); - - if (of_phy_is_fixed_link(phynode)) { - ret = of_phy_register_fixed_link(phynode); - if (ret) { - netdev_err(netdev, - "cannot register fixed PHY\n"); - of_node_put(phynode); - goto return_error; - } - } - phydev = of_phy_connect(netdev, phynode, - lan743x_phy_link_status_change, 0, - adapter->phy_mode); - of_node_put(phynode); - } + /* try devicetree phy, or fixed link */ + phydev = of_phy_get_and_connect(netdev, adapter->pdev->dev.of_node, + lan743x_phy_link_status_change); if (!phydev) { /* try internal phy */ @@ -1048,10 +1021,9 @@ static int lan743x_phy_open(struct lan743x_adapter *adapter) if (!phydev) goto return_error; - adapter->phy_mode = PHY_INTERFACE_MODE_GMII; ret = phy_connect_direct(netdev, phydev, lan743x_phy_link_status_change, - adapter->phy_mode); + PHY_INTERFACE_MODE_GMII); if (ret) goto return_error; } @@ -1066,6 +1038,7 @@ static int lan743x_phy_open(struct lan743x_adapter *adapter) phy_start(phydev); phy_start_aneg(phydev); + phy_attached_info(phydev); return 0; return_error: @@ -1962,6 +1935,14 @@ static struct sk_buff *lan743x_rx_allocate_skb(struct lan743x_rx *rx) length, GFP_ATOMIC | GFP_DMA); } +static void lan743x_rx_update_tail(struct lan743x_rx *rx, int index) +{ + /* update the tail once per 8 descriptors */ + if ((index & 7) == 7) + lan743x_csr_write(rx->adapter, RX_TAIL(rx->channel_number), + index); +} + static int lan743x_rx_init_ring_element(struct lan743x_rx *rx, int index, struct sk_buff *skb) { @@ -1992,6 +1973,7 @@ static int lan743x_rx_init_ring_element(struct lan743x_rx *rx, int index, descriptor->data0 = (RX_DESC_DATA0_OWN_ | (length & RX_DESC_DATA0_BUF_LENGTH_MASK_)); skb_reserve(buffer_info->skb, RX_HEAD_PADDING); + lan743x_rx_update_tail(rx, index); return 0; } @@ -2010,6 +1992,7 @@ static void lan743x_rx_reuse_ring_element(struct lan743x_rx *rx, int index) descriptor->data0 = (RX_DESC_DATA0_OWN_ | ((buffer_info->buffer_length) & RX_DESC_DATA0_BUF_LENGTH_MASK_)); + lan743x_rx_update_tail(rx, index); } static void lan743x_rx_release_ring_element(struct lan743x_rx *rx, int index) @@ -2220,6 +2203,7 @@ static int lan743x_rx_napi_poll(struct napi_struct *napi, int weight) { struct lan743x_rx *rx = container_of(napi, struct lan743x_rx, napi); struct lan743x_adapter *adapter = rx->adapter; + int result = RX_PROCESS_RESULT_NOTHING_TO_DO; u32 rx_tail_flags = 0; int count; @@ -2228,27 +2212,19 @@ static int lan743x_rx_napi_poll(struct napi_struct *napi, int weight) lan743x_csr_write(adapter, DMAC_INT_STS, DMAC_INT_BIT_RXFRM_(rx->channel_number)); } - count = 0; - while (count < weight) { - int rx_process_result = lan743x_rx_process_packet(rx); - - if (rx_process_result == RX_PROCESS_RESULT_PACKET_RECEIVED) { - count++; - } else if (rx_process_result == - RX_PROCESS_RESULT_NOTHING_TO_DO) { + for (count = 0; count < weight; count++) { + result = lan743x_rx_process_packet(rx); + if (result == RX_PROCESS_RESULT_NOTHING_TO_DO) break; - } else if (rx_process_result == - RX_PROCESS_RESULT_PACKET_DROPPED) { - continue; - } } rx->frame_count += count; - if (count == weight) - goto done; + if (count == weight || result == RX_PROCESS_RESULT_PACKET_RECEIVED) + return weight; if (!napi_complete_done(napi, count)) - goto done; + return count; + /* re-arm interrupts, must write to rx tail on some chip variants */ if (rx->vector_flags & LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_SET) rx_tail_flags |= RX_TAIL_SET_TOP_INT_VEC_EN_; if (rx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_SET) { @@ -2258,10 +2234,10 @@ static int lan743x_rx_napi_poll(struct napi_struct *napi, int weight) INT_BIT_DMA_RX_(rx->channel_number)); } - /* update RX_TAIL */ - lan743x_csr_write(adapter, RX_TAIL(rx->channel_number), - rx_tail_flags | rx->last_tail); -done: + if (rx_tail_flags) + lan743x_csr_write(adapter, RX_TAIL(rx->channel_number), + rx_tail_flags | rx->last_tail); + return count; } @@ -2405,7 +2381,7 @@ static int lan743x_rx_open(struct lan743x_rx *rx) netif_napi_add(adapter->netdev, &rx->napi, lan743x_rx_napi_poll, - rx->ring_size - 1); + NAPI_POLL_WEIGHT); lan743x_csr_write(adapter, DMAC_CMD, DMAC_CMD_RX_SWR_(rx->channel_number)); |