📄 am930llc.c
字号:
void am930llc_rxframe( am930llc_t *llc, UINT8 *frm, UINT32 len){ struct sk_buff *skb; DBFENTER; llc->dev->interrupt = 1;#ifdef DEBUG_RXHDR_ETHam930llc_dbprt_frame( frm, len, 1 );#endif if ( llc->dev->start ) { skb = dev_alloc_skb(len + 2); /* I do +2 because it's what 8390 does */ if ( skb == NULL ) { DBPRT( DBRXPATH, "Memory low, frame dropped\n"); } else { llc->dev->last_rx = jiffies; skb->len = len; skb->dev = llc->dev; /* The following is from 8390.c */ skb_reserve(skb, 2); /* IP headers on 16 byte boundaries */ skb_put( skb, len); /* make room */ memcpy( skb->data, frm, len); skb->protocol = eth_type_trans( skb, llc->dev);/*#define BLOCK_INPUT(buf, len) { memcpy( (buf), (frm), (len)); } GET_PACKET( llc->dev, skb, len);*/ V2P(llc->dev->priv)->stats.rx_packets++; netif_rx(skb); mark_bh(NET_BH); } } llc->dev->interrupt = 0; DBFEXIT; return;}/*----------------------------------------------------------------* am930llc_rxframe_err** returns: zero----------------------------------------------------------------*/void am930llc_rxframe_err( am930llc_t *llc){ DBFENTER; V2P(llc->dev->priv)->stats.rx_errors++; DBFEXIT; return;}/*----------------------------------------------------------------* am930llc_devgetstats* getstats method for the linux net device. Called as a result* of a number of user mode utilities used to check the rx/tx* statistics of an interface.** returns: zero----------------------------------------------------------------*/enet_stats_t* am930llc_devgetstats(device_t *dev){ DBFENTER; DBFEXIT; return &(V2P(dev->priv)->stats);}/*----------------------------------------------------------------* am930llc_devset_multicast_list* set_multicast_list method for the linux net device. ** returns: nothing----------------------------------------------------------------*/#define HW_MAX_ADDRS 4void am930llc_devset_multicast_list(device_t *dev){ DBFENTER; if ( dev->flags & IFF_PROMISC ) { /* Enable Promiscuous Mode */ UINT8 one = 1; am930mgr_mibsetitem(V2P(dev->priv)->llc->mgr, MAC_PROMISC_EN, &one, sizeof(one)); } else if ( dev->flags & IFF_ALLMULTI || (dev->mc_count > HW_MAX_ADDRS) ) { /* Enable the hw "rcv all multicast" mode, either because of the IFF_ALLMULTI switch or because we have more multicast hw addresses than the hw filter can hold (1.0 fw has four). */ printk(KERN_DEBUG "IFF_ALLMULTI currently unsupported.\n"); } else if ( dev->mc_count ) { /* Load the contents of the mc_list from the dev structure into the filter list in the hardware (effectively reset it from scratch). */ printk(KERN_DEBUG "Multicast filters currently unsupported.\n"); } else { /* Disable promiscuous, disable allmulti, and clear the multicast filter list */ UINT8 zero = 0; am930mgr_mibsetitem(V2P(dev->priv)->llc->mgr, MAC_PROMISC_EN, &zero, sizeof(zero)); } DBFEXIT; return;}/*----------------------------------------------------------------* am930llc_devdo_ioctl* do_ioctl method for the linux net device. Private ioctl handler* for the net device. Used here to pass commands to the mgr* object.* TODO: Define the interface between the mgr object and user* mode utilities. ** returns: zero----------------------------------------------------------------*/int am930llc_devdo_ioctl(device_t *dev, wlan_req_t *req, int cmd){ int result = 0; DBFENTER; /* Test the memory passed */ if ( req->len > 0 ) result = verify_area( VERIFY_WRITE, req->data, req->len); if ( result == 0 ) { switch( cmd ) { case WLAN_TEST: req->result = 0xf0f0; break; /* start mod: tld */ case WLAN_TLD: req->result = am930hw_rssi_tld(30); break; /* end mod: tld */ case WLAN_SCAN: { wlan_scan_t cmd; copy_from_user( &cmd, req->data, sizeof(cmd)); req->result = am930mgr_scan( V2P(dev->priv)->llc->mgr, cmd.scantype, /*active/passive*/ cmd.bsstype, /*ind./infra./both*/ cmd.bssid, /*bcast/specific*/ cmd.startch, cmd.endch, cmd.timech ); /*time per ch.*/ break; } case WLAN_NETLIST_LEN: { wlan_netlist_len_t cmd; knownbss_t *curr; int i; am930mgr_t* mgr = V2P(dev->priv)->llc->mgr; i = 0; for( curr = mgr->bsslist; curr != NULL; curr = curr->next) i++; cmd.nitems = i; copy_to_user( req->data, &cmd, sizeof(cmd)); req->result = 0; break; } case WLAN_NETLIST: { wlan_netlist_t *cmd; wlan_netlist_t tmp; knownbss_t *curr; int i; am930mgr_t* mgr = V2P(dev->priv)->llc->mgr; copy_from_user( &tmp, req->data, sizeof(tmp)); cmd = kmalloc(sizeof(wlan_netlist_t) + (tmp.nitems * sizeof(netitem_t)), GFP_ATOMIC); cmd->nitems = tmp.nitems; i = 0; for( curr = mgr->bsslist; curr != NULL; curr = curr->next) { cmd->netlist[i].channel = curr->channel; cmd->netlist[i].bcn_int = curr->bcn_int; memcpy(cmd->netlist[i].bssid, curr->bssid, 6); strcpy(cmd->netlist[i].ssid, curr->ssid); i++; } copy_to_user( req->data, cmd, sizeof(wlan_netlist_t) + (cmd->nitems * sizeof(netitem_t))); break; } case WLAN_BSSCREATE: { wlan_bsscreate_t cmd; copy_from_user( &cmd, req->data, sizeof(cmd)); req->result = am930mgr_createbss( V2P(dev->priv)->llc->mgr, cmd.channel, cmd.ssid, cmd.beacon_int, cmd.atim_win); break; } case WLAN_BSSJOIN: { wlan_bssjoin_t cmd; copy_from_user( &cmd, req->data, sizeof(cmd)); req->result = am930mgr_joinbss( V2P(dev->priv)->llc->mgr, cmd.bssid ); break; } case WLAN_GETMIB: { UINT8* p = NULL; UINT32 size = 0; UINT32 mibcode; p = kmalloc(req->len, GFP_KERNEL); if (p == NULL) { printk(KERN_DEBUG "kmalloc failed in ioctl.\n"); break; } copy_from_user( &mibcode, req->data, 4 );/* mibcode frm wlan_mibget_t*/ switch(mibcode) { case SUMIB_LOCAL: size = sizeof(su_mib_local_t); break; case SUMIB_ADDR: size = sizeof(su_mib_mac_addr_stat_grp_t); break; case SUMIB_MAC: size = sizeof(su_mib_mac_t); break; case SUMIB_STAT: size = sizeof(su_mib_mac_statistics_t); break; case SUMIB_MGMT: size = sizeof(su_mib_mac_mgmt_t); break; case SUMIB_DRVR: /* size = sizeof(su_mib_local_t); */ size = 0; break; case SUMIB_PHY: size = sizeof(su_mib_phy_t); break; } am930mgr_mibget( V2P(dev->priv)->llc->mgr, mibcode, size, p); copy_to_user( ((UINT8*)(req->data)) + 4, p, size); kfree_s(p, req->len); break; } case WLAN_GETMIBITEM: break; case WLAN_SETMIBITEM: break; default: printk(KERN_DEBUG "am930_cs: Unknown or unsupported wlan ioctl!\n"); break; } } DBFEXIT; return result;}/*----------------------------------------------------------------* am930llc_ontxcomplete** returns: zero----------------------------------------------------------------*/void am930llc_ontxcomplete( am930llc_t *llc, UINT32 txresult){ DBFENTER; if ( txresult != 0 ) /* tx failure */ { V2P(llc->dev->priv)->stats.tx_errors++; } else { V2P(llc->dev->priv)->stats.tx_packets++; } llc->dev->tbusy = 0; mark_bh(NET_BH); DBFEXIT; return;}/*----------------------------------------------------------------* am930llc_dbprt_frame** returns: nothing----------------------------------------------------------------*/void am930llc_dbprt_frame( UINT8* frm, UINT32 len, int isrx ){ int i; char buf[80]; if ( len > 0 ) { for ( i = 0; i < len; i++) { if ( i % 20 == 0 && i > 0) { printk( KERN_DEBUG "llc: %s\n", buf); } sprintf( &buf[(i % 20)*3], "%02x ", frm[i]); } if ( i % 20 > 0 ) { printk( KERN_DEBUG "%s%d: %s\n", isrx ? "rx" : "tx", i % 20, buf); } } else { printk( KERN_DEBUG "llc: frame length is zero\n"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -