patch-2.1.31 linux/drivers/net/ibmtr.c
Next file: linux/drivers/net/ibmtr.h
Previous file: linux/drivers/net/hp100.c
Back to the patch index
Back to the overall index
- Lines: 358
- Date:
Mon Mar 31 12:52:30 1997
- Orig file:
v2.1.30/linux/drivers/net/ibmtr.c
- Orig date:
Fri Feb 7 05:54:54 1997
diff -u --recursive --new-file v2.1.30/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
@@ -53,7 +53,9 @@
* from being rudely overwritten before the transmit cycle is
* complete. (August 15 1996)
* + completed multiple adapter support. (November 20 1996)
- */
+ * + implemented csum_partial_copy in tr_rx and increased receive
+ * buffer size and count. Minor fixes. (March 15, 1997)
+*/
#ifdef PCMCIA
#define MODULE
@@ -79,13 +81,10 @@
/* some 95 OS send many non UI frame; this allow removing the warning */
#define TR_FILTERNONUI 1
-/* use memcpy to read/write frame data instead of for-loop */
-#define USE_MEMCPY 1
-
/* version and credits */
static char *version =
"ibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n"
-" v2.1.10 11/20/96 Paul Norton <pnorton@cts.com>\n";
+" v2.1.29 3/15/97 Paul Norton <pnorton@cts.com>\n";
static char pcchannelid[] = {
0x05, 0x00, 0x04, 0x09,
@@ -120,6 +119,7 @@
#include <linux/netdevice.h>
#include <linux/trdevice.h>
#include <linux/stddef.h>
+#include <net/checksum.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -178,8 +178,6 @@
void ibmtr_readlog(struct device *dev);
void ibmtr_reset_timer(struct timer_list *tmr, struct device *dev);
-static struct timer_list tr_timer;
-
static unsigned int ibmtr_portlist[] = {
0xa20, 0xa24, 0
};
@@ -858,7 +856,7 @@
open_ret_code);
if (ti->open_status != FAILURE) {
- ibmtr_reset_timer(&tr_timer, dev);
+ ibmtr_reset_timer(&(ti->tr_timer), dev);
}
}
@@ -872,7 +870,7 @@
if (readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))) {
DPRINTK("open_sap failed: ret_code = %02X,retrying\n",
(int)readb(ti->srb+offsetof(struct dlc_open_sap, ret_code)));
- ibmtr_reset_timer(&tr_timer, dev);
+ ibmtr_reset_timer(&(ti->tr_timer), dev);
} else {
ti->exsap_station_id=
readw(ti->srb+offsetof(struct dlc_open_sap, station_id));
@@ -983,7 +981,7 @@
DPRINTK("Signal loss/Lobe fault\n");
DPRINTK("We try to reopen the adapter.\n");
- ibmtr_reset_timer(&tr_timer, dev);
+ ibmtr_reset_timer(&(ti->tr_timer), dev);
} else if (ring_status & (HARD_ERROR | XMIT_BEACON
| AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER))
DPRINTK("New ring status: %02X\n", ring_status);
@@ -1297,27 +1295,16 @@
/* header length including rif is computed above, now move the data
and set fields appropriately. */
-#if USE_MEMCPY
memcpy_toio(dhb, ti->current_skb->data, hdr_len);
-#else
- for (i=0; i<hdr_len; i++)
- writeb(*(unsigned char *)(ti->current_skb->data +i), dhb++);
-#endif
writeb(hdr_len, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
writew(htons(ti->current_skb->len-sizeof(struct trh_hdr)+hdr_len),
ti->asb + offsetof(struct asb_xmit_resp, frame_length));
/* now copy the actual packet data next to hdr */
-#if USE_MEMCPY
memcpy_toio(dhb + hdr_len,
ti->current_skb->data + sizeof(struct trh_hdr),
ti->current_skb->len - sizeof(struct trh_hdr));
-#else
- for (i=0; i<ti->current_skb->len-sizeof(struct trh_hdr); i++)
- writeb(*(unsigned char *)(ti->current_skb->data +sizeof(struct trh_hdr)+i),
- dhb+i);
-#endif
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
dev->tbusy=0;
@@ -1329,20 +1316,20 @@
static void tr_rx(struct device *dev)
{
- int i;
struct tok_info *ti=(struct tok_info *) dev->priv;
- __u32 rbuffer;
+ __u32 rbuffer, rbufdata;
__u32 llc;
unsigned char *data;
- unsigned int rbuffer_len, lan_hdr_len;
+ unsigned int rbuffer_len, lan_hdr_len, hdr_len;
unsigned int arb_frame_len;
struct sk_buff *skb;
unsigned int skb_size = 0;
int is8022 = 0;
+ unsigned int chksum = 0;
rbuffer=(ti->sram
- +ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))));
-
+ +ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))))+2;
+
if(readb(ti->asb + offsetof(struct asb_rec, ret_code))!=0xFF)
DPRINTK("ASB not free !!!\n");
@@ -1354,7 +1341,7 @@
ti->asb + offsetof(struct asb_rec, rec_buf_addr));
lan_hdr_len=readb(ti->arb + offsetof(struct arb_rec_req, lan_hdr_len));
-
+
llc=(rbuffer+offsetof(struct rec_buf, data) + lan_hdr_len);
#if TR_VERBOSE
@@ -1367,128 +1354,123 @@
"ethertype: %04X\n",
(int)readb(llc + offsetof(struct trllc, dsap)),
(int)readb(llc + offsetof(struct trllc, ssap)),
+ (int)readb(llc + offsetof(struct trllc, llc)),
(int)readb(llc + offsetof(struct trllc, protid)),
(int)readb(llc + offsetof(struct trllc, protid)+1),
(int)readb(llc + offsetof(struct trllc, protid)+2),
(int)readw(llc + offsetof(struct trllc, ethertype)));
#endif
-
if (readb(llc + offsetof(struct trllc, llc))!=UI_CMD) {
-#if !TR_FILTERNONUI
- DPRINTK("non-UI frame arrived. dropped. llc= %02X\n",
- (int)readb(llc + offsetof(struct trllc, llc))
-#endif
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 TR_VERBOSE
- if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
- (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
-
- __u32 trhhdr;
-
- trhhdr=(rbuffer+offsetof(struct rec_buf,data));
-
- DPRINTK("Probably non-IP frame received.\n");
- DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X "
- "daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
- (int)readb(llc + offsetof(struct trllc, ssap)),
- (int)readb(llc + offsetof(struct trllc, dsap)),
- (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)),
- (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+1),
- (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+2),
- (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+3),
- (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+4),
- (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+5),
- (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)),
- (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+1),
- (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+2),
- (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+3),
- (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+4),
- (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+5));
- }
-#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);
- if (is8022) {
- skb_size += sizeof(struct trllc);
- }
-
- if (!(skb=dev_alloc_skb(skb_size))) {
- DPRINTK("out of memory. frame dropped.\n");
- ti->tr_stats.rx_dropped++;
- writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
- writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- return;
- }
-
- skb_put(skb, skb_size);
- skb->dev=dev;
-
- data=skb->data;
-#if USE_MEMCPY
- memcpy_fromio(data, rbuffer + offsetof(struct rec_buf, data), lan_hdr_len);
-#else
- for (i=0; i<lan_hdr_len; i++)
- data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
-#endif
- 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) {
- struct trllc *local_llc = (struct trllc *)data;
- memset(local_llc, 0, sizeof(*local_llc));
- local_llc->ethertype = htons(ETH_P_TR_802_2);
- data += sizeof(struct trllc);
- }
+ if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
+ (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
+ is8022 = 1;
+ }
#if TR_VERBOSE
- DPRINTK("rbuffer_len: %d, data: %p\n", rbuffer_len, data);
-#endif
-#if USE_MEMCPY
- memcpy_fromio(data, rbuffer + offsetof(struct rec_buf, data) + lan_hdr_len, rbuffer_len);
-#else
- for (i=0; i<rbuffer_len; i++)
- data[i]=readb(rbuffer+ offsetof(struct rec_buf, data)+lan_hdr_len+i);
-#endif
- data+=rbuffer_len;
+ if (is8022){
- while (readw(rbuffer + offsetof(struct rec_buf, buf_ptr))) {
- rbuffer=(ti->sram
- +ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_ptr)))-2);
- rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)));
- for (i=0; i<rbuffer_len; i++)
- data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
- data+=rbuffer_len;
+ __u32 trhhdr;
-#if TR_VERBOSE
- DPRINTK("buf_ptr: %d, data =%p\n",
- ntohs((rbuffer + offsetof(struct rec_buf, buf_ptr))), data);
-#endif
- }
+ trhhdr=(rbuffer+offsetof(struct rec_buf,data));
- writeb(0, ti->asb + offsetof(struct asb_rec, ret_code));
+ DPRINTK("Probably non-IP frame received.\n");
+ DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X "
+ "daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ (int)readb(llc + offsetof(struct trllc, ssap)),
+ (int)readb(llc + offsetof(struct trllc, dsap)),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+1),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+2),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+3),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+4),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+5),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+1),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+2),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+3),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+4),
+ (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+5));
+ }
+#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);
+ if (is8022) {
+ skb_size += sizeof(struct trllc);
+ }
+
+ if (!(skb=dev_alloc_skb(skb_size))) {
+ DPRINTK("out of memory. frame dropped.\n");
+ ti->tr_stats.rx_dropped++;
+ writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
+ writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+ return;
+ }
+
+ skb_put(skb, skb_size);
+ skb->dev=dev;
+
+ data=skb->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 skb buffer (why not the real one?) */
+ 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);
+ } 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);
+ }
+ data += hdr_len;
+ lan_hdr_len += hdr_len;
+ rbuffer_len -= hdr_len;
+ rbufdata = rbuffer + offsetof(struct rec_buf,data) + lan_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);
+ rbuffer = ntohs(readw(rbuffer));
+ if (!rbuffer)
+ break;
+ data += rbuffer_len;
+ rbuffer += ti->sram;
+ rbuffer_len = ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)));
+ rbufdata = rbuffer + offsetof(struct rec_buf, data);
+ }
- writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+ writeb(0, ti->asb + offsetof(struct asb_rec, ret_code));
- ti->tr_stats.rx_packets++;
+ writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- skb->protocol=tr_type_trans(skb,dev);
- netif_rx(skb);
+ ti->tr_stats.rx_packets++;
+ skb->protocol = tr_type_trans(skb,dev);
+ if (!is8022){
+ skb->csum = chksum;
+ skb->ip_summed = 1;
}
+ netif_rx(skb);
+}
static int tok_send_packet(struct sk_buff *skb, struct device *dev)
{
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov