mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-29 07:34:06 +08:00
Merge branch 'SMSC95xx-driver-updates'
Ben Dooks says: ==================== SMSC95xx driver updates (round 1) This is a series of a few driver cleanups and some fixups of the code for the SMSC95XX driver. There have been a few reviews, and the issues have been fixed so this should be ready for merging. I will work on the tx-alignment and the other bits of usbnet changes and produce at least two more patch series for this later. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
e119a369b0
@ -618,9 +618,7 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&intdata, urb->transfer_buffer, 4);
|
||||
le32_to_cpus(&intdata);
|
||||
|
||||
intdata = get_unaligned_le32(urb->transfer_buffer);
|
||||
netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata);
|
||||
|
||||
if (intdata & INT_ENP_PHY_INT_)
|
||||
@ -1295,6 +1293,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||
dev->net->features |= NETIF_F_RXCSUM;
|
||||
|
||||
dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
|
||||
set_bit(EVENT_NO_IP_ALIGN, &dev->flags);
|
||||
|
||||
smsc95xx_init_mac_address(dev);
|
||||
|
||||
@ -1933,8 +1932,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
||||
unsigned char *packet;
|
||||
u16 size;
|
||||
|
||||
memcpy(&header, skb->data, sizeof(header));
|
||||
le32_to_cpus(&header);
|
||||
header = get_unaligned_le32(skb->data);
|
||||
skb_pull(skb, 4 + NET_IP_ALIGN);
|
||||
packet = skb->data;
|
||||
|
||||
@ -2011,12 +2009,30 @@ static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb)
|
||||
return (high_16 << 16) | low_16;
|
||||
}
|
||||
|
||||
/* The TX CSUM won't work if the checksum lies in the last 4 bytes of the
|
||||
* transmission. This is fairly unlikely, only seems to trigger with some
|
||||
* short TCP ACK packets sent.
|
||||
*
|
||||
* Note, this calculation should probably check for the alignment of the
|
||||
* data as well, but a straight check for csum being in the last four bytes
|
||||
* of the packet should be ok for now.
|
||||
*/
|
||||
static bool smsc95xx_can_tx_checksum(struct sk_buff *skb)
|
||||
{
|
||||
unsigned int len = skb->len - skb_checksum_start_offset(skb);
|
||||
|
||||
if (skb->len <= 45)
|
||||
return false;
|
||||
return skb->csum_offset < (len - (4 + 1));
|
||||
}
|
||||
|
||||
static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
|
||||
struct sk_buff *skb, gfp_t flags)
|
||||
{
|
||||
bool csum = skb->ip_summed == CHECKSUM_PARTIAL;
|
||||
int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD;
|
||||
u32 tx_cmd_a, tx_cmd_b;
|
||||
void *ptr;
|
||||
|
||||
/* We do not advertise SG, so skbs should be already linearized */
|
||||
BUG_ON(skb_shinfo(skb)->nr_frags);
|
||||
@ -2030,8 +2046,11 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tx_cmd_b = (u32)skb->len;
|
||||
tx_cmd_a = tx_cmd_b | TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_;
|
||||
|
||||
if (csum) {
|
||||
if (skb->len <= 45) {
|
||||
if (!smsc95xx_can_tx_checksum(skb)) {
|
||||
/* workaround - hardware tx checksum does not work
|
||||
* properly with extremely small packets */
|
||||
long csstart = skb_checksum_start_offset(skb);
|
||||
@ -2043,24 +2062,18 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
|
||||
csum = false;
|
||||
} else {
|
||||
u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
|
||||
skb_push(skb, 4);
|
||||
cpu_to_le32s(&csum_preamble);
|
||||
memcpy(skb->data, &csum_preamble, 4);
|
||||
ptr = skb_push(skb, 4);
|
||||
put_unaligned_le32(csum_preamble, ptr);
|
||||
|
||||
tx_cmd_a += 4;
|
||||
tx_cmd_b += 4;
|
||||
tx_cmd_b |= TX_CMD_B_CSUM_ENABLE;
|
||||
}
|
||||
}
|
||||
|
||||
skb_push(skb, 4);
|
||||
tx_cmd_b = (u32)(skb->len - 4);
|
||||
if (csum)
|
||||
tx_cmd_b |= TX_CMD_B_CSUM_ENABLE;
|
||||
cpu_to_le32s(&tx_cmd_b);
|
||||
memcpy(skb->data, &tx_cmd_b, 4);
|
||||
|
||||
skb_push(skb, 4);
|
||||
tx_cmd_a = (u32)(skb->len - 8) | TX_CMD_A_FIRST_SEG_ |
|
||||
TX_CMD_A_LAST_SEG_;
|
||||
cpu_to_le32s(&tx_cmd_a);
|
||||
memcpy(skb->data, &tx_cmd_a, 4);
|
||||
ptr = skb_push(skb, 8);
|
||||
put_unaligned_le32(tx_cmd_a, ptr);
|
||||
put_unaligned_le32(tx_cmd_b, ptr+4);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user