patch-2.1.53 linux/drivers/net/ibmtr.c
Next file: linux/drivers/net/myri_sbus.c
Previous file: linux/drivers/net/ethertap.c
Back to the patch index
Back to the overall index
- Lines: 249
- Date:
Thu Sep 4 13:25:28 1997
- Orig file:
v2.1.52/linux/drivers/net/ibmtr.c
- Orig date:
Thu Jul 17 10:06:05 1997
diff -u --recursive --new-file v2.1.52/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
@@ -58,6 +58,10 @@
*
* Changes by Christopher Turcksin <wabbit@rtfc.demon.co.uk>
* + Now compiles ok as a module again.
+ *
+ * Changes by Paul Norton (pnorton@cts.com) :
+ * + moved the header manipulation code in tr_tx and tr_rx to
+ * net/802/tr.c. (July 12 1997)
*/
#ifdef PCMCIA
@@ -87,7 +91,7 @@
/* version and credits */
static char *version =
"ibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n"
-" v2.1.35 5/ 1/97 Paul Norton <pnorton@cts.com>\n";
+" v2.1.42 7/12/97 Paul Norton <pnorton@cts.com>\n";
static char pcchannelid[] = {
0x05, 0x00, 0x04, 0x09,
@@ -168,8 +172,8 @@
static int ibmtr_probe1(struct device *dev, int ioaddr);
static unsigned char get_sram_size(struct tok_info *adapt_info);
static int tok_init_card(struct device *dev);
-static int trdev_init(struct device *dev);
void tok_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static int trdev_init(struct device *dev);
static void initial_tok_int(struct device *dev);
static void open_sap(unsigned char type,struct device *dev);
void tok_open_adapter(unsigned long dev_addr);
@@ -1249,7 +1253,15 @@
effective address where we will place data.*/
dhb=ti->sram
+ntohs(readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address)));
- llc = (struct trllc *) &(ti->current_skb->data[sizeof(struct trh_hdr)]);
+
+ /* Figure out the size of the 802.5 header */
+ if (!(trhdr->saddr[0] & 0x80)) /* RIF present? */
+ hdr_len=sizeof(struct trh_hdr)-18;
+ else
+ hdr_len=((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK)>>8)
+ +sizeof(struct trh_hdr)-18;
+
+ llc = (struct trllc *)(ti->current_skb->data + hdr_len);
xmit_command = readb(ti->srb + offsetof(struct srb_xmit, command));
@@ -1277,39 +1289,15 @@
}
- /* the token ring packet is copied from sk_buff to the adapter
- buffer identified in the command data received with the
- interrupt. The sk_buff area was set up with a maximum
- sized route information field so here we must compress
- out the extra (all) rif fields. */
- /* nb/dwm .... I re-arranged code here to avoid copy of extra
- bytes, ended up with fewer statements as well. */
-
- /* TR arch. identifies if RIF present by high bit of source
- address. So here we check if RIF present */
-
- if (!(trhdr->saddr[0] & 0x80)) { /* RIF present : preserve it */
- hdr_len=sizeof(struct trh_hdr)-18;
-
-#if TR_VERBOSE
- DPRINTK("hdr_length: %d, frame length: %ld\n", hdr_len,
- ti->current_skb->len-18);
-#endif
- } else hdr_len=((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK)>>8)
- +sizeof(struct trh_hdr)-18;
-
- /* header length including rif is computed above, now move the data
- and set fields appropriately. */
- memcpy_toio(dhb, ti->current_skb->data, hdr_len);
-
+ /*
+ * the token ring packet is copied from sk_buff to the adapter
+ * buffer identified in the command data received with the interrupt.
+ */
writeb(hdr_len, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
- writew(htons(ti->current_skb->len-sizeof(struct trh_hdr)+hdr_len),
+ writew(htons(ti->current_skb->len),
ti->asb + offsetof(struct asb_xmit_resp, frame_length));
- /* now copy the actual packet data next to hdr */
- memcpy_toio(dhb + hdr_len,
- ti->current_skb->data + sizeof(struct trh_hdr),
- ti->current_skb->len - sizeof(struct trh_hdr));
+ memcpy_toio(dhb, ti->current_skb->data, ti->current_skb->len);
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
dev->tbusy=0;
@@ -1328,7 +1316,7 @@
unsigned int rbuffer_len, lan_hdr_len, hdr_len, ip_len, length;
struct sk_buff *skb;
unsigned int skb_size = 0;
- int is8022 = 0;
+ int IPv4_p = 0;
unsigned int chksum = 0;
struct iphdr *iph;
@@ -1347,7 +1335,7 @@
lan_hdr_len=readb(ti->arb + offsetof(struct arb_rec_req, lan_hdr_len));
- llc=(rbuffer+offsetof(struct rec_buf, data) + lan_hdr_len);
+ llc=(rbuffer + offsetof(struct rec_buf, data) + lan_hdr_len);
#if TR_VERBOSE
DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",
@@ -1366,19 +1354,19 @@
(int)readw(llc + offsetof(struct trllc, ethertype)));
#endif
if (readb(llc + offsetof(struct trllc, llc))!=UI_CMD) {
- writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
- ti->tr_stats.rx_dropped++;
- writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- return;
+ writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
+ ti->tr_stats.rx_dropped++;
+ writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+ return;
}
- if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
- (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
- is8022 = 1;
+ if ((readb(llc + offsetof(struct trllc, dsap))==0xAA) &&
+ (readb(llc + offsetof(struct trllc, ssap))==0xAA)) {
+ IPv4_p = 1;
}
#if TR_VERBOSE
- if (is8022){
+ if (!IPv4_p){
__u32 trhhdr;
@@ -1405,11 +1393,8 @@
#endif
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);
- }
-
+ skb_size = length-lan_hdr_len+sizeof(struct trh_hdr)+sizeof(struct trllc);
+
if (!(skb=dev_alloc_skb(skb_size))) {
DPRINTK("out of memory. frame dropped.\n");
ti->tr_stats.rx_dropped++;
@@ -1418,53 +1403,37 @@
return;
}
- skb_put(skb, skb_size);
+ skb_put(skb, length);
+ skb_reserve(skb, sizeof(struct trh_hdr)-lan_hdr_len+sizeof(struct trllc));
skb->dev=dev;
-
data=skb->data;
+ rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)));
+ rbufdata = rbuffer + offsetof(struct rec_buf,data);
- /* Copy the 802.5 MAC header */
- memcpy_fromio(data, rbuffer + offsetof(struct rec_buf, data), lan_hdr_len);
-
- if (lan_hdr_len<sizeof(struct trh_hdr))
- memset(data+lan_hdr_len, 0, sizeof(struct trh_hdr)-lan_hdr_len);
-
- data+=sizeof(struct trh_hdr);
- rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)))-lan_hdr_len;
-
- if (is8022) {
- /* 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);
+ if (IPv4_p) {
+ /* Copy the headers without checksumming */
+ hdr_len = lan_hdr_len + sizeof(struct trllc) + sizeof(struct iphdr);
+ memcpy_fromio(data, rbufdata, hdr_len);
/* Watch for padded packets and bogons */
- iph=(struct iphdr*)(data+sizeof(struct trllc));
+ iph=(struct iphdr*)(data + lan_hdr_len + sizeof(struct trllc));
ip_len = ntohs(iph->tot_len) - sizeof(struct iphdr);
- length -= lan_hdr_len + hdr_len;
+ length -= hdr_len;
if ((ip_len <= length) && (ip_len > 7))
length = ip_len;
+ data += hdr_len;
+ rbuffer_len -= hdr_len;
+ rbufdata += hdr_len;
}
- data += hdr_len;
- rbuffer_len -= 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
+ if (IPv4_p)
chksum = csum_partial_copy(bus_to_virt(rbufdata), data,
length < rbuffer_len ? length : rbuffer_len,
chksum);
+ else
+ memcpy_fromio(data, rbufdata, rbuffer_len);
rbuffer = ntohs(readw(rbuffer));
if (!rbuffer)
break;
@@ -1481,11 +1450,14 @@
ti->tr_stats.rx_packets++;
- skb->protocol = tr_type_trans(skb,dev);
- if (!is8022){
+ tr_reformat(skb, lan_hdr_len);
+ skb->protocol = tr_type_trans(skb,dev);
+
+ if (IPv4_p){
skb->csum = chksum;
skb->ip_summed = 1;
}
+
netif_rx(skb);
}
@@ -1610,7 +1582,7 @@
irq2dev_map[dev_ibmtr[i]->irq] = NULL;
release_region(dev_ibmtr[i]->base_addr, IBMTR_IO_EXTENT);
kfree_s(dev_ibmtr[i]->priv, sizeof(struct tok_info));
- kfree_s(dev_ibmtr[i], sizeof(struct dev));
+ kfree_s(dev_ibmtr[i], sizeof(struct device));
dev_ibmtr[i] = NULL;
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov