/* * * wlanni.h * * Description: * WLAN accelerator driver implementation * */ #ifndef _WLANNI_H_ #define _WLANNI_H_ /* ------------------------------------------------------------------ */ /* -------- tx packet info ------------------------------------------ */ /* ------------------------------------------------------------------ */ /* 2: added member reason */ #define WLANNI_TX_PACKET_INFO_VERSION 2 enum wlanni_tx_reason { wlanni_tx_reason_firsttime = 0, wlanni_tx_reason_fromqueue, wlanni_tx_reason_checkqueue }; typedef struct wlanni_tx_packet_info { int version; /* input */ u32 pktinfo; /* from ti_meta_info */ unsigned int pktlen; /* total size of packet to transmit */ unsigned char *hdr; /* pointer to header data */ unsigned int hlen; /* bytes of header data available */ int accelerated; /* accelerated through PP */ enum wlanni_tx_reason reason; } wlanni_tx_packet_info_t; /* 4 Bit */ #define WLANNI_PKTINFO_ENDPOINT_SHIFT 0 #define WLANNI_PKTINFO_ENDPOINT_MASK (0xf << WLANNI_PKTINFO_ENDPOINT_SHIFT) #define WLANNI_ENDPOINT_MAX ((WLANNI_PKTINFO_ENDPOINT_MASK>>WLANNI_PKTINFO_ENDPOINT_SHIFT)+1) /* 1 Bit */ #define WLANNI_PKTINFO_LOCAL_SHIFT 4 #define WLANNI_PKTINFO_LOCAL_MASK (0x1 << WLANNI_PKTINFO_LOCAL_SHIFT) /* 1 Bit */ #define WLANNI_PKTINFO_PWRSAVE_SHIFT 5 #define WLANNI_PKTINFO_PWRSAVE_MASK (0x1 << WLANNI_PKTINFO_PWRSAVE_SHIFT) /* 1 Bit */ #define WLANNI_PKTINFO_HIGHPRIO_SHIFT 6 #define WLANNI_PKTINFO_HIGHPRIO_MASK (0x1 << WLANNI_PKTINFO_HIGHPRIO_SHIFT) /* 5 Bit */ #define WLANNI_PKTINFO_NODE_SHIFT 7 #define WLANNI_PKTINFO_NODE_MASK (0x1f << WLANNI_PKTINFO_NODE_SHIFT) /* 7 Bit */ #define WLANNI_PKTINFO_L2HLEN_SHIFT 12 #define WLANNI_PKTINFO_L2HLEN_MASK (0x7f << WLANNI_PKTINFO_L2HLEN_SHIFT) #define WLANNI_PKTINFO_ALL_MASK (WLANNI_PKTINFO_ENDPOINT_MASK \ |WLANNI_PKTINFO_LOCAL_MASK \ |WLANNI_PKTINFO_PWRSAVE_MASK \ |WLANNI_PKTINFO_HIGHPRIO_MASK \ |WLANNI_PKTINFO_NODE_MASK \ |WLANNI_PKTINFO_L2HLEN_MASK) /* ------------------------------------------------------------------ */ static inline unsigned wlanni_pktinfo_get_ep(u32 pktinfo) { return (pktinfo & WLANNI_PKTINFO_ENDPOINT_MASK) >> WLANNI_PKTINFO_ENDPOINT_SHIFT; } static inline unsigned wlanni_pktinfo_get_local(u32 pktinfo) { return (pktinfo & WLANNI_PKTINFO_LOCAL_MASK) >> WLANNI_PKTINFO_LOCAL_SHIFT; } static inline unsigned wlanni_pktinfo_get_pwrsave(u32 pktinfo) { return (pktinfo & WLANNI_PKTINFO_PWRSAVE_MASK) >> WLANNI_PKTINFO_PWRSAVE_SHIFT; } static inline unsigned wlanni_pktinfo_get_highprio(u32 pktinfo) { return (pktinfo & WLANNI_PKTINFO_HIGHPRIO_MASK) >> WLANNI_PKTINFO_HIGHPRIO_SHIFT; } static inline unsigned wlanni_pktinfo_get_node(u32 pktinfo) { return (pktinfo & WLANNI_PKTINFO_NODE_MASK) >> WLANNI_PKTINFO_NODE_SHIFT; } static inline unsigned wlanni_pktinfo_get_l2hlen(u32 pktinfo) { return (pktinfo & WLANNI_PKTINFO_L2HLEN_MASK) >> WLANNI_PKTINFO_L2HLEN_SHIFT; } /* ------------------------------------------------------------------ */ static inline void wlanni_pktinfo_wlan_init(u32 *pktinfop) { *pktinfop = 0; } static inline void wlanni_pktinfo_set_ep(u32 *pktinfop, unsigned ep) { u32 pktinfo = *pktinfop; pktinfo &= (WLANNI_PKTINFO_ALL_MASK^WLANNI_PKTINFO_ENDPOINT_MASK); pktinfo |= (ep << WLANNI_PKTINFO_ENDPOINT_SHIFT) & WLANNI_PKTINFO_ENDPOINT_MASK; *pktinfop = pktinfo; } static inline void wlanni_pktinfo_set_local(u32 *pktinfop, int local) { u32 pktinfo = *pktinfop; pktinfo &= (WLANNI_PKTINFO_ALL_MASK^WLANNI_PKTINFO_LOCAL_MASK); if (local) pktinfo |= (1 << WLANNI_PKTINFO_LOCAL_SHIFT); *pktinfop = pktinfo; } static inline void wlanni_pktinfo_set_pwrsave(u32 *pktinfop, int pwrsave) { u32 pktinfo = *pktinfop; pktinfo &= (WLANNI_PKTINFO_ALL_MASK^WLANNI_PKTINFO_PWRSAVE_MASK); if (pwrsave) pktinfo |= (1 << WLANNI_PKTINFO_PWRSAVE_SHIFT); *pktinfop = pktinfo; } static inline void wlanni_pktinfo_set_highprio(u32 *pktinfop, int highprio) { u32 pktinfo = *pktinfop; pktinfo &= (WLANNI_PKTINFO_ALL_MASK^WLANNI_PKTINFO_HIGHPRIO_MASK); if (highprio) pktinfo |= (1 << WLANNI_PKTINFO_HIGHPRIO_SHIFT); *pktinfop = pktinfo; } static inline void wlanni_pktinfo_set_node(u32 *pktinfop, unsigned node) { u32 pktinfo = *pktinfop; pktinfo &= (WLANNI_PKTINFO_ALL_MASK^WLANNI_PKTINFO_NODE_MASK); pktinfo |= (node << WLANNI_PKTINFO_NODE_SHIFT) & WLANNI_PKTINFO_NODE_MASK; *pktinfop = pktinfo; } static inline void wlanni_pktinfo_set_l2hlen(u32 *pktinfop, unsigned hlen) { u32 pktinfo = *pktinfop; pktinfo &= (WLANNI_PKTINFO_ALL_MASK^WLANNI_PKTINFO_L2HLEN_MASK); pktinfo |= (hlen << WLANNI_PKTINFO_L2HLEN_SHIFT) & WLANNI_PKTINFO_L2HLEN_MASK; *pktinfop = pktinfo; } /* ------------------------------------------------------------------ */ /* -------- exported functions -------------------------------------- */ /* ------------------------------------------------------------------ */ /* * Send received packet to PP prefetcher and try to accelerate it * * returns: * 0 - packet sent to PP * <= -1 - can't send packet to PP, use slow path or drop packet */ int wlanni_packet_received(struct sk_buff *skb); /* * Send packet to send to PP and may handle qos * (transmit packet through net_device "wlanni0") * * returns: * 0 - packet sent to PP * <= -1 - can't send packet to PP, use slow path or drop packet */ int wlanni_packet_send(struct sk_buff *skb, u32 pktinfo); /* * If there are packets queued for this endpoint , try to transmit them. * returns: nothing */ void wlanni_start_transmit_for_ep(unsigned ep); /* * return number of descriptors in hardware tx queue * or 0 if no driver is registered */ int wlanni_tx_hw_queue_len_for_ep(unsigned ep); /* * return number of descriptors in ep (software) tx queue */ int wlanni_tx_sw_queue_len_for_ep(unsigned ep); /* * return number of descriptors returned to WLAN driver * * interate sw queue and call function for each element. * if function returns: * 0 - keep packet in queue * >= 1 - return packet to WLAN driver for queueing there * with callback "packet_return" * <= -1 - Error, drop packet */ #define WLANNI_TX_SW_QUEUE_ITERATE_IMPLEMENTED int wlanni_tx_sw_queue_iterate(unsigned ep, u32 pktinfo, int (*walkfunc)(wlanni_tx_packet_info_t *p, u32 pktinfo)); /* ------------------------------------------------------------------ */ #define WLANNI_WLANDRIVER_INTERFACE_VERSION 2 enum wlanni_wlandriver_type { wlanni_wlandriver_type_magpie = 0, wlanni_wlandriver_type_usb = 1 }; typedef struct wlanni_wlandriver_interface { int version; /* * returns: * 0 - packet may be transmited. * >= 1 - return packet to WLAN driver for queueing there * with callback "packet_return" * <= -1 - Error, drop packet */ int (*may_transmit)(wlanni_tx_packet_info_t *p); /* * returns: * 0 - packet is prepared for sending, credits adjusted * >= 1 - queue packet for endpoint (no credits). * (try again when wlanni_start_transmit_for_ep() was called * <= -1 - Error, drop packet */ int (*prepare_transmit)(wlanni_tx_packet_info_t *p); /* * returns: * 0 - packet returned * != 0 - Error, drop packet */ int (*packet_return)(struct sk_buff *skb, u32 pktinfo); /* * private data structure for wlan driver */ void *driver_handle; /* * for debugging purpose: selection of data paths to use pp infrastructure */ int accelleration_mode; /* added in version 2 */ enum wlanni_wlandriver_type type; unsigned char ep2queue_map[WLANNI_ENDPOINT_MAX]; } wlanni_wlandriver_interface_t; /* * register wlan driver (only one driver can register) * * returns: * 0 - registered * >= 1 - this driver is already registered (double register) * <= -1 - other driver is already registered */ int wlanni_register_wlandriver(wlanni_wlandriver_interface_t *drv); /* * unregister wlan driver * * returns: * 0 - unregistered * >= 1 - no driver registered * <= -1 - other driver is registered */ int wlanni_unregister_wlandriver(wlanni_wlandriver_interface_t *drv); /* * returns registered wlan driver interface structure * or 0 if no wlan driver is registered * */ wlanni_wlandriver_interface_t *wlanni_get_wlandriver(void); #endif /* _WLANNI_H_ */