patch-2.1.40 linux/drivers/net/ibmtr.c
Next file: linux/drivers/pci/pci.c
Previous file: linux/drivers/net/hp100.h
Back to the patch index
Back to the overall index
- Lines: 102
- Date:
Sun May 18 16:38:34 1997
- Orig file:
v2.1.39/linux/drivers/net/ibmtr.c
- Orig date:
Tue May 13 22:41:09 1997
diff -u --recursive --new-file v2.1.39/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
@@ -84,7 +84,7 @@
/* version and credits */
static char *version =
"ibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n"
-" v2.1.29 3/15/97 Paul Norton <pnorton@cts.com>\n";
+" v2.1.35 5/ 1/97 Paul Norton <pnorton@cts.com>\n";
static char pcchannelid[] = {
0x05, 0x00, 0x04, 0x09,
@@ -1013,14 +1013,15 @@
} /* ARB response */
if (status & SSB_RESP_INT) { /* SSB response */
-
+ unsigned char retcode;
switch (readb(ti->ssb)) { /* SSB command check */
-
+
case XMIT_DIR_FRAME:
case XMIT_UI_FRAME:
- if (readb(ti->ssb+2)) /* checks ret_code */
+ retcode = readb(ti->ssb+2);
+ if (retcode && (retcode != 0x22)) /* checks ret_code */
DPRINTK("xmit ret_code: %02X xmit error code: %02X\n",
- (int)readb(ti->ssb+2), (int)readb(ti->ssb+6));
+ (int)retcode, (int)readb(ti->ssb+6));
else ti->tr_stats.tx_packets++;
break;
@@ -1321,12 +1322,12 @@
__u32 rbuffer, rbufdata;
__u32 llc;
unsigned char *data;
- unsigned int rbuffer_len, lan_hdr_len, hdr_len;
- unsigned int arb_frame_len;
+ unsigned int rbuffer_len, lan_hdr_len, hdr_len, ip_len, length;
struct sk_buff *skb;
unsigned int skb_size = 0;
int is8022 = 0;
unsigned int chksum = 0;
+ struct iphdr *iph;
rbuffer=(ti->sram
+ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))))+2;
@@ -1400,8 +1401,8 @@
}
#endif
- arb_frame_len=ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len)));
- skb_size = arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr);
+ length = ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len)));
+ skb_size = length-lan_hdr_len+sizeof(struct trh_hdr);
if (is8022) {
skb_size += sizeof(struct trllc);
}
@@ -1429,30 +1430,42 @@
rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)))-lan_hdr_len;
if (is8022) {
- /* create whitewashed LLC header in skb buffer (why not the real one?) */
+ /* create whitewashed LLC header in sk buffer */
struct trllc *local_llc = (struct trllc *)data;
memset(local_llc, 0, sizeof(*local_llc));
local_llc->ethertype = htons(ETH_P_TR_802_2);
hdr_len = sizeof(struct trllc);
+ /* copy the real LLC header to the sk buffer */
+ data += hdr_len;
+ memcpy_fromio(data, rbuffer+offsetof(struct rec_buf, data)+lan_hdr_len,hdr_len);
} else {
/* Copy the LLC header and the IPv4 header */
hdr_len = sizeof(struct trllc) + sizeof(struct iphdr);
memcpy_fromio(data, rbuffer+offsetof(struct rec_buf, data)+lan_hdr_len,hdr_len);
+
+ /* Watch for padded packets and bogons */
+ iph=(struct iphdr*)(data+sizeof(struct trllc));
+ ip_len = ntohs(iph->tot_len) - sizeof(struct iphdr);
+ length -= lan_hdr_len + hdr_len;
+ if ((ip_len <= length) && (ip_len > 7))
+ length = ip_len;
}
data += hdr_len;
- lan_hdr_len += hdr_len;
rbuffer_len -= hdr_len;
- rbufdata = rbuffer + offsetof(struct rec_buf,data) + lan_hdr_len;
+ rbufdata = rbuffer + offsetof(struct rec_buf,data) + lan_hdr_len + hdr_len;
/* Copy the payload... */
for (;;) {
if (is8022)
memcpy_fromio(data, rbufdata, rbuffer_len);
else
- chksum = csum_partial_copy(bus_to_virt(rbufdata), data, rbuffer_len, chksum);
+ chksum = csum_partial_copy(bus_to_virt(rbufdata), data,
+ length < rbuffer_len ? length : rbuffer_len,
+ chksum);
rbuffer = ntohs(readw(rbuffer));
if (!rbuffer)
break;
+ length -= rbuffer_len;
data += rbuffer_len;
rbuffer += ti->sram;
rbuffer_len = ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)));
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov