diff options
Diffstat (limited to 'drivers/net/usb/r8152.c')
-rw-r--r-- | drivers/net/usb/r8152.c | 151 |
1 files changed, 79 insertions, 72 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 87f71047621..f95e678cb69 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -424,7 +424,7 @@ enum rtl_register_content { FULL_DUP = 0x01, }; -#define RTL8152_MAX_TX 10 +#define RTL8152_MAX_TX 4 #define RTL8152_MAX_RX 10 #define INTBUFSIZE 2 #define CRC_SIZE 4 @@ -607,9 +607,9 @@ enum tx_csum_stat { * The RTL chips use a 64 element hash table based on the Ethernet CRC. */ static const int multicast_filter_limit = 32; -static unsigned int rx_buf_sz = 16384; +static unsigned int agg_buf_sz = 16384; -#define RTL_LIMITED_TSO_SIZE (rx_buf_sz - sizeof(struct tx_desc) - \ +#define RTL_LIMITED_TSO_SIZE (agg_buf_sz - sizeof(struct tx_desc) - \ VLAN_ETH_HLEN - VLAN_HLEN) static @@ -623,8 +623,8 @@ int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) return -ENOMEM; ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), - RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, - value, index, tmp, size, 500); + RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, + value, index, tmp, size, 500); memcpy(data, tmp, size); kfree(tmp); @@ -643,8 +643,8 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) return -ENOMEM; ret = usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), - RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, - value, index, tmp, size, 500); + RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, + value, index, tmp, size, 500); kfree(tmp); @@ -652,7 +652,7 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) } static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, - void *data, u16 type) + void *data, u16 type) { u16 limit = 64; int ret = 0; @@ -692,7 +692,7 @@ static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, } static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, - u16 size, void *data, u16 type) + u16 size, void *data, u16 type) { int ret; u16 byteen_start, byteen_end, byen; @@ -726,8 +726,8 @@ static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, while (size) { if (size > limit) { ret = set_registers(tp, index, - type | BYTE_EN_DWORD, - limit, data); + type | BYTE_EN_DWORD, + limit, data); if (ret < 0) goto error1; @@ -736,8 +736,8 @@ static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, size -= limit; } else { ret = set_registers(tp, index, - type | BYTE_EN_DWORD, - size, data); + type | BYTE_EN_DWORD, + size, data); if (ret < 0) goto error1; @@ -972,36 +972,8 @@ void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val) usb_autopm_put_interface(tp->intf); } -static -int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags); - -static inline void set_ethernet_addr(struct r8152 *tp) -{ - struct net_device *dev = tp->netdev; - int ret; - u8 node_id[8] = {0}; - - if (tp->version == RTL_VER_01) - ret = pla_ocp_read(tp, PLA_IDR, sizeof(node_id), node_id); - else - ret = pla_ocp_read(tp, PLA_BACKUP, sizeof(node_id), node_id); - - if (ret < 0) { - netif_notice(tp, probe, dev, "inet addr fail\n"); - } else { - if (tp->version != RTL_VER_01) { - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, - CRWECR_CONFIG); - pla_ocp_write(tp, PLA_IDR, BYTE_EN_SIX_BYTES, - sizeof(node_id), node_id); - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, - CRWECR_NORAML); - } - - memcpy(dev->dev_addr, node_id, dev->addr_len); - memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - } -} +static int +r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags); static int rtl8152_set_mac_address(struct net_device *netdev, void *p) { @@ -1020,6 +992,37 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p) return 0; } +static int set_ethernet_addr(struct r8152 *tp) +{ + struct net_device *dev = tp->netdev; + struct sockaddr sa; + int ret; + + if (tp->version == RTL_VER_01) + ret = pla_ocp_read(tp, PLA_IDR, 8, sa.sa_data); + else + ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa.sa_data); + + if (ret < 0) { + netif_err(tp, probe, dev, "Get ether addr fail\n"); + } else if (!is_valid_ether_addr(sa.sa_data)) { + netif_err(tp, probe, dev, "Invalid ether addr %pM\n", + sa.sa_data); + eth_hw_addr_random(dev); + ether_addr_copy(sa.sa_data, dev->dev_addr); + ret = rtl8152_set_mac_address(dev, &sa); + netif_info(tp, probe, dev, "Random ether addr %pM\n", + sa.sa_data); + } else { + if (tp->version == RTL_VER_01) + ether_addr_copy(dev->dev_addr, sa.sa_data); + else + ret = rtl8152_set_mac_address(dev, &sa); + } + + return ret; +} + static void read_bulk_callback(struct urb *urb) { struct net_device *netdev; @@ -1248,13 +1251,13 @@ static int alloc_all_mem(struct r8152 *tp) skb_queue_head_init(&tp->tx_queue); for (i = 0; i < RTL8152_MAX_RX; i++) { - buf = kmalloc_node(rx_buf_sz, GFP_KERNEL, node); + buf = kmalloc_node(agg_buf_sz, GFP_KERNEL, node); if (!buf) goto err1; if (buf != rx_agg_align(buf)) { kfree(buf); - buf = kmalloc_node(rx_buf_sz + RX_ALIGN, GFP_KERNEL, + buf = kmalloc_node(agg_buf_sz + RX_ALIGN, GFP_KERNEL, node); if (!buf) goto err1; @@ -1274,13 +1277,13 @@ static int alloc_all_mem(struct r8152 *tp) } for (i = 0; i < RTL8152_MAX_TX; i++) { - buf = kmalloc_node(rx_buf_sz, GFP_KERNEL, node); + buf = kmalloc_node(agg_buf_sz, GFP_KERNEL, node); if (!buf) goto err1; if (buf != tx_agg_align(buf)) { kfree(buf); - buf = kmalloc_node(rx_buf_sz + TX_ALIGN, GFP_KERNEL, + buf = kmalloc_node(agg_buf_sz + TX_ALIGN, GFP_KERNEL, node); if (!buf) goto err1; @@ -1311,8 +1314,8 @@ static int alloc_all_mem(struct r8152 *tp) tp->intr_interval = (int)ep_intr->desc.bInterval; usb_fill_int_urb(tp->intr_urb, tp->udev, usb_rcvintpipe(tp->udev, 3), - tp->intr_buff, INTBUFSIZE, intr_callback, - tp, tp->intr_interval); + tp->intr_buff, INTBUFSIZE, intr_callback, + tp, tp->intr_interval); return 0; @@ -1354,8 +1357,7 @@ static inline __be16 get_protocol(struct sk_buff *skb) return protocol; } -/* - * r8152_csum_workaround() +/* r8152_csum_workaround() * The hw limites the value the transport offset. When the offset is out of the * range, calculate the checksum by sw. */ @@ -1398,8 +1400,7 @@ drop: } } -/* - * msdn_giant_send_check() +/* msdn_giant_send_check() * According to the document of microsoft, the TCP Pseudo Header excludes the * packet length for IPv6 TCP large packets. */ @@ -1518,8 +1519,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) spin_unlock(&tx_queue->lock); tx_data = agg->head; - agg->skb_num = agg->skb_len = 0; - remain = rx_buf_sz; + agg->skb_num = 0; + agg->skb_len = 0; + remain = agg_buf_sz; while (remain >= ETH_ZLEN + sizeof(struct tx_desc)) { struct tx_desc *tx_desc; @@ -1566,7 +1568,7 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) dev_kfree_skb_any(skb); - remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head); + remain = agg_buf_sz - (int)(tx_agg_align(tx_data) - agg->head); } if (!skb_queue_empty(&skb_head)) { @@ -1772,8 +1774,8 @@ static int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) { usb_fill_bulk_urb(agg->urb, tp->udev, usb_rcvbulkpipe(tp->udev, 1), - agg->head, rx_buf_sz, - (usb_complete_t)read_bulk_callback, agg); + agg->head, agg_buf_sz, + (usb_complete_t)read_bulk_callback, agg); return usb_submit_urb(agg->urb, mem_flags); } @@ -1835,18 +1837,22 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) /* Unconditionally log net taps. */ netif_notice(tp, link, netdev, "Promiscuous mode enabled\n"); ocp_data |= RCR_AM | RCR_AAP; - mc_filter[1] = mc_filter[0] = 0xffffffff; + mc_filter[1] = 0xffffffff; + mc_filter[0] = 0xffffffff; } else if ((netdev_mc_count(netdev) > multicast_filter_limit) || (netdev->flags & IFF_ALLMULTI)) { /* Too many to filter perfectly -- accept all multicasts. */ ocp_data |= RCR_AM; - mc_filter[1] = mc_filter[0] = 0xffffffff; + mc_filter[1] = 0xffffffff; + mc_filter[0] = 0xffffffff; } else { struct netdev_hw_addr *ha; - mc_filter[1] = mc_filter[0] = 0; + mc_filter[1] = 0; + mc_filter[0] = 0; netdev_for_each_mc_addr(ha, netdev) { int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; + mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); ocp_data |= RCR_AM; } @@ -1861,7 +1867,7 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) } static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, - struct net_device *netdev) + struct net_device *netdev) { struct r8152 *tp = netdev_priv(netdev); @@ -1877,8 +1883,9 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, usb_mark_last_busy(tp->udev); tasklet_schedule(&tp->tl); } - } else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen) + } else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen) { netif_stop_queue(netdev); + } return NETDEV_TX_OK; } @@ -1903,7 +1910,7 @@ static void rtl8152_nic_reset(struct r8152 *tp) for (i = 0; i < 1000; i++) { if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST)) break; - udelay(100); + usleep_range(100, 400); } } @@ -1911,8 +1918,8 @@ static void set_tx_qlen(struct r8152 *tp) { struct net_device *netdev = tp->netdev; - tp->tx_qlen = rx_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + VLAN_HLEN + - sizeof(struct tx_desc)); + tp->tx_qlen = agg_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + VLAN_HLEN + + sizeof(struct tx_desc)); } static inline u8 rtl8152_get_speed(struct r8152 *tp) @@ -2861,8 +2868,7 @@ static int rtl8152_close(struct net_device *netdev) if (res < 0) { rtl_drop_queued_tx(tp); } else { - /* - * The autosuspend may have been enabled and wouldn't + /* The autosuspend may have been enabled and wouldn't * be disable when autoresume occurs, because the * netif_running() would be false. */ @@ -3085,8 +3091,9 @@ static int rtl8152_resume(struct usb_interface *intf) } else { tp->rtl_ops.up(tp); rtl8152_set_speed(tp, AUTONEG_ENABLE, - tp->mii.supports_gmii ? SPEED_1000 : SPEED_100, - DUPLEX_FULL); + tp->mii.supports_gmii ? + SPEED_1000 : SPEED_100, + DUPLEX_FULL); } tp->speed = 0; netif_carrier_off(tp->netdev); @@ -3147,8 +3154,8 @@ static void rtl8152_get_drvinfo(struct net_device *netdev, { struct r8152 *tp = netdev_priv(netdev); - strncpy(info->driver, MODULENAME, ETHTOOL_BUSINFO_LEN); - strncpy(info->version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN); + strlcpy(info->driver, MODULENAME, sizeof(info->driver)); + strlcpy(info->version, DRIVER_VERSION, sizeof(info->version)); usb_make_path(tp->udev, info->bus_info, sizeof(info->bus_info)); } |