|
@@ -369,7 +369,7 @@ static int xemaclite_send_data(struct net_local *drvdata, u8 *data,
|
|
|
*
|
|
|
* Return: Total number of bytes received
|
|
|
*/
|
|
|
-static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
|
|
|
+static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data, int maxlen)
|
|
|
{
|
|
|
void __iomem *addr;
|
|
|
u16 length, proto_type;
|
|
@@ -409,7 +409,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
|
|
|
|
|
|
/* Check if received ethernet frame is a raw ethernet frame
|
|
|
* or an IP packet or an ARP packet */
|
|
|
- if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
|
|
|
+ if (proto_type > ETH_DATA_LEN) {
|
|
|
|
|
|
if (proto_type == ETH_P_IP) {
|
|
|
length = ((ntohl(__raw_readl(addr +
|
|
@@ -417,6 +417,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
|
|
|
XEL_RXBUFF_OFFSET)) >>
|
|
|
XEL_HEADER_SHIFT) &
|
|
|
XEL_RPLR_LENGTH_MASK);
|
|
|
+ length = min_t(u16, length, ETH_DATA_LEN);
|
|
|
length += ETH_HLEN + ETH_FCS_LEN;
|
|
|
|
|
|
} else if (proto_type == ETH_P_ARP)
|
|
@@ -429,6 +430,9 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
|
|
|
/* Use the length in the frame, plus the header and trailer */
|
|
|
length = proto_type + ETH_HLEN + ETH_FCS_LEN;
|
|
|
|
|
|
+ if (WARN_ON(length > maxlen))
|
|
|
+ length = maxlen;
|
|
|
+
|
|
|
/* Read from the EmacLite device */
|
|
|
xemaclite_aligned_read((u32 __force *) (addr + XEL_RXBUFF_OFFSET),
|
|
|
data, length);
|
|
@@ -603,7 +607,7 @@ static void xemaclite_rx_handler(struct net_device *dev)
|
|
|
|
|
|
skb_reserve(skb, 2);
|
|
|
|
|
|
- len = xemaclite_recv_data(lp, (u8 *) skb->data);
|
|
|
+ len = xemaclite_recv_data(lp, (u8 *) skb->data, len);
|
|
|
|
|
|
if (!len) {
|
|
|
dev->stats.rx_errors++;
|